MCPcopy Create free account
hub / github.com/IfcOpenShell/IfcOpenShell / PagedFileImpl

Class PagedFileImpl

src/ifcparse/FileReader.cpp:62–150  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

60};
61
62struct PagedFileImpl final : FileReader::Impl {
63 std::string fn_;
64 FILE* fp_ = nullptr;
65 size_t file_size_ = 0;
66 size_t page_size_ = 4096;
67
68 // LRU cache
69 size_t capacity_ = 8;
70 mutable std::list<size_t> lru_;
71 struct Entry {
72 FileReader::Page page;
73 std::list<size_t>::iterator it;
74 };
75 mutable std::unordered_map<size_t, Entry> map_;
76
77 PagedFileImpl(const std::string& fn, size_t page_size, size_t cap)
78 : fn_(fn), page_size_(std::max<size_t>(512, page_size)), capacity_(std::max<size_t>(2, cap))
79 {
80#ifdef _MSC_VER
81 std::wstring fn_ws = IfcUtil::path::from_utf8(fn);
82 const wchar_t* fn_wide = fn_ws.c_str();
83 fp_ = _wfopen(fn_wide, L"rb");
84#else
85 fp_ = fopen(fn.c_str(), "rb");
86#endif
87 fseek(fp_, 0, SEEK_END);
88 file_size_ = (size_t)ftell(fp_);
89 rewind(fp_);
90 }
91
92 ~PagedFileImpl() override {
93 if (fp_) std::fclose(fp_);
94 fp_ = nullptr;
95 }
96
97 size_t size() const override { return file_size_; }
98
99 char get(size_t pos) const override {
100 if (pos >= file_size_) throw std::out_of_range("get out of range");
101 const size_t pidx = pos / page_size_;
102 const FileReader::Page& p = fetchPage_(pidx);
103 const size_t off = pos % page_size_;
104 if (off >= p.data.size()) throw std::out_of_range("offset beyond valid page bytes");
105 return p.data[off];
106 }
107
108private:
109 const FileReader::Page& fetchPage_(size_t idx) const {
110 auto it = map_.find(idx);
111 if (it != map_.end()) {
112 touch_(it);
113 return it->second.page;
114 }
115 // Load page from disk using persistent FILE*
116 FileReader::Page pg;
117 pg.data.resize(page_size_);
118 const size_t begin = idx * page_size_;
119 const size_t avail = std::min(page_size_, file_size_ - begin);

Callers

nothing calls this directly

Calls 7

file_seek_absFunction · 0.85
resizeMethod · 0.80
dataMethod · 0.80
findMethod · 0.45
endMethod · 0.45
sizeMethod · 0.45
beginMethod · 0.45

Tested by

no test coverage detected