Exemple #1
0
enum TDB_ERROR tdb_fetch(struct tdb_context *tdb, struct tdb_data key,
			 struct tdb_data *data)
{
	tdb_off_t off;
	struct tdb_used_record rec;
	struct hash_info h;
	enum TDB_ERROR ecode;

	off = find_and_lock(tdb, key, F_RDLCK, &h, &rec, NULL);
	if (TDB_OFF_IS_ERR(off)) {
		return tdb->last_error = off;
	}

	if (!off) {
		ecode = TDB_ERR_NOEXIST;
	} else {
		data->dsize = rec_data_length(&rec);
		data->dptr = tdb_alloc_read(tdb, off + sizeof(rec) + key.dsize,
					    data->dsize);
		if (TDB_PTR_IS_ERR(data->dptr)) {
			ecode = TDB_PTR_ERR(data->dptr);
		} else
			ecode = TDB_SUCCESS;
	}

	tdb_unlock_hashes(tdb, h.hlock_start, h.hlock_range, F_RDLCK);
	return tdb->last_error = ecode;
}
Exemple #2
0
uint64_t hash_record(struct tdb_context *tdb, tdb_off_t off)
{
	const struct tdb_used_record *r;
	const void *key;
	uint64_t klen, hash;

	r = tdb_access_read(tdb, off, sizeof(*r), true);
	if (TDB_PTR_IS_ERR(r)) {
		/* FIXME */
		return 0;
	}

	klen = rec_key_length(r);
	tdb_access_release(tdb, r);

	key = tdb_access_read(tdb, off + sizeof(*r), klen, false);
	if (TDB_PTR_IS_ERR(key)) {
		return 0;
	}

	hash = tdb_hash(tdb, key, klen);
	tdb_access_release(tdb, key);
	return hash;
}
Exemple #3
0
enum TDB_ERROR tdb_parse_record_(struct tdb_context *tdb,
				 TDB_DATA key,
				 enum TDB_ERROR (*parse)(TDB_DATA k,
							 TDB_DATA d,
							 void *data),
				 void *data)
{
	tdb_off_t off;
	struct tdb_used_record rec;
	struct hash_info h;
	enum TDB_ERROR ecode;

	if (tdb->flags & TDB_VERSION1) {
		return tdb->last_error = tdb1_parse_record(tdb, key, parse,
							   data);
	}

	off = find_and_lock(tdb, key, F_RDLCK, &h, &rec, NULL);
	if (TDB_OFF_IS_ERR(off)) {
		return tdb->last_error = TDB_OFF_TO_ERR(off);
	}

	if (!off) {
		ecode = TDB_ERR_NOEXIST;
	} else {
		const void *dptr;
		dptr = tdb_access_read(tdb, off + sizeof(rec) + key.dsize,
				       rec_data_length(&rec), false);
		if (TDB_PTR_IS_ERR(dptr)) {
			ecode = TDB_PTR_ERR(dptr);
		} else {
			TDB_DATA d = tdb_mkdata(dptr, rec_data_length(&rec));

			ecode = parse(key, d, data);
			tdb_access_release(tdb, dptr);
		}
	}

	tdb_unlock_hashes(tdb, h.hlock_start, h.hlock_range, F_RDLCK);
	return tdb->last_error = ecode;
}
Exemple #4
0
static tdb_bool_err key_matches(struct tdb_context *tdb,
				const struct tdb_used_record *rec,
				tdb_off_t off,
				const struct tdb_data *key)
{
	tdb_bool_err ret = false;
	const char *rkey;

	if (rec_key_length(rec) != key->dsize) {
		tdb->stats.compare_wrong_keylen++;
		return ret;
	}

	rkey = tdb_access_read(tdb, off + sizeof(*rec), key->dsize, false);
	if (TDB_PTR_IS_ERR(rkey)) {
		return TDB_PTR_ERR(rkey);
	}
	if (memcmp(rkey, key->dptr, key->dsize) == 0)
		ret = true;
	else
		tdb->stats.compare_wrong_keycmp++;
	tdb_access_release(tdb, rkey);
	return ret;
}