* Update the on-disk chain state. * The caches and indexes are flushed if either they're too large, forceWrite is set, or * fast is not set and it's been a while since the last write. */
| 3341 | * fast is not set and it's been a while since the last write. |
| 3342 | */ |
| 3343 | static bool FlushStateToDisk(CValidationState& state, FlushStateMode mode, int nManualPruneHeight) |
| 3344 | { |
| 3345 | //LOCK2(cs_main, cs_LastBlockFile); |
| 3346 | static int64_t nLastWrite = 0; |
| 3347 | static int64_t nLastFlush = 0; |
| 3348 | static int64_t nLastSetChain = 0; |
| 3349 | int retries = MAX_DATA_FLUSH_RETRY; |
| 3350 | string strErr = ""; |
| 3351 | |
| 3352 | while (retries > 0) |
| 3353 | { |
| 3354 | bool isExceptionOccured = false; |
| 3355 | std::set<int> setFilesToPrune; |
| 3356 | bool fFlushForPrune = false; |
| 3357 | try |
| 3358 | { |
| 3359 | if (fPruneMode && (fCheckForPruning || nManualPruneHeight > 0) && !fReindex) |
| 3360 | { |
| 3361 | if (nManualPruneHeight > 0) { |
| 3362 | FindFilesToPruneManual(setFilesToPrune, nManualPruneHeight); |
| 3363 | } else { |
| 3364 | FindFilesToPrune(setFilesToPrune, Params().PruneAfterHeight()); |
| 3365 | fCheckForPruning = false; |
| 3366 | } |
| 3367 | |
| 3368 | if (!setFilesToPrune.empty()) { |
| 3369 | fFlushForPrune = true; |
| 3370 | if (!fHavePruned) { |
| 3371 | pblocktree->WriteFlag("prunedblockfiles", true); |
| 3372 | fHavePruned = true; |
| 3373 | } |
| 3374 | } |
| 3375 | } |
| 3376 | int64_t nNow = GetTimeMicros(); |
| 3377 | // Avoid writing/flushing immediately after startup. |
| 3378 | if (nLastWrite == 0) { |
| 3379 | nLastWrite = nNow; |
| 3380 | } |
| 3381 | if (nLastFlush == 0) { |
| 3382 | nLastFlush = nNow; |
| 3383 | } |
| 3384 | if (nLastSetChain == 0) { |
| 3385 | nLastSetChain = nNow; |
| 3386 | } |
| 3387 | int64_t maxMempoolSize = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; |
| 3388 | int64_t nMempoolUsage = mempool.DynamicMemoryUsage(); |
| 3389 | int64_t cacheSize = pcoinsTip->DynamicMemoryUsage() * 2; // coincache mempool memory peak |
| 3390 | int64_t nTotalSpace = nCoinCacheUsage + max<int64_t>(maxMempoolSize - nMempoolUsage, 0); |
| 3391 | int64_t minMemPeak = 50 * 2; |
| 3392 | int64_t maxMemPeak = 200 * 2; |
| 3393 | // The cache is large and close to the limit, but we have time now (not in the middle of a block processing). |
| 3394 | bool fCacheLarge = mode == FLUSH_STATE_PERIODIC && cacheSize > min(max(nTotalSpace / 2, nTotalSpace - minMemPeak * 1024 * 1024), max((9 * nTotalSpace) / 10, nTotalSpace - maxMemPeak * 1024 * 1024)); |
| 3395 | // The cache is over the limit, we have to write now. |
| 3396 | bool fCacheCritical = mode == FLUSH_STATE_IF_NEEDED && cacheSize > nTotalSpace; |
| 3397 | // It's been a while since we wrote the block index to disk. Do this frequently, so we don't need to redownload after a crash. |
| 3398 | bool fPeriodicWrite = mode == FLUSH_STATE_PERIODIC && nNow > nLastWrite + (int64_t)DATABASE_WRITE_INTERVAL * 1000000; |
| 3399 | // It's been very long since we flushed the cache. Do this infrequently, to optimize cache usage. |
| 3400 | bool fPeriodicFlush = mode == FLUSH_STATE_PERIODIC && nNow > nLastFlush + (int64_t)DATABASE_FLUSH_INTERVAL * 1000000; |
no test coverage detected