/** * Synchronize dirty values. * * The ``which'' argument is a bitfield indicating the set of things to * synchronize: * * DBMW_SYNC_CACHE requests that dirty values from the local DBMW cache * be flushed to the DB map layer immediately. * * DBMW_SYNC_MAP requests that the DB map layer be flushed, if it is backed * by disk data. * * If DBMW_DELETED_ONLY is specified along with DBMW_SYNC_CACHE, only the * dirty values that are marked as pending deletion are flushed. * * @return amount of value flushes plus amount of sdbm page flushes, -1 if * an error occurred. */ ssize_t dbmw_sync(dbmw_t *dw, int which) { ssize_t amount = 0; gboolean error = FALSE; if (which & DBMW_SYNC_CACHE) { struct flush_context ctx; ctx.dw = dw; ctx.error = FALSE; ctx.deleted_only = booleanize(which & DBMW_DELETED_ONLY); ctx.amount = 0; map_foreach(dw->values, flush_dirty, &ctx); if (!ctx.error) dw->count_needs_sync = FALSE; amount += ctx.amount; error = ctx.error; } if (which & DBMW_SYNC_MAP) { ssize_t ret = dbmap_sync(dw->dm); if (-1 == ret) error = TRUE; else amount += ret; } return error ? -1 : amount; }
/** * Synchronize dirty values. * * The ``which'' argument is a bitfield indicating the set of things to * synchronize: * * DBMW_SYNC_CACHE requests that dirty values from the local DBMW cache * be flushed to the DB map layer immediately. * * DBMW_SYNC_MAP requests that the DB map layer be flushed, if it is backed * by disk data. * * If DBMW_DELETED_ONLY is specified along with DBMW_SYNC_CACHE, only the * dirty values that are marked as pending deletion are flushed. * * @return amount of value flushes plus amount of sdbm page flushes, -1 if * an error occurred. */ ssize_t dbmw_sync(dbmw_t *dw, int which) { ssize_t amount = 0; size_t pages = 0, values = 0; bool error = FALSE; dbmw_check(dw); if (which & DBMW_SYNC_CACHE) { struct flush_context ctx; ctx.dw = dw; ctx.error = FALSE; ctx.deleted_only = booleanize(which & DBMW_DELETED_ONLY); ctx.amount = 0; if (dbg_ds_debugging(dw->dbg, 6, DBG_DSF_CACHING)) { dbg_ds_log(dw->dbg, dw, "%s: syncing cache%s", G_STRFUNC, ctx.deleted_only ? " (deleted only)" : ""); } map_foreach(dw->values, flush_dirty, &ctx); if (!ctx.error && !ctx.deleted_only) dw->count_needs_sync = FALSE; /* * We can safely reset the amount of cached entries to 0, regardless * of whether we only sync'ed deleted entries: that value is rather * meaningless when ``count_needs_sync'' is TRUE anyway since we will * come here first, and we'll then reset it to zero. */ dw->cached = 0; /* No more dirty values */ amount += ctx.amount; values = ctx.amount; error = ctx.error; } if (which & DBMW_SYNC_MAP) { ssize_t ret; if (dbg_ds_debugging(dw->dbg, 6, DBG_DSF_CACHING)) dbg_ds_log(dw->dbg, dw, "%s: syncing map", G_STRFUNC); ret = dbmap_sync(dw->dm); if (-1 == ret) { error = TRUE; } else { amount += ret; pages = ret; } } if (dbg_ds_debugging(dw->dbg, 5, DBG_DSF_CACHING)) { dbg_ds_log(dw->dbg, dw, "%s: %s (flushed %zu value%s, %zu page%s)", G_STRFUNC, error ? "FAILED" : "OK", values, plural(values), pages, plural(pages)); } return error ? -1 : amount; }