示例#1
0
QObject *qdict_get(const QDict *qdict, const char *key)
{
    QDictEntry *entry;

    entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_HASH_SIZE);
    return (entry == NULL ? NULL : entry->value);
}
示例#2
0
enum TDB_ERROR tdb1_parse_record(struct tdb_context *tdb, TDB_DATA key,
				 enum TDB_ERROR (*parser)(TDB_DATA key,
							  TDB_DATA data,
							  void *private_data),
				 void *private_data)
{
	tdb1_off_t rec_ptr;
	struct tdb1_record rec;
	enum TDB_ERROR ret;
	uint32_t hash;

	/* find which hash bucket it is in */
	hash = tdb_hash(tdb, key.dptr, key.dsize);

	if (!(rec_ptr = tdb1_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) {
		return tdb->last_error;
	}

	ret = tdb1_parse_data(tdb, key, rec_ptr + sizeof(rec) + rec.key_len,
			     rec.data_len, parser, private_data);

	tdb1_unlock(tdb, TDB1_BUCKET(rec.full_hash), F_RDLCK);

	return ret;
}
示例#3
0
int tdb1_delete(struct tdb_context *tdb, TDB_DATA key)
{
	uint32_t hash = tdb_hash(tdb, key.dptr, key.dsize);
	int ret;

	assert(tdb->flags & TDB_VERSION1);
	ret = tdb1_delete_hash(tdb, key, hash);
	return ret;
}
示例#4
0
void qdict_del(QDict *qdict, const char *key)
{
    QDictEntry *entry;

    entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_HASH_SIZE);
    if (entry) {
        QLIST_REMOVE(entry, next);
        qentry_destroy(entry);
        qdict->size--;
    }
}
示例#5
0
文件: qdict.c 项目: 0bliv10n/s2e
/**
 * qdict_next(): Return next qdict entry in an iteration.
 */
const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry)
{
    QDictEntry *ret;

    ret = QLIST_NEXT(entry, next);
    if (!ret) {
        unsigned int bucket = tdb_hash(entry->key) % QDICT_BUCKET_MAX;
        ret = qdict_next_entry(qdict, bucket + 1);
    }

    return ret;
}
示例#6
0
/* Append to an entry. Create if not exist. */
int tdb1_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf)
{
	uint32_t hash;
	TDB_DATA dbuf;
	int ret = -1;

	assert(tdb->flags & TDB_VERSION1);

	/* find which hash bucket it is in */
	hash = tdb_hash(tdb, key.dptr, key.dsize);
	if (tdb1_lock(tdb, TDB1_BUCKET(hash), F_WRLCK) == -1)
		return -1;

	dbuf = _tdb1_fetch(tdb, key);

	if (dbuf.dptr == NULL) {
		dbuf.dptr = (unsigned char *)malloc(new_dbuf.dsize);
	} else {
		unsigned int new_len = dbuf.dsize + new_dbuf.dsize;
		unsigned char *new_dptr;

		/* realloc '0' is special: don't do that. */
		if (new_len == 0)
			new_len = 1;
		new_dptr = (unsigned char *)realloc(dbuf.dptr, new_len);
		if (new_dptr == NULL) {
			free(dbuf.dptr);
		}
		dbuf.dptr = new_dptr;
	}

	if (dbuf.dptr == NULL) {
		tdb->last_error = TDB_ERR_OOM;
		goto failed;
	}

	memcpy(dbuf.dptr + dbuf.dsize, new_dbuf.dptr, new_dbuf.dsize);
	dbuf.dsize += new_dbuf.dsize;

	ret = _tdb1_store(tdb, key, dbuf, 0, hash);

failed:
	tdb1_unlock(tdb, TDB1_BUCKET(hash), F_WRLCK);
	SAFE_FREE(dbuf.dptr);
	return ret;
}
示例#7
0
void qdict_put_obj(QDict *qdict, const char *key, QObject *value)
{
    unsigned int hash;
    QDictEntry *entry;

    hash = tdb_hash(key) % QDICT_HASH_SIZE;
    entry = qdict_find(qdict, key, hash);
    if (entry) {
        /* replace key's value */
        qobject_decref(entry->value);
        entry->value = value;
    } else {
        /* allocate a new entry */
        entry = alloc_entry(key, value);
        QLIST_INSERT_HEAD(&qdict->table[hash], entry, next);
        qdict->size++;
    }
}
示例#8
0
/* If an entry doesn't exist tdb1_err will be set to
 * TDB_ERR_NOEXIST. If a key has no data attached
 * then the TDB_DATA will have zero length but
 * a non-zero pointer
 */
static TDB_DATA _tdb1_fetch(struct tdb_context *tdb, TDB_DATA key)
{
	tdb1_off_t rec_ptr;
	struct tdb1_record rec;
	TDB_DATA ret;
	uint32_t hash;

	/* find which hash bucket it is in */
	hash = tdb_hash(tdb, key.dptr, key.dsize);
	if (!(rec_ptr = tdb1_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) {
		ret.dptr = NULL;
		ret.dsize = 0;
		return ret;
	}

	ret.dptr = tdb1_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len,
				  rec.data_len);
	ret.dsize = rec.data_len;
	tdb1_unlock(tdb, TDB1_BUCKET(rec.full_hash), F_RDLCK);
	return ret;
}
示例#9
0
/* store an element in the database, replacing any existing element
   with the same key

   return 0 on success, -1 on failure
*/
int tdb1_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
{
	uint32_t hash;
	int ret;

	assert(tdb->flags & TDB_VERSION1);

	if ((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) {
		tdb->last_error = tdb_logerr(tdb, TDB_ERR_RDONLY,
					     TDB_LOG_USE_ERROR,
					     "tdb_store: read-only tdb");
		return -1;
	}

	/* find which hash bucket it is in */
	hash = tdb_hash(tdb, key.dptr, key.dsize);
	if (tdb1_lock(tdb, TDB1_BUCKET(hash), F_WRLCK) == -1)
		return -1;

	ret = _tdb1_store(tdb, key, dbuf, flag, hash);
	tdb1_unlock(tdb, TDB1_BUCKET(hash), F_WRLCK);
	return ret;
}
示例#10
0
文件: hash.c 项目: Arkhont/samba
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;
}
示例#11
0
文件: hash.c 项目: Arkhont/samba
/* This is the core routine which searches the hashtable for an entry.
 * On error, no locks are held and -ve is returned.
 * Otherwise, hinfo is filled in (and the optional tinfo).
 * If not found, the return value is 0.
 * If found, the return value is the offset, and *rec is the record. */
tdb_off_t find_and_lock(struct tdb_context *tdb,
			struct tdb_data key,
			int ltype,
			struct hash_info *h,
			struct tdb_used_record *rec,
			struct traverse_info *tinfo)
{
	uint32_t i, group;
	tdb_off_t hashtable;
	enum TDB_ERROR ecode;

	h->h = tdb_hash(tdb, key.dptr, key.dsize);
	h->hash_used = 0;
	group = use_bits(h, TDB_TOPLEVEL_HASH_BITS - TDB_HASH_GROUP_BITS);
	h->home_bucket = use_bits(h, TDB_HASH_GROUP_BITS);

	h->hlock_start = hlock_range(group, &h->hlock_range);
	ecode = tdb_lock_hashes(tdb, h->hlock_start, h->hlock_range, ltype,
				TDB_LOCK_WAIT);
	if (ecode != TDB_SUCCESS) {
		return ecode;
	}

	hashtable = offsetof(struct tdb_header, hashtable);
	if (tinfo) {
		tinfo->toplevel_group = group;
		tinfo->num_levels = 1;
		tinfo->levels[0].entry = 0;
		tinfo->levels[0].hashtable = hashtable
			+ (group << TDB_HASH_GROUP_BITS) * sizeof(tdb_off_t);
		tinfo->levels[0].total_buckets = 1 << TDB_HASH_GROUP_BITS;
	}

	while (h->hash_used <= 64) {
		/* Read in the hash group. */
		h->group_start = hashtable
			+ group * (sizeof(tdb_off_t) << TDB_HASH_GROUP_BITS);

		ecode = tdb_read_convert(tdb, h->group_start, &h->group,
					 sizeof(h->group));
		if (ecode != TDB_SUCCESS) {
			goto fail;
		}

		/* Pointer to another hash table?  Go down... */
		if (is_subhash(h->group[h->home_bucket])) {
			hashtable = (h->group[h->home_bucket] & TDB_OFF_MASK)
				+ sizeof(struct tdb_used_record);
			if (tinfo) {
				/* When we come back, use *next* bucket */
				tinfo->levels[tinfo->num_levels-1].entry
					+= h->home_bucket + 1;
			}
			group = use_bits(h, TDB_SUBLEVEL_HASH_BITS
					 - TDB_HASH_GROUP_BITS);
			h->home_bucket = use_bits(h, TDB_HASH_GROUP_BITS);
			if (tinfo) {
				tinfo->levels[tinfo->num_levels].hashtable
					= hashtable;
				tinfo->levels[tinfo->num_levels].total_buckets
					= 1 << TDB_SUBLEVEL_HASH_BITS;
				tinfo->levels[tinfo->num_levels].entry
					= group << TDB_HASH_GROUP_BITS;
				tinfo->num_levels++;
			}
			continue;
		}

		/* It's in this group: search (until 0 or all searched) */
		for (i = 0, h->found_bucket = h->home_bucket;
		     i < (1 << TDB_HASH_GROUP_BITS);
		     i++, h->found_bucket = ((h->found_bucket+1)
					     % (1 << TDB_HASH_GROUP_BITS))) {
			tdb_bool_err berr;
			if (is_subhash(h->group[h->found_bucket]))
				continue;

			if (!h->group[h->found_bucket])
				break;

			berr = match(tdb, h, &key, h->group[h->found_bucket],
				     rec);
			if (berr < 0) {
				ecode = berr;
				goto fail;
			}
			if (berr) {
				if (tinfo) {
					tinfo->levels[tinfo->num_levels-1].entry
						+= h->found_bucket;
				}
				return h->group[h->found_bucket] & TDB_OFF_MASK;
			}
		}
		/* Didn't find it: h indicates where it would go. */
		return 0;
	}

	return find_in_chain(tdb, key, hashtable, h, rec, tinfo);

fail:
	tdb_unlock_hashes(tdb, h->hlock_start, h->hlock_range, ltype);
	return ecode;
}
示例#12
0
int qdict_haskey(const QDict *qdict, const char *key)
{
    unsigned int hash = tdb_hash(key) % QDICT_HASH_SIZE;
    return (qdict_find(qdict, key, hash) == NULL ? 0 : 1);
}
示例#13
0
文件: modpost.c 项目: nyyotam/u-boot
	memset(s, 0, sizeof(*s));
	strcpy(s->name, name);
	s->weak = weak;
	s->next = next;
	return s;
}

/* For the hash of exported symbols */
static struct symbol *new_symbol(const char *name, struct module *module,
				 enum export export)
{
	unsigned int hash;
	struct symbol *new;

	hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
	new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);
	new->module = module;
	new->export = export;
	return new;
}

static struct symbol *find_symbol(const char *name)
{
	struct symbol *s;

	/* For our purposes, .foo matches foo.  PPC64 needs this. */
	if (name[0] == '.')
		name++;

	for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s=s->next) {
示例#14
0
文件: qdict.c 项目: 0bliv10n/s2e
/**
 * qdict_haskey(): Check if 'key' exists
 *
 * Return 1 if 'key' exists in the dict, 0 otherwise
 */
int qdict_haskey(const QDict *qdict, const char *key)
{
    unsigned int bucket = tdb_hash(key) % QDICT_BUCKET_MAX;
    return (qdict_find(qdict, key, bucket) == NULL ? 0 : 1);
}