hash/index/atom

1. Hash.c/hash.h

typedef struct hash
{
HashFunctions fun; /* Function block */
int is_allocated; /* 0 iff hash structure is on stack or is static */
ErtsAlcType_t type;
char* name; /* Table name (static string, for debugging) */
int size; /* Number of slots */
int size20percent; /* 20 percent of number of slots */
int size80percent; /* 80 percent of number of slots */
int ix; /* Size index in size table */
int used; /* Number of slots used */
HashBucket** bucket; /* Vector of bucket pointers (objects) */
} Hash;

函数:
typedef struct hash_functions
{
H_FUN hash; //取值
HCMP_FUN cmp; //比较
HALLOC_FUN alloc;
HFREE_FUN free;
} HashFunctions;

桶:
/*
** This bucket must be placed in top of
** every object that uses hashing!!!
** (Object*) == (Object*) &bucket
*/
typedef struct hash_bucket
{
struct hash_bucket* next; /* Next bucket */
HashValue hvalue; /* Store hash value for get, rehash */
} HashBucket;

查找:
/*
** Find an object in the hash table
**
*/
void* hash_get(Hash* h, void* tmpl)
{
HashValue hval = h->fun.hash(tmpl);
int ix = hval % h->size;
HashBucket* b = h->bucket[ix];

while(b != (HashBucket*) 0) {
if ((b->hvalue == hval) && (h->fun.cmp(tmpl, (void*)b) == 0))
return (void*) b;
b = b->next;
}
return (void*) 0;
}

Rehash???
2. Index.c/index.h


typedef struct index_table
{
Hash htable; /* Mapping obj -> index */
ErtsAlcType_t type;
int size; /* Allocated size */
int limit; /* Max size */
int entries; /* Number of entries */
IndexSlot*** seg_table; /* Mapping index -> obj */
} IndexTable;


Hash中应该存储的是 obj -> index(即IndexSlot*)


int
index_put(IndexTable* t, void* tmpl)
{
int ix;
IndexSlot* p = (IndexSlot*) hash_put(&t->htable, tmpl);

if (p->index >= 0) {
return p->index;
}

ix = t->entries;
if (ix >= t->size) {
Uint sz;
if (ix >= t->limit) {
erl_exit(1, "no more index entries in %s (max=%d)\n",
t->htable.name, t->limit);
}
sz = INDEX_PAGE_SIZE*sizeof(IndexSlot*);
t->seg_table[ix>>INDEX_PAGE_SHIFT] = erts_alloc(t->type, sz);
t->size += INDEX_PAGE_SIZE;
}
t->entries++;
p->index = ix;
t->seg_table[ix>>INDEX_PAGE_SHIFT][ix&INDEX_PAGE_MASK] = p;
return ix;
}

其实就是hash表,再加一个Index -> HashBucket的映射(即IndexSlot*)

3. Atom
typedef struct atom {
IndexSlot slot; /* MUST BE LOCATED AT TOP OF STRUCT!!! */
int len; /* length of atom name */
int ord0; /* ordinal value of first 3 bytes + 7 bits */
byte* name; /* name of atom */
} Atom;

Eterm
am_atom_put(const char* name, int len)
{
Atom a;
Eterm ret;
int aix;

/*
* Silently truncate the atom if it is too long. Overlong atoms
* could occur in situations where we have no good way to return
* an error, such as in the I/O system. (Unfortunately, many
* drivers don't check for errors.)
*
* If an error should be produced for overlong atoms (such in
* list_to_atom/1), the caller should check the length before
* calling this function.
*/
if (len > MAX_ATOM_LENGTH) {
len = MAX_ATOM_LENGTH;
}
a.len = len;
a.name = (byte*)name;
atom_read_lock();
aix = index_get(&erts_atom_table, (void*) &a);
atom_read_unlock();
if (aix >= 0)
ret = make_atom(aix);
else {
atom_write_lock();
ret = make_atom(index_put(&erts_atom_table, (void*) &a));
atom_write_unlock();
}
return ret;
}
如果erts_atom_table中有这个atom,则直接生成一个atom;
否则先index_put进来,在生成一个atom

#define make_atom(x) ((Eterm)(((x) << _TAG_IMMED2_SIZE) + _TAG_IMMED2_ATOM))

Atom的Eterm就是把一个index包上tag,length。。。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值