`

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。。。
分享到:
评论

相关推荐

    RUBY 教程.doc

    3. **IDE选择:** 推荐使用Visual Studio Code、Sublime Text或Atom等支持RUBY插件的集成开发环境(IDE),这些IDE提供了诸如代码高亮、智能提示等功能,可以极大地提高开发效率。 4. **Gem管理器:** Gem是RUBY中的...

    达梦数据库执行计划操作符介绍

    NEST LOOP INNER JOIN2是达梦数据库中的嵌套循环内连接操作符,用于连接两个表时没有索引可用,且无法使用HASH连接的情况。例如,下面的SQL语句中,NEST LOOP INNER JOIN2操作符将被用来连接t1和t2表: ```sql ...

    Bochs - The cross platform IA-32 (x86) emulator

    Changes in 2.4.6 (February 22, 2011): Brief summary : - Support more host OS to run on: - Include win64 native binary in the release. - Fixed failures on big endian hosts. - BIOS: Support for up to...

    常用Common LISP函数分类总结.docx

    - `(atom object)`:检查object是否为原子,即不是cons结构。 - `(characterp object)`:判断object是否为字符。 - `(compoundp object)`:检查object是否为复合对象,即非原子。 - `(compile-function-p object)`:...

    ZendFramework中文文档

    13.6. 单个Atom条目的处理 13.7. 修改Feed和条目结构 13.8. 自定义Feed和条目类 14. Zend_Filter 14.1. 简介 14.1.1. 什么是过滤器(filter)? 14.1.2. 过滤器的基本用法 14.1.3. 使用静态 get() 方法 14.2. ...

Global site tag (gtag.js) - Google Analytics