libmonaa 0.5.2
Loading...
Searching...
No Matches
lazy_deque.hh
1#pragma once
2
3#include <cassert>
4#include <cstdio>
5#include <deque>
6#include <limits>
7#include <stdexcept>
8#include <utility>
9
10#include "common_types.hh"
11
12static inline int getOne(FILE *file, std::pair<Alphabet, double> &p) {
13 return fscanf(file, " %c %lf\n", &p.first, &p.second);
14}
15
16static inline int getOneBinary(FILE *file, std::pair<Alphabet, double> &p) {
17 if (fread(&p.first, sizeof(char), 1, file)) {
18 if (fread(&p.second, sizeof(double), 1, file)) {
19 return sizeof(char) + sizeof(double);
20 }
21 }
22 return EOF;
23}
24
29class LazyDeque : public std::deque<std::pair<Alphabet, double>> {
30private:
31 std::size_t front = 0;
32 std::size_t N;
33 FILE *file;
34 int (*getElem)(FILE *, std::pair<Alphabet, double> &);
35
36public:
42 LazyDeque(FILE *file, bool isBinary = false)
43 : N(std::numeric_limits<std::size_t>::max()), file(file) {
44 assert(file != nullptr);
45 getElem = isBinary ? getOneBinary : getOne;
46 }
47 std::pair<Alphabet, double> operator[](std::size_t n) {
48 const std::size_t indInDeque = n - front;
49 if (n < front || n >= N ||
50 indInDeque >= std::deque<std::pair<Alphabet, double>>::size()) {
51 throw std::out_of_range("thrown at LazyDeque::operator[] ");
52 }
53 return std::deque<std::pair<Alphabet, double>>::at(indInDeque);
54 }
55 std::pair<Alphabet, double> at(std::size_t n) { return (*this)[n]; }
56 std::size_t size() const { return N; }
59 void setFront(std::size_t newFront) {
60 if (newFront < front) {
61 throw std::out_of_range("thrown at LazyDeque::setFront ");
62 }
63 const std::size_t eraseSize = std::min(
64 newFront - front, std::deque<std::pair<Alphabet, double>>::size());
65 const int readTimes = (newFront - front) - eraseSize;
66 front = newFront;
67 this->erase(this->begin(), this->begin() + eraseSize);
68 for (int i = 0; i < readTimes; i++) {
69 std::pair<Alphabet, double> elem;
70 getElem(file, elem);
71 }
72 }
73 bool fetch(std::size_t n) noexcept {
74 if (n < front || n >= N) {
75 return false;
76 }
77 const std::size_t indInDeque = n - front;
78 const int allocTimes =
79 indInDeque - std::deque<std::pair<Alphabet, double>>::size() + 1;
80 for (int i = 0; i < allocTimes; i++) {
81 std::pair<Alphabet, double> elem;
82 if (getElem(file, elem) == EOF) {
83 N = front + std::deque<std::pair<Alphabet, double>>::size();
84 return false;
85 }
86 this->push_back(elem);
87 }
88 return true;
89 }
90};
A Wrapper of FILE Reading. This class is given to WordContainer class as its template argument.
Definition lazy_deque.hh:29
void setFront(std::size_t newFront)
Update the internal front. The elements before the front are removed.
Definition lazy_deque.hh:59
LazyDeque(FILE *file, bool isBinary=false)
Definition lazy_deque.hh:42