MCPcopy Create free account
hub / github.com/apple/foundationdb / changeFileSize

Method changeFileSize

fdbrpc/AsyncFileCached.actor.cpp:178–250  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

176}
177
178Future<Void> AsyncFileCached::changeFileSize(int64_t size) {
179 ++countFileCacheWrites;
180 ++countCacheWrites;
181
182 std::vector<Future<Void>> actors;
183 int64_t oldLength = length;
184
185 int offsetInPage = size % pageCache->pageSize;
186 int64_t pageOffset = size - offsetInPage;
187
188 if (offsetInPage == 0 && size == length) {
189 return Void();
190 }
191
192 length = size;
193 prevLength = size;
194
195 if (offsetInPage) {
196 CODE_PROBE(true, "Truncating to the middle of a page");
197 auto p = pages.find(pageOffset);
198 if (p != pages.end()) {
199 auto f = p->second->flush();
200 if (!f.isReady() || f.isError())
201 actors.push_back(f);
202 } else {
203 CODE_PROBE(true, "Truncating to the middle of a page that isn't in cache");
204 }
205
206 pageOffset += pageCache->pageSize;
207 }
208
209 // if this call to truncate results in a larger file, there is no
210 // need to erase any pages
211 if (oldLength > pageOffset) {
212 // Iterating through all pages results in better cache locality than
213 // looking up pages one by one in the hash table. However, if we only need
214 // to truncate a small portion of data, looking up pages one by one should
215 // be faster. So for now we do single key lookup for each page if it results
216 // in less than a fixed percentage of the unordered map being accessed.
217 int64_t numLookups = (oldLength + (pageCache->pageSize - 1) - pageOffset) / pageCache->pageSize;
218 if (numLookups < pages.size() * FLOW_KNOBS->PAGE_CACHE_TRUNCATE_LOOKUP_FRACTION) {
219 for (int64_t offset = pageOffset; offset < oldLength; offset += pageCache->pageSize) {
220 auto iter = pages.find(offset);
221 if (iter != pages.end()) {
222 auto f = iter->second->truncate();
223 if (!f.isReady() || f.isError()) {
224 actors.push_back(f);
225 }
226 pages.erase(iter);
227 }
228 }
229 } else {
230 for (auto p = pages.begin(); p != pages.end();) {
231 if (p->first >= pageOffset) {
232 auto f = p->second->truncate();
233 if (!f.isReady() || f.isError()) {
234 actors.push_back(f);
235 }

Callers 1

truncate_implMethod · 0.95

Calls 12

waitForAllFunction · 0.85
VoidClass · 0.70
findMethod · 0.45
endMethod · 0.45
flushMethod · 0.45
isReadyMethod · 0.45
isErrorMethod · 0.45
push_backMethod · 0.45
sizeMethod · 0.45
truncateMethod · 0.45
eraseMethod · 0.45
beginMethod · 0.45

Tested by

no test coverage detected