_PUBLIC_ int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, int (*parser)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data) { tdb_off_t rec_ptr; struct tdb_record rec; int ret; uint32_t hash; /* find which hash bucket it is in */ hash = tdb->hash_fn(&key); if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) { /* record not found */ tdb_trace_1rec_ret(tdb, "tdb_parse_record", key, -1); tdb->ecode = TDB_ERR_NOEXIST; return -1; } tdb_trace_1rec_ret(tdb, "tdb_parse_record", key, 0); ret = tdb_parse_data(tdb, key, rec_ptr + sizeof(rec) + rec.key_len, rec.data_len, parser, private_data); tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); return ret; }
_PUBLIC_ int tdb_exists(struct tdb_context *tdb, TDB_DATA key) { uint32_t hash = tdb->hash_fn(&key); int ret; ret = tdb_exists_hash(tdb, key, hash); tdb_trace_1rec_ret(tdb, "tdb_exists", key, ret); return ret; }
/* lock/unlock one hash chain, non-blocking. This is meant to be used to reduce contention - it cannot guarantee how many records will be locked */ _PUBLIC_ int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key) { int ret = tdb_lock_nonblock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); tdb_trace_1rec_ret(tdb, "tdb_chainlock_nonblock", key, ret); return ret; }