Skip to content

Commit

Permalink
Add cache for pipes
Browse files Browse the repository at this point in the history
  • Loading branch information
dhurum committed Nov 24, 2015
1 parent 4a2cd48 commit b7d7ac6
Show file tree
Hide file tree
Showing 5 changed files with 292 additions and 55 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ string(REPLACE ";" " " CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
set(${TARGET}_SRCS
src/config.cpp
src/file_io.cpp
src/file_cache.cpp
src/file_stream.cpp
src/file_reader.cpp
src/file_forward_reader.cpp
Expand Down
133 changes: 133 additions & 0 deletions src/file_cache.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*******************************************************************************
Copyright 2015 Denis Tikhomirov
This file is part of Mattext
Mattext is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mattext is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mattext. If not, see http://www.gnu.org/licenses/.
*******************************************************************************/

#include <stdlib.h>
#include "file_cache.h"

void FileCache::addForward(char byte) {
cur = (start + len) % cache_max_len;
if (len == cache_max_len) {
incCounter(start);
cache[cur] = byte;
} else {
cache.push_back(byte);
}
status = Reached::End;
if (len < cache_max_len) {
++len;
}
}

bool FileCache::readForward(char &byte) {
if ((status == Reached::End) || !len) {
return false;
}
incCounter(cur);
byte = cache[cur];
status = Reached::Ok;

if (cur == getEnd()) {
status = Reached::End;
}
return true;
}

bool FileCache::readBackward(char &byte) {
if ((status == Reached::Start) || !len) {
return false;
}
decCounter(cur);
byte = cache[cur];
status = Reached::Ok;

if (cur == start) {
status = Reached::Start;
}
return true;
}

inline void FileCache::incCounter(size_t &counter) {
++counter;
if (counter >= cache_max_len) {
counter = 0;
}
}

inline void FileCache::decCounter(size_t &counter) {
if (counter == 0) {
counter = cache_max_len - 1;
return;
}
--counter;
}

inline size_t FileCache::getEnd() {
return (start + len - 1) % cache_max_len;
}

void FileCache::rewindToStart() {
if (!len) {
return;
}
cur = start;
status = Reached::Start;
}

void FileCache::rewindToEnd() {
if (!len) {
return;
}
cur = getEnd();
status = Reached::End;
}

void FileCache::offsetTo(int _offset) {
if (!len) {
return;
}
const size_t end = getEnd();
const size_t offset = abs(_offset);
size_t start_fix = 0;

if (_offset > 0) {
if (cur >= start) {
start_fix = start;
}
if ((cur - start_fix + offset) >= end) {
cur = end;
status = Reached::End;
} else {
cur = (cur + offset) % cache_max_len;
status = Reached::Ok;
}
return;
}
if (cur < start) {
start_fix = len;
}
if ((cur + start_fix - start) < offset) {
cur = start;
status = Reached::Start;
} else {
cur -= offset;
status = Reached::Ok;
}
}
48 changes: 48 additions & 0 deletions src/file_cache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*******************************************************************************
Copyright 2015 Denis Tikhomirov
This file is part of Mattext
Mattext is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Mattext is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Mattext. If not, see http://www.gnu.org/licenses/.
*******************************************************************************/

#pragma once

#include <vector>
#include <stddef.h>

class FileCache {
public:
void addForward(char byte);
bool readForward(char &byte);
bool readBackward(char &byte);
void rewindToStart();
void rewindToEnd();
void offsetTo(int offset);

private:
static const size_t cache_max_len = 1000000;
std::vector<char> cache;
size_t start = 0;
size_t len = 0;
size_t cur = 0;
enum class Reached {Start, End, Ok};
Reached status = Reached::End;

static inline void incCounter(size_t &counter);
static inline void decCounter(size_t &counter);
inline size_t getEnd();
};
Loading

0 comments on commit b7d7ac6

Please sign in to comment.