免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2309 | 回复: 2
打印 上一主题 下一主题

[算法] tokyocabinet的内存tree数据结构 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-01-04 20:37 |只看该作者 |倒序浏览
  1. #include <stdio.h>
  2. #include <assert.h>
  3. #include <stdlib.h>
  4. #include <stddef.h>
  5. #include <string.h>

  6. /* compare keys of two records by lexical order */
  7. #define TCCMPLEXICAL(TC_rv, TC_aptr, TC_asiz, TC_bptr, TC_bsiz) \
  8.   do { \
  9.     (TC_rv) = 0; \
  10.     int _TC_min = (TC_asiz) < (TC_bsiz) ? (TC_asiz) : (TC_bsiz); \
  11.     for(int _TC_i = 0; _TC_i < _TC_min; _TC_i++){ \
  12.       if(((unsigned char *)(TC_aptr))[_TC_i] != ((unsigned char *)(TC_bptr))[_TC_i]){ \
  13.         (TC_rv) = ((unsigned char *)(TC_aptr))[_TC_i] - ((unsigned char *)(TC_bptr))[_TC_i]; \
  14.         break; \
  15.       } \
  16.     } \
  17.     if((TC_rv) == 0) (TC_rv) = (TC_asiz) - (TC_bsiz); \
  18.   } while(false)



  19. /* Compare keys of two records by lexical order. */
  20. int tccmplexical(const char *aptr, int asiz, const char *bptr, int bsiz, void *op){
  21.         assert(aptr && asiz >= 0 && bptr && bsiz >= 0);
  22.         int rv;
  23.         TCCMPLEXICAL(rv, aptr, asiz, bptr, bsiz);
  24.         return rv;
  25. }


  26. typedef int (*TCCMP)(const char *aptr, int asiz, const char *bptr, int bsiz, void *op);

  27. typedef struct _TCTREEREC {              /* type of structure for an element of a tree */
  28.   int ksiz;                          /* size of the region of the key */
  29.   int vsiz;                          /* size of the region of the value */
  30.   char v[255];
  31.   char k[255];
  32.   struct _TCTREEREC *left;               /* pointer to the left child */
  33.   struct _TCTREEREC *right;              /* pointer to the right child */
  34. } TCTREEREC;

  35. typedef struct {                         /* type of structure for a tree */
  36.   TCTREEREC *root;                       /* pointer to the root element */
  37.   TCTREEREC *cur;                        /* pointer to the current element */
  38.   unsigned long long rnum;                         /* number of records */
  39.   unsigned long long msiz;                         /* total size of records */
  40.   TCCMP cmp;                             /* pointer to the comparison function */
  41.   void *cmpop;                           /* opaque object for the comparison function */
  42. } TCTREE;


  43. TCTREEREC* tctreesplay(TCTREE *tree, const char *kbuf, int ksiz){
  44.         assert(tree && kbuf && ksiz>=0);
  45.         TCTREEREC *top = tree->root;
  46.         if (!top) return NULL;

  47.         TCCMP cmp = tree->cmp;
  48.         void *cmpop = tree->cmpop;
  49.         TCTREEREC ent;
  50.         ent.left = NULL;
  51.         ent.right = NULL;
  52.         TCTREEREC *lrec = &ent;
  53.         TCTREEREC *rrec = &ent;

  54.         while (true) {
  55.             char *dbuf = (char *)top + sizeof(*top);
  56.         int cv = cmp(kbuf, ksiz, dbuf, top->ksiz, cmpop);
  57.                 if (cv < 0 ) {
  58.                   if(!top->left) break;
  59.                   dbuf = (char *)top->left + sizeof(*top);
  60.                   cv = cmp(kbuf, ksiz, dbuf, top->left->ksiz, cmpop);
  61.                   if(cv < 0){
  62.                         TCTREEREC *swap = top->left;
  63.                         top->left = swap->right;
  64.                         swap->right = top;
  65.                         top = swap;
  66.                         if(!top->left) break;
  67.                   }
  68.                   rrec->left = top;
  69.                   rrec = top;
  70.                   top = top->left;
  71.                 } else if (cv >0 ) {
  72.                    if(!top->right) break;
  73.                   dbuf = (char *)top->right + sizeof(*top);
  74.                   cv = cmp(kbuf, ksiz, dbuf, top->right->ksiz, cmpop);
  75.                   if(cv > 0){
  76.                         TCTREEREC *swap = top->right;
  77.                         top->right = swap->left;
  78.                         swap->left = top;
  79.                         top = swap;
  80.                         if(!top->right) break;
  81.                   }
  82.                   lrec->right = top;
  83.                   lrec = top;
  84.                   top = top->right;
  85.                 } else {
  86.                    break;
  87.                 }
  88.         }


  89.         lrec->right = top->left;
  90.         rrec->left = top->right;
  91.         top->left = ent.right;
  92.         top->right = ent.left;
  93.         return top;
  94. }


  95. /* Store a record into a tree object. */
  96. void tctreeput(TCTREE *tree, const char *kbuf, int ksiz, const char *vbuf, int vsiz){
  97.   assert(tree && kbuf && ksiz >= 0 && vbuf && vsiz >= 0);
  98.   TCTREEREC *top = tctreesplay(tree, kbuf, ksiz);
  99.   if (!top){
  100.      TCTREEREC *rec;
  101.          rec = (TCTREEREC *)malloc(sizeof(*rec) + ksiz + vsiz + 1);
  102.          char *dbuf = (char *)rec + sizeof(*rec);
  103.      memcpy(dbuf, kbuf, ksiz);
  104.      dbuf[ksiz] = '\0';
  105.      rec->ksiz = ksiz;
  106.      memcpy(dbuf + ksiz, vbuf, vsiz);
  107.      dbuf[ksiz+vsiz] = '\0';
  108.      rec->vsiz = vsiz;
  109.      rec->left = NULL;
  110.      rec->right = NULL;
  111.          memcpy(rec->k, kbuf, ksiz);
  112.          memcpy(rec->v, vbuf, vsiz);
  113.      tree->root = rec;
  114.      tree->rnum = 1;
  115.      tree->msiz = ksiz + vsiz;
  116.      return;
  117.   }

  118.   char *dbuf = (char *)top + sizeof(*top);
  119.   int cv = tree->cmp(kbuf, ksiz, dbuf, top->ksiz, tree->cmpop);
  120.    if(cv < 0){
  121.             TCTREEREC *rec;
  122.          rec = (TCTREEREC *)malloc(sizeof(*rec) + ksiz + vsiz + 1);
  123.          char *dbuf = (char *)rec + sizeof(*rec);
  124.      memcpy(dbuf, kbuf, ksiz);
  125.      dbuf[ksiz] = '\0';
  126.      rec->ksiz = ksiz;
  127.      memcpy(dbuf + ksiz, vbuf, vsiz);
  128.      dbuf[ksiz+vsiz] = '\0';
  129.      rec->vsiz = vsiz;
  130.          memcpy(rec->k, kbuf, ksiz);
  131.          memcpy(rec->v, vbuf, vsiz);
  132.          rec->left = top->left;
  133.      rec->right = top;
  134.      top->left = NULL;
  135.      tree->rnum++;
  136.      tree->msiz += ksiz + vsiz;
  137.      tree->root = rec;
  138.    } else if (cv>0) {
  139.      TCTREEREC *rec;
  140.          rec = (TCTREEREC *)malloc(sizeof(*rec) + ksiz + vsiz + 1);
  141.          char *dbuf = (char *)rec + sizeof(*rec);
  142.      memcpy(dbuf, kbuf, ksiz);
  143.      dbuf[ksiz] = '\0';
  144.      rec->ksiz = ksiz;
  145.      memcpy(dbuf + ksiz, vbuf, vsiz);
  146.      dbuf[ksiz+vsiz] = '\0';
  147.      rec->vsiz = vsiz;
  148.          memcpy(rec->k, kbuf, ksiz);
  149.          memcpy(rec->v, vbuf, vsiz);
  150.          rec->left = top;
  151.      rec->right = top->right;
  152.      top->right = NULL;
  153.      tree->rnum++;
  154.      tree->msiz += ksiz + vsiz;
  155.      tree->root = rec;
  156.    } else {
  157.        tree->msiz += vsiz - top->vsiz;
  158.            if(vsiz > top->vsiz){
  159.                   TCTREEREC *old = top;
  160.                   top = (TCTREEREC *)realloc(top,sizeof(*top) + ksiz + vsiz + 1);
  161.                   if(top != old){
  162.                         if(tree->cur == old) tree->cur = top;
  163.                         dbuf = (char *)top + sizeof(*top);
  164.                   }
  165.                 }
  166.                 memcpy(dbuf + ksiz, vbuf, vsiz);

  167.                 dbuf[ksiz+vsiz] = '\0';
  168.                 top->vsiz = vsiz;
  169.                 tree->root = top;
  170.    }
  171. }




  172. /* Create a tree object with specifying the custom comparison function. */
  173. TCTREE *tctreenew2(TCCMP cmp, void *cmpop){
  174.   assert(cmp);
  175.   TCTREE *tree;
  176.   tree = (TCTREE *)malloc(sizeof(*tree));
  177.   tree->root = NULL;
  178.   tree->cur = NULL;
  179.   tree->rnum = 0;
  180.   tree->msiz = 0;
  181.   tree->cmp = cmp;
  182.   tree->cmpop = cmpop;
  183.   return tree;
  184. }

  185. int main(void)
  186. {
  187.         TCTREE * tree = tctreenew2(tccmplexical, NULL);
  188.        
  189.         tctreeput(tree,"F", 1,"fff", 3);
  190.         tctreeput(tree,"D", 1,"ddd", 3);
  191.         tctreeput(tree,"E", 1,"eee", 3);
  192.         tctreeput(tree,"H", 1,"hhh", 3);
  193.         tctreeput(tree,"G", 1,"ggg", 3);
  194.         tctreeput(tree,"B", 1,"bbb", 3);
  195.         tctreeput(tree,"C", 1,"ccc", 3);
  196.         tctreeput(tree,"I", 1,"iii", 3);


  197.         /*

  198.         tctreeput(tree,"N", 1,"nnn", 3);
  199.         tctreeput(tree,"M", 1,"mmm", 3);
  200.         tctreeput(tree,"L", 1,"lll", 3);
  201.         tctreeput(tree,"K", 1,"kkk", 3);
  202.         tctreeput(tree,"J", 1,"jjj", 3);
  203.         tctreeput(tree,"I", 1,"iii", 3);
  204.         tctreeput(tree,"H", 1,"hhh", 3);
  205.         tctreeput(tree,"G", 1,"ggg", 3);
  206. */
  207.        

  208.          system("pause");
  209.      return 0;
  210. }
复制代码
求大神解读一下这是种什么样的二叉排序树吧,它是如何进行存储排序的,程序可以在vc2008下运行

论坛徽章:
1
寅虎
日期:2014-11-30 21:25:54
2 [报告]
发表于 2015-01-05 08:58 |只看该作者
splay树 伸展树

论坛徽章:
0
3 [报告]
发表于 2015-01-05 09:11 |只看该作者
是的 书本上好像没有介绍这个树
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP