1111#include < vector>
1212#include < deque>
1313
14- // Boost iostreams mmap
1514#include < boost/iostreams/device/mapped_file.hpp>
1615
17-
18-
1916namespace {
2017
2118#if defined(_WIN32)
@@ -32,8 +29,6 @@ namespace {
3229
3330} // namespace
3431
35- // ===================== Concrete backends =====================
36-
3732using namespace IfcParse ;
3833
3934struct FullBufferImpl final : FileReader::Impl {
@@ -64,7 +59,7 @@ struct PagedFileImpl final : FileReader::Impl {
6459
6560 // LRU cache
6661 size_t capacity_ = 8 ;
67- mutable std::list<size_t > lru_; // most recent at front
62+ mutable std::list<size_t > lru_;
6863 struct Entry {
6964 FileReader::Page page;
7065 std::list<size_t >::iterator it;
@@ -90,16 +85,14 @@ struct PagedFileImpl final : FileReader::Impl {
9085 char get (size_t pos) const override {
9186 if (pos >= file_size_) throw std::out_of_range (" get out of range" );
9287 const size_t pidx = pos / page_size_;
93- const FileReader::Page& p = fetch_page_ (pidx);
88+ const FileReader::Page& p = fetchPage_ (pidx);
9489 const size_t off = pos % page_size_;
9590 if (off >= p.data .size ()) throw std::out_of_range (" offset beyond valid page bytes" );
96- // Opportunistic read-ahead for sequential scans
97- // if (off + 1 == p.data.size()) (void)try_prefetch_(pidx + 1);
9891 return p.data [off];
9992 }
10093
10194private:
102- const FileReader::Page& fetch_page_ (size_t idx) const {
95+ const FileReader::Page& fetchPage_ (size_t idx) const {
10396 auto it = map_.find (idx);
10497 if (it != map_.end ()) {
10598 touch_ (it);
@@ -116,7 +109,8 @@ struct PagedFileImpl final : FileReader::Impl {
116109 const size_t nread = std::fread (pg.data .data (), 1 , avail, fp_);
117110 if (nread != avail) throw std::runtime_error (" Short fread on page" );
118111 }
119- pg.data .resize (avail); // trim to actual size
112+ // trim to actual size
113+ pg.data .resize (avail);
120114
121115 // Insert into LRU
122116 if (map_.size () >= capacity_) evict_ ();
@@ -127,16 +121,6 @@ struct PagedFileImpl final : FileReader::Impl {
127121 return emplaced_it->second .page ;
128122 }
129123
130- /*
131- bool try_prefetch_(size_t idx) const {
132- if (idx * page_size_ >= file_size_) return false;
133- if (map_.find(idx) != map_.end()) return true;
134- if (map_.size() + 1 > capacity_) return false;
135- (void)fetch_page_(idx);
136- return true;
137- }
138- */
139-
140124 void touch_ (typename std::unordered_map<size_t , Entry>::iterator it) const {
141125 lru_.erase (it->second .it );
142126 lru_.push_front (it->first );
@@ -189,7 +173,7 @@ struct PushedSequentialImpl final : std::enable_shared_from_this<PushedSequentia
189173 }
190174
191175 // Drop fully-consumed pages so pos is guaranteed to be within the first page
192- void drop_consumed_up_to (size_t pos) {
176+ void dropPages (size_t pos) override {
193177 while (!pages_.empty ()) {
194178 if (pos - discarded_page_bytes_ >= pages_.front ().data .size ()) {
195179 discarded_page_bytes_ += pages_.front ().data .size ();
@@ -202,11 +186,17 @@ struct PushedSequentialImpl final : std::enable_shared_from_this<PushedSequentia
202186
203187 char get (size_t pos) const override {
204188 auto self = const_cast <PushedSequentialImpl*>(this );
189+
190+ /*
191+ // We do not do this automatically because all variable width tokens:
192+ // ENUM/STRING/BINARY/KEYWORD are stored as file offsets until a full
193+ // entity instance is finalized.
205194 if (this->shared_from_this().use_count() == 2) {
206195 // only drop pages when there is only one active client.
207196 // NB this->shared_from_this() increases count by 1
208197 self->drop_consumed_up_to(pos);
209198 }
199+ */
210200
211201 const size_t avail_end = size ();
212202 if (pos >= avail_end) throw std::out_of_range (" pushed backend: position not committed yet" );
@@ -226,14 +216,12 @@ struct PushedSequentialImpl final : std::enable_shared_from_this<PushedSequentia
226216 throw std::out_of_range (" pushed backend: internal inconsistency" );
227217 }
228218
229- void push_next_page (const std::string& data) override {
219+ void pushNextPage (const std::string& data) override {
230220 FileReader::Page p; p.data .assign (data.data (), data.data () + data.size ());
231221 pages_.push_back (std::move (p));
232222 }
233223};
234224
235- // ===================== FileReader public API =====================
236-
237225IfcParse::FileReader::FileReader (const std::string& fn)
238226 : cursor_(0 )
239227{
@@ -255,7 +243,7 @@ IfcParse::FileReader::FileReader(const caller_fed_tag&)
255243IfcParse::FileReader::FileReader (const std::string& content, const caller_fed_tag&)
256244{
257245 impl_ = std::make_shared<PushedSequentialImpl>();
258- impl_->push_next_page (content);
246+ impl_->pushNextPage (content);
259247}
260248
261249IfcParse::FileReader::FileReader (const std::string& fn, size_t page_size, size_t page_capacity)
@@ -289,9 +277,19 @@ void FileReader::increment(size_t n) {
289277 cursor_ += n;
290278}
291279
292- void IfcParse::FileReader::push_next_page (const std::string& data)
280+ void IfcParse::FileReader::pushNextPage (const std::string& data)
281+ {
282+ impl_->pushNextPage (data);
283+ }
284+
285+ void IfcParse::FileReader::dropPages ()
286+ {
287+ impl_->dropPages (0 );
288+ }
289+
290+ void IfcParse::FileReader::dropPages (size_t up_to_pos)
293291{
294- impl_->push_next_page (data );
292+ impl_->dropPages (up_to_pos );
295293}
296294
297295bool IfcParse::FileReader::eof () const
0 commit comments