/** * Is key present in the database? */ gboolean dbmw_exists(dbmw_t *dw, gconstpointer key) { struct cached *entry; gboolean ret; dbmw_check(dw); g_assert(key); dw->r_access++; entry = map_lookup(dw->values, key); if (entry) { dw->r_hits++; return !entry->absent; } dw->ioerr = FALSE; ret = dbmap_contains(dw->dm, key); if (dbmap_has_ioerr(dw->dm)) { dw->ioerr = TRUE; dw->error = errno; g_warning("DBMW \"%s\" I/O error whilst checking key existence: %s", dw->name, dbmap_strerror(dw->dm)); return FALSE; } /* * If the maximum value length of the DB is 0, then it is used as a * "search table" only, meaning there will be no read to get values, * only existence checks. * * Therefore, it makes sense to cache existence checks. A data read * will also correctly return a null item from the cache. */ if (0 == dw->value_size) { WALLOC0(entry); entry->absent = !ret; (void) allocate_entry(dw, key, entry); } return ret; }
/** * Is key present in the database? */ bool dbmw_exists(dbmw_t *dw, const void *key) { struct cached *entry; bool ret; dbmw_check(dw); g_assert(key); dw->r_access++; entry = map_lookup(dw->values, key); if (entry) { if (dbg_ds_debugging(dw->dbg, 5, DBG_DSF_CACHING | DBG_DSF_ACCESS)) { dbg_ds_log(dw->dbg, dw, "%s: read cache hit on %s key=%s%s", G_STRFUNC, entry->dirty ? "dirty" : "clean", dbg_ds_keystr(dw->dbg, key, (size_t) -1), entry->absent ? " (absent)" : ""); } dw->r_hits++; return !entry->absent; } dw->ioerr = FALSE; ret = dbmap_contains(dw->dm, key); if (dbmap_has_ioerr(dw->dm)) { dw->ioerr = TRUE; dw->error = errno; s_warning("DBMW \"%s\" I/O error whilst checking key existence: %s", dw->name, dbmap_strerror(dw->dm)); return FALSE; } /* * If the maximum value length of the DB is 0, then it is used as a * "search table" only, meaning there will be no read to get values, * only existence checks. * * Therefore, it makes sense to cache existence checks. A data read * will also correctly return a null item from the cache. * * If the value length is not 0, we only cache negative lookups (i.e. * the value was not found) because we did not get any value so it is * possible to record an absent cache entry. */ if (0 == dw->value_size || !ret) { WALLOC0(entry); entry->absent = !ret; (void) allocate_entry(dw, key, entry); if (dbg_ds_debugging(dw->dbg, 2, DBG_DSF_CACHING)) { dbg_ds_log(dw->dbg, dw, "%s: cached %s key=%s", G_STRFUNC, entry->absent ? "absent" : "present", dbg_ds_keystr(dw->dbg, key, (size_t) -1)); } } return ret; }