tokyo cabinet源代码分析(3)

2.3数据记录的写入

   在前面的2节对于内存hash memory的基本数据结构进行了分析。通过tcmdbput将key,value结构写入到内存中。

/*通过tcmdbput进行存储 *先通过key映射到某个map上面 *然后在map上面进行bucket的操作*/ /* Store a record into an on-memory hash database. */ void tcmdbput(TCMDB *mdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ assert(mdb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); unsigned int mi; TCMDBHASH(mi, kbuf, ksiz); if(pthread_rwlock_wrlock((pthread_rwlock_t *)mdb->mmtxs + mi) != 0) return; tcmapput(mdb->maps[mi], kbuf, ksiz, vbuf, vsiz); pthread_rwlock_unlock((pthread_rwlock_t *)mdb->mmtxs + mi); }

2.3.1 Hash算法映射

先通过hash算法,映射到maps数据的元素上。

 

/*将一个对象存储在map object中*/ /* Store a record into a map object. */ void tcmapput(TCMAP *map, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ assert(map && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); if(ksiz > TCMAPKMAXSIZ) ksiz = TCMAPKMAXSIZ; uint32_t hash; /*第一次HASH映射到map数组上*/ TCMAPHASH1(hash, kbuf, ksiz); int bidx = hash % map->bnum; TCMAPREC *rec = map->buckets[bidx]; /*entp保存父节点地址*/ TCMAPREC **entp = map->buckets + bidx; /*第二次HASH映射到特定map的bucket上*/ TCMAPHASH2(hash, kbuf, ksiz); hash &= ~TCMAPKMAXSIZ;

再通过hash算法,映射到特定maps元素的buckets数组中。即:先找个MAP,再找buckets。

2.3.2记录初次插入二叉树

我们先讨论初次加入二叉树结构的方法。

/*如果为首次加入,则直接放入到buckets中*/ /*计算需要pad的字节大小*? int psiz = TCALIGNPAD(ksiz); map->msiz += ksiz + vsiz; /*分配key,value,pad大小,末尾'/0' *rec表示了左右子树,父节点*/ TCMALLOC(rec, sizeof(*rec) + ksiz + psiz + vsiz + 1); char *dbuf = (char *)rec + sizeof(*rec); /*在TCMAPREC结构体之后,存放key的内容*/ memcpy(dbuf, kbuf, ksiz); /*key值通过在末尾增加'/0'分割*/ dbuf[ksiz] = '/0'; rec->ksiz = ksiz | hash; /*value值的拷贝*/ memcpy(dbuf + ksiz + psiz, vbuf, vsiz); dbuf[ksiz+psiz+vsiz] = '/0'; /*修改rec记录的大小*/ rec->vsiz = vsiz; rec->left = NULL; rec->right = NULL; /*record的prev节点指向原先的最后一个节点 *构成双向链表结构,并通过Map的first和last *节点进行连接*/ rec->prev = map->last; rec->next = NULL; /*加入到树中*/ *entp = rec; /*如果该buckets数组为初次插入节点,则first头节点指向该记录*/ if(!map->first) map->first = rec; /*如果last节点不为空,(已经有插入节点),则将原先节点的next节点 *指向该记录,然后last节点指向新的记录,即:将原先的节点都连接起来*/ if(map->last) map->last->next = rec; map->last = rec; /*record记录数增加*/ map->rnum++;

 

你可能感兴趣的:(数据结构,算法,object,null,存储,代码分析)