• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

B+树在内存的实现

武飞扬头像
flowesy
帮助1

       一个月前看完uCore内核后,决定写一个B 树在内存中的实现巩固一下在内核代码中学习到的一些编码技巧,B 树常用于组织起数据库的索引,且叶子节点包含真实内容,可以很方便地进行区间查找,比如select mkey > 5 in table之类的,通过叶子节点的链表就可以获取后面的数据了,由于磁盘中块的大小(大多数情况下pageSize = 4096),可以让树的中间节点包含多个子节点以使每个BNode结构体在磁盘上填满每页。从而减少磁盘io,提高运行效率。

        代码中的英文注释是我自己写的,可能有一些语法或者词性方面的错误(很久没有写英文了)。

        我定义的BNode结构体(在内存中),其中n1为子节点个数,isDirty为相对于磁盘数据是否要写回磁盘。List_entry为组织叶子节点的双链表(该技巧从ucore内核中学来的,如果list_entry用其他数据结构组织起来(比如红黑树),那么BNode就会被红黑树组织起来,该技巧可以减少代码量。)

  1.  
    struct BNode
  2.  
    {
  3.  
    unsigned n1 : 10;
  4.  
    unsigned isLeaf : 1;
  5.  
    unsigned isDirty : 1;
  6.  
     
  7.  
    //unsigned int n1;
  8.  
    //bool isLeaf;
  9.  
    BNode* fa;
  10.  
    List_entry leaflist;
  11.  
    BNode* childp[2 * t];//which contains the pointer of child node
  12.  
    //represent the block num of child(point to data block if leaf)
  13.  
    int ckey[2 * t];//represent the key for parition child(ckey[i] == the least key of corresponding child i)
  14.  
    BNode() :fa(NULL), isLeaf(true), n1(0), isDirty(0)
  15.  
    {
  16.  
     
  17.  
    };
  18.  
    ~BNode()
  19.  
    {
  20.  
    if (isDirty)
  21.  
    {
  22.  
    //printf("page write block num %u...\n", this);//WriteBlock func called,copy content from memory to hard disk
  23.  
    isDirty = 0;
  24.  
    }
  25.  
    //delete leaflist;
  26.  
    };
  27.  
    };
学新通

        其中BNode中childp虽然存的是子节点的虚地址,实际应用时应该存的是子节点所在的磁盘block num,通过ReadBlock将对应的BNode的读入内存中,然后填入内存中new的一个BNode。(List_entry中prev,nxt也是同理)

        ReadBlock最理想的状态是第一次由系统调用int 80触发,后面页置换出去的时候填入对应的磁盘块号,而后由14号中断(缺页)触发调入内存。

        t的选择应该使得BNode的大小 == pageSize,但为了测试可以把t设的小一些(>=3).

        经测试该B树叶子节点排序没有什么问题,不过中间有没有退化就不知道了,应该没有吧,毕竟我也没有怎么看B 树的定义,具体的思想可以看我写的注释。

  1.  
    #include <stdio.h>
  2.  
    #include <stdlib.h>
  3.  
    #include <assert.h>
  4.  
    #include <set>
  5.  
    #pragma warning(disable:4996)
  6.  
    #define size_int sizeof(int)
  7.  
    typedef unsigned int uint;
  8.  
     
  9.  
    using namespace std;
  10.  
     
  11.  
    const static int pageSize = 4096;
  12.  
    //const static int t = (pageSize - 96)/ size_int / 4;
  13.  
    const static int t = 3;
  14.  
    int mtop;
  15.  
    const static int bign = 105;
  16.  
    int mstack[bign];
  17.  
    const static int maxd = 2 * t - 1;
  18.  
    const static int mind = t - 1;
  19.  
    struct List_entry
  20.  
    {
  21.  
    List_entry *prev, *nxt;
  22.  
    }*mhead;
  23.  
    static int inMemory = 0;
  24.  
    struct BNode
  25.  
    {
  26.  
    unsigned n1 : 10;
  27.  
    unsigned isLeaf : 1;
  28.  
    unsigned isDirty : 1;
  29.  
     
  30.  
    //unsigned int n1;
  31.  
    //bool isLeaf;
  32.  
    BNode* fa;
  33.  
    List_entry leaflist;
  34.  
    BNode* childp[2 * t];//which contains the pointer of child node
  35.  
    //represent the block num of child(point to data block if leaf)
  36.  
    int ckey[2 * t];//represent the key for parition child(ckey[i] == the least key of corresponding child i)
  37.  
    BNode() :fa(NULL), isLeaf(true), n1(0), isDirty(0)
  38.  
    {
  39.  
     
  40.  
    };
  41.  
    ~BNode()
  42.  
    {
  43.  
    if (isDirty)
  44.  
    {
  45.  
    //printf("page write block num %u...\n", this);//WriteBlock func called,copy content from memory to hard disk
  46.  
    isDirty = 0;
  47.  
    }
  48.  
    //delete leaflist;
  49.  
    };
  50.  
    };
  51.  
    BNode *Troot = NULL, *NodeTemplate;
  52.  
     
  53.  
    bool msplit(BNode* bnode);
  54.  
     
  55.  
    inline BNode* to_struct(List_entry* leafEntry)
  56.  
    {
  57.  
    if (Troot == NULL)
  58.  
    Troot = new BNode();
  59.  
    return (BNode*)((char*)leafEntry - ((char*)(&(Troot->leaflist)) - (char*)Troot));
  60.  
    }
  61.  
     
  62.  
    inline void listAdd(List_entry* prevn, List_entry* nextn, List_entry* dataentry)
  63.  
    {
  64.  
    dataentry->prev = prevn;
  65.  
    dataentry->nxt = nextn;
  66.  
    nextn->prev = dataentry;
  67.  
    prevn->nxt = dataentry;
  68.  
    }
  69.  
     
  70.  
    inline void listDel(List_entry* dataentry)
  71.  
    {
  72.  
    dataentry->prev->nxt = dataentry->nxt;
  73.  
    dataentry->nxt->prev = dataentry->prev;
  74.  
    }
  75.  
     
  76.  
    inline void list_AddAfter(List_entry* listentry, List_entry* dataentry)
  77.  
    {
  78.  
    List_entry* tnxt = listentry->nxt;
  79.  
    listAdd(listentry, tnxt, dataentry);
  80.  
    }
  81.  
     
  82.  
    inline BNode* prevB(BNode* u)
  83.  
    {
  84.  
    assert(u->isLeaf);
  85.  
    if (u->leaflist.prev != mhead)
  86.  
    {
  87.  
    return to_struct(u->leaflist.prev);
  88.  
    }
  89.  
    else
  90.  
    {
  91.  
    return NULL;
  92.  
    }
  93.  
    }
  94.  
     
  95.  
    inline BNode* nextB(BNode* u)
  96.  
    {
  97.  
    assert(u->isLeaf);
  98.  
    if (u->leaflist.nxt != mhead)
  99.  
    {
  100.  
    return to_struct(u->leaflist.nxt);
  101.  
    }
  102.  
    else
  103.  
    {
  104.  
    return NULL;
  105.  
    }
  106.  
    }
  107.  
     
  108.  
    struct Block
  109.  
    {
  110.  
    char bdata[pageSize];
  111.  
    };
  112.  
     
  113.  
    BNode* getBlock()
  114.  
    {
  115.  
    return (BNode*)(rand() % 65536);//can be replaced by an unique num
  116.  
    }
  117.  
    //Block data if read into memory.
  118.  
     
  119.  
    //BTree height increasing or decreasing only when the root node split or merge
  120.  
    void ReadBlock(BNode *blocknum = 0)//using virtual addr of BNode to represent the corresponding block.
  121.  
    {
  122.  
    //if blocknum not in memory
  123.  
    //in best case,triggered by int 14 except first time read(int 80)
  124.  
    //printf("page read %u...\n", blocknum);
  125.  
    inMemory ;
  126.  
    }
  127.  
     
  128.  
    void WriteBlock(BNode *blocknum = 0)
  129.  
    {
  130.  
    //if blocknum is dirty
  131.  
    if (blocknum != NULL && blocknum->isDirty == 1)
  132.  
    {
  133.  
    //printf("page write %d...\n", blocknum);
  134.  
    //inMemory--;
  135.  
    blocknum->isDirty = 0;
  136.  
    }
  137.  
    }
  138.  
     
  139.  
     
  140.  
    void init()
  141.  
    {
  142.  
    srand(11);
  143.  
    Troot = new BNode();
  144.  
    /*
  145.  
    Troot->isLeaf = true;
  146.  
    Troot->fa = NULL;
  147.  
    Troot->n1 = 0;
  148.  
    Troot->leaflist = new List_entry();*/
  149.  
    mhead = new List_entry();
  150.  
    mhead->prev = mhead->nxt = mhead;
  151.  
    list_AddAfter(mhead, &(Troot->leaflist));
  152.  
    }
  153.  
     
  154.  
    inline bool mtransfer(BNode* snode, BNode* dnode, int childno, int mflag) //matching with left rotate and right rotate in binary tree
  155.  
    {
  156.  
    if (!mflag)//mflag == 0,represent transferring to prev node
  157.  
    {
  158.  
    uint nd = dnode->n1;
  159.  
    dnode->childp[nd] = snode->childp[0];
  160.  
    dnode->ckey[nd] = snode->ckey[0];
  161.  
    if (!dnode->isLeaf)
  162.  
    dnode->childp[nd]->fa = dnode;
  163.  
    dnode->n1 ;
  164.  
    snode->n1--;
  165.  
    for (uint i = 0; i < snode->n1; i )
  166.  
    {
  167.  
    snode->childp[i] = snode->childp[i 1];
  168.  
    snode->ckey[i] = snode->ckey[i 1];
  169.  
    }
  170.  
    BNode* tfa = snode->fa;
  171.  
    ReadBlock(tfa);
  172.  
    tfa->ckey[childno] = snode->ckey[0];
  173.  
    tfa->isDirty = 1;
  174.  
    }
  175.  
    else //mflag == 1,represent transferring to next node
  176.  
    {
  177.  
    snode->n1--;
  178.  
    dnode->n1 ;
  179.  
    for (uint i = dnode->n1 - 1; i > 0; i--)
  180.  
    {
  181.  
    dnode->ckey[i] = dnode->ckey[i - 1];
  182.  
    dnode->childp[i] = dnode->childp[i - 1];
  183.  
    }
  184.  
    int sn1 = snode->n1;
  185.  
    BNode* tfa = snode->fa;
  186.  
    ReadBlock(tfa);
  187.  
    tfa->ckey[childno 1] = dnode->ckey[0] = snode->ckey[sn1];
  188.  
    dnode->childp[0] = snode->childp[sn1];
  189.  
    if (!dnode->isLeaf)
  190.  
    dnode->childp[0]->fa = dnode;
  191.  
    tfa->isDirty = 1;
  192.  
    }
  193.  
    snode->isDirty = 1;
  194.  
    dnode->isDirty = 1;
  195.  
    // WriteBlock(snode);
  196.  
    // WriteBlock(dnode);
  197.  
    return false;
  198.  
    }
  199.  
     
  200.  
    inline bool msplit(BNode *bnode)
  201.  
    {
  202.  
    BNode* nxtbnode = new BNode();
  203.  
    bnode->n1 /= 2;
  204.  
    int bn1 = bnode->n1;
  205.  
    nxtbnode->n1 = bn1;
  206.  
    nxtbnode->isLeaf = bnode->isLeaf;//
  207.  
    for (int i = 0; i < bn1; i )
  208.  
    {
  209.  
    nxtbnode->ckey[i] = bnode->ckey[i bn1];
  210.  
    nxtbnode->childp[i] = bnode->childp[i bn1];
  211.  
    if (!nxtbnode->isLeaf)
  212.  
    nxtbnode->childp[i]->fa = nxtbnode;
  213.  
    }
  214.  
     
  215.  
    if(bnode->isLeaf == 1)
  216.  
    list_AddAfter(&bnode->leaflist, &nxtbnode->leaflist);
  217.  
    int childno = 0;
  218.  
    if (bnode->fa == NULL)
  219.  
    {
  220.  
    Troot = new BNode();
  221.  
    bnode->fa = Troot;
  222.  
    Troot->ckey[0] = bnode->ckey[0];
  223.  
    Troot->childp[0] = bnode;
  224.  
    Troot->n1 ;
  225.  
    Troot->isLeaf = false;
  226.  
    }
  227.  
    else
  228.  
    {
  229.  
    childno = mstack[mtop - 1];
  230.  
    }
  231.  
    BNode *tfa = nxtbnode->fa = bnode->fa;
  232.  
    ReadBlock(tfa);
  233.  
    tfa->n1 ;
  234.  
    for(uint i = tfa->n1 - 1; i > childno 1 ; i--)
  235.  
    {
  236.  
    tfa->ckey[i] = tfa->ckey[i - 1];
  237.  
    tfa->childp[i] = tfa->childp[i - 1];
  238.  
    }
  239.  
    tfa->ckey[childno 1] = nxtbnode->ckey[0];
  240.  
    tfa->childp[childno 1] = nxtbnode;
  241.  
    //nxtbnode->fa = tfa;
  242.  
    return true;
  243.  
    }
  244.  
     
  245.  
     
  246.  
     
  247.  
    inline void mmerge(BNode* u, BNode* v)
  248.  
    {
  249.  
    int tun = u->n1;
  250.  
    u->n1 = v->n1;
  251.  
    for (int i = tun; i < u->n1; i )
  252.  
    {
  253.  
    u->childp[i] = v->childp[i - tun];
  254.  
    u->ckey[i] = v->ckey[i - tun];
  255.  
    if (!u->isLeaf)
  256.  
    u->childp[i]->fa = u;
  257.  
    }
  258.  
    u->isDirty = 1;
  259.  
    if (v->isLeaf)
  260.  
    {
  261.  
    listDel(&v->leaflist);
  262.  
    }
  263.  
    delete v;
  264.  
    //free space Bnode v occupied on disk
  265.  
    inMemory--;
  266.  
     
  267.  
    BNode* ufa = u->fa;
  268.  
    ReadBlock(ufa);
  269.  
    int chno = mstack[mtop - 1];
  270.  
    ufa->n1--;
  271.  
    for (int i = chno 1; i < ufa->n1; i )
  272.  
    {
  273.  
    ufa->childp[i] = ufa->childp[i 1];
  274.  
    ufa->ckey[i] = ufa->ckey[i 1];
  275.  
    }
  276.  
    //ufa->ckey[chno] = u->ckey[0];
  277.  
    ufa->isDirty = 1;
  278.  
    return;
  279.  
    }
  280.  
     
  281.  
    bool DealWithNode(BNode* &u, bool isinsert = true)
  282.  
    {
  283.  
    int chno = mstack[mtop - 1];
  284.  
    BNode* ufa = u->fa;
  285.  
    if (ufa != NULL)
  286.  
    {
  287.  
    ReadBlock(ufa);
  288.  
    if(!isinsert)
  289.  
    ufa->ckey[chno] = u->ckey[0];
  290.  
    }
  291.  
    bool mflag = false;
  292.  
    if (isinsert)
  293.  
    {
  294.  
    if (ufa == NULL)
  295.  
    {
  296.  
    msplit(u);
  297.  
    return true;
  298.  
    }
  299.  
    int un = ufa->n1;
  300.  
    if (chno > 0)
  301.  
    {
  302.  
    BNode* v = ufa->childp[chno - 1];
  303.  
    ReadBlock(v);
  304.  
    if (v->n1 < maxd)
  305.  
    {
  306.  
    mtransfer(u, v, chno, 0);
  307.  
    return true;
  308.  
    }
  309.  
    }
  310.  
    if (chno < un - 1)
  311.  
    {
  312.  
    BNode* v = ufa->childp[chno 1];
  313.  
    ReadBlock(v);
  314.  
    if (v->n1 < maxd)
  315.  
    {
  316.  
    mtransfer(u, v, chno, 1);
  317.  
    return true;
  318.  
    }
  319.  
    }
  320.  
    msplit(u);
  321.  
    return false;
  322.  
    }
  323.  
    else
  324.  
    {
  325.  
    int un = ufa->n1;
  326.  
    BNode* v = NULL;
  327.  
    int tflag = 0;
  328.  
    if (chno > 0)
  329.  
    {
  330.  
    v = ufa->childp[chno - 1];
  331.  
    ReadBlock(v);
  332.  
    if (v->n1 > mind)
  333.  
    {
  334.  
    mtransfer(v, u, chno - 1, 1);
  335.  
    return true;
  336.  
    }
  337.  
    }
  338.  
    if (chno < un - 1)
  339.  
    {
  340.  
    v = ufa->childp[chno 1];
  341.  
    tflag = 1;
  342.  
    ReadBlock(v);
  343.  
    if (v->n1 > mind)
  344.  
    {
  345.  
    mtransfer(v, u, chno 1, 0);
  346.  
    return true;
  347.  
    }
  348.  
    }
  349.  
     
  350.  
    if (tflag == 0)
  351.  
    {
  352.  
    BNode* tmp = u;
  353.  
    u = v;
  354.  
    v = tmp;
  355.  
    mstack[mtop - 1]--;
  356.  
    //ufa->ckey[mstack[mtop - 1]] = u->ckey[0];
  357.  
    }
  358.  
     
  359.  
    mmerge(u, v);
  360.  
     
  361.  
    if (ufa->n1 == 1 && ufa == Troot)
  362.  
    {
  363.  
    delete Troot;
  364.  
    Troot = u;
  365.  
    }
  366.  
    if (u == Troot)
  367.  
    return true;
  368.  
     
  369.  
    return false;
  370.  
    }
  371.  
    }
  372.  
     
  373.  
    void BInsert(int mkey)
  374.  
    {
  375.  
    BNode* u = Troot;
  376.  
     
  377.  
    mtop = 1;
  378.  
    while (true)
  379.  
    {
  380.  
    ReadBlock(u);
  381.  
    if (u->isLeaf)
  382.  
    {
  383.  
    uint i = 0;
  384.  
    for (i = 0; i < u->n1; i )
  385.  
    {
  386.  
    assert(mkey != u->ckey[i]);
  387.  
    if (u->ckey[i] > mkey)
  388.  
    {
  389.  
    break;
  390.  
    }
  391.  
    }
  392.  
    u->n1 ;
  393.  
    for (uint j = u->n1 - 1; j > i; j--)
  394.  
    {
  395.  
    u->childp[j] = u->childp[j - 1];
  396.  
    u->ckey[j] = u->ckey[j - 1];
  397.  
    }
  398.  
    u->childp[i] = getBlock();
  399.  
    u->ckey[i] = mkey;
  400.  
    u->isDirty = 1;
  401.  
    /*
  402.  
    if (u->n1 > maxd)
  403.  
    {
  404.  
    bool flag = false;
  405.  
    if (!flag)
  406.  
    {
  407.  
    BNode *tBNode = prevB(u);
  408.  
    if (tBNode != NULL && tBNode->fa == u->fa && tBNode->n1 < maxd)
  409.  
    {
  410.  
    ReadBlock(u->fa);
  411.  
    mtransfer(u, tBNode, 0);
  412.  
    flag = true;
  413.  
    }
  414.  
    }
  415.  
     
  416.  
    if (!flag)
  417.  
    {
  418.  
    BNode* tBNode = nextB(u);
  419.  
    if (tBNode != NULL && tBNode->fa == u->fa && tBNode->n1 < maxd)
  420.  
    {
  421.  
    ReadBlock(u->fa);
  422.  
    mtransfer(u, tBNode, 1);
  423.  
    flag = true;
  424.  
    }
  425.  
    }
  426.  
     
  427.  
    if (!flag)
  428.  
    {
  429.  
    //ReadBlock(u->fa);
  430.  
    msplit(u);
  431.  
    //WriteBlock(u->fa);
  432.  
    }
  433.  
     
  434.  
    }
  435.  
    WriteBlock(u);*/
  436.  
    break;
  437.  
    }
  438.  
    else
  439.  
    {
  440.  
    uint i = 0;
  441.  
    for (i = 0; i < u->n1; i )
  442.  
    {
  443.  
    assert(mkey != u->ckey[i]);
  444.  
    if (u->ckey[i] > mkey)
  445.  
    {
  446.  
    if (i > 0)
  447.  
    i--;
  448.  
    break;
  449.  
    }
  450.  
    }
  451.  
    if (i == u->n1 && i > 0)
  452.  
    i--;
  453.  
    if (i == 0)
  454.  
    {
  455.  
    if (mkey < u->ckey[i])
  456.  
    {
  457.  
    u->ckey[i] = mkey;
  458.  
    u->isDirty = 1;
  459.  
    //WriteBlock(u);
  460.  
    }
  461.  
    }
  462.  
    mstack[mtop ] = i;
  463.  
    u = u->childp[i];
  464.  
    }
  465.  
    }
  466.  
    //u = u->fa;
  467.  
     
  468.  
    while(u != NULL)
  469.  
    {
  470.  
    ReadBlock(u);
  471.  
     
  472.  
    if (u->n1 <= maxd)
  473.  
    {
  474.  
    // WriteBlock(u);
  475.  
    break;
  476.  
    }
  477.  
    bool flag = false;
  478.  
    flag = DealWithNode(u, true);
  479.  
     
  480.  
    if (!flag)
  481.  
    u = u->fa;
  482.  
    else
  483.  
    break;
  484.  
    mtop--;
  485.  
    }
  486.  
     
  487.  
    }
  488.  
    inline void fixchno(BNode *u)
  489.  
    {
  490.  
    while (u != Troot)
  491.  
    {
  492.  
    int chno = mstack[mtop - 1];
  493.  
    BNode *ufa = u->fa;
  494.  
    ReadBlock(ufa);
  495.  
    assert(ufa->childp[chno] == u);
  496.  
    if (ufa->ckey[chno] == u->ckey[0])
  497.  
    {
  498.  
    break;
  499.  
    }
  500.  
    else
  501.  
    {
  502.  
    ufa->ckey[chno] = u->ckey[0];
  503.  
    ufa->isDirty = 1;
  504.  
    //WriteBlock(ufa);
  505.  
    }
  506.  
    u = ufa;
  507.  
    mtop--;
  508.  
    }
  509.  
    }
  510.  
     
  511.  
    void BDelete(int mkey)
  512.  
    {
  513.  
    BNode* u = Troot;
  514.  
     
  515.  
    mtop = 1;
  516.  
    while (true)
  517.  
    {
  518.  
    ReadBlock(u);
  519.  
    if (u->isLeaf)
  520.  
    {
  521.  
    uint i = 0;
  522.  
    for (i = 0; i < u->n1; i )
  523.  
    {
  524.  
    if (u->ckey[i] == mkey)
  525.  
    {
  526.  
    break;
  527.  
    }
  528.  
    }
  529.  
    u->n1--;
  530.  
    for (uint j = i; j < u->n1; j )
  531.  
    {
  532.  
    u->childp[j] = u->childp[j 1];
  533.  
    u->ckey[j] = u->ckey[j 1];
  534.  
    }
  535.  
    u->isDirty = 1;
  536.  
    break;
  537.  
    }
  538.  
    else
  539.  
    {
  540.  
    uint i = 0;
  541.  
    for (i = 0; i < u->n1; i )
  542.  
    {
  543.  
    if (u->ckey[i] > mkey)
  544.  
    break;
  545.  
    }
  546.  
    assert(i > 0);
  547.  
    i--;
  548.  
    mstack[mtop ] = i;
  549.  
    u = u->childp[i];
  550.  
     
  551.  
    }
  552.  
    }
  553.  
    while (u != Troot)
  554.  
    {
  555.  
    ReadBlock(u);
  556.  
     
  557.  
    if (u->n1 >= mind)
  558.  
    {
  559.  
    WriteBlock(u);
  560.  
    fixchno(u);
  561.  
    break;
  562.  
    }
  563.  
    bool flag = false;
  564.  
    //BNode* oldu = u;
  565.  
    flag = DealWithNode(u, false);
  566.  
    //assert(oldu == u);
  567.  
     
  568.  
    u = u->fa;
  569.  
    mtop--;
  570.  
    if (flag)
  571.  
    {
  572.  
    fixchno(u);
  573.  
    break;
  574.  
    }
  575.  
    }
  576.  
    }
  577.  
    const int bigm = 1000000;
  578.  
    //int mark[bign];
  579.  
    set<int> used_set;
  580.  
    inline int getrand()
  581.  
    {
  582.  
    return (rand() * 32767ll rand()) % bigm;
  583.  
    }
  584.  
    void Btest()
  585.  
    {
  586.  
    used_set.clear();
  587.  
    int nown = 0;
  588.  
    for (int i = 0; i < bigm; i )
  589.  
    {
  590.  
    if (nown < 5000)
  591.  
    {
  592.  
    int x = getrand();
  593.  
    int cnt = 0;
  594.  
    for (int j = x; j != x - 1; j = (j 1) % bigm)
  595.  
    {
  596.  
    cnt ;
  597.  
     
  598.  
    if (used_set.count(j) == 0)
  599.  
    {
  600.  
    used_set.insert(j);
  601.  
    nown ;
  602.  
    BInsert(j);
  603.  
    break;
  604.  
    }
  605.  
    else if(cnt > 10)
  606.  
    {
  607.  
    BDelete(j);
  608.  
    used_set.erase(j);
  609.  
    nown--;
  610.  
    }
  611.  
    }
  612.  
    }
  613.  
    else
  614.  
    {
  615.  
    int x = getrand();
  616.  
    if (x % 2 == 0)
  617.  
    {
  618.  
    int cnt = 0;
  619.  
    for (int j = x; j != x - 1; j = (j 1) % bigm)
  620.  
    {
  621.  
    cnt ;
  622.  
    if (used_set.count(j) == 0)
  623.  
    {
  624.  
    used_set.insert(j);
  625.  
    BInsert(j);
  626.  
    nown ;
  627.  
    break;
  628.  
    }
  629.  
    else if (cnt > 10)
  630.  
    {
  631.  
    BDelete(j);
  632.  
    used_set.erase(j);
  633.  
    nown--;
  634.  
    break;
  635.  
    }
  636.  
    }
  637.  
    }
  638.  
    else
  639.  
    {
  640.  
    auto it = used_set.lower_bound(x);
  641.  
    if (it != used_set.end())
  642.  
    {
  643.  
    x = *it;
  644.  
    }
  645.  
    else
  646.  
    {
  647.  
    x = *used_set.begin();
  648.  
    }
  649.  
    BDelete(x);
  650.  
    used_set.erase(x);
  651.  
    nown--;
  652.  
    }
  653.  
    }
  654.  
    if (i > 0 && i % 100 == 0)
  655.  
    {
  656.  
    int lastval = -1;
  657.  
    int cnt = 0;
  658.  
    for (List_entry* j = mhead->nxt; j != mhead; j = j->nxt)
  659.  
    {
  660.  
    BNode* tb = to_struct(j);
  661.  
    assert(tb->ckey[0] > lastval);
  662.  
    lastval = tb->ckey[tb->n1 - 1];
  663.  
    if (rand() % 30 == 0)
  664.  
    {
  665.  
    for (int k = 1; k < tb->n1; k )
  666.  
    {
  667.  
    assert(tb->ckey[k] > tb->ckey[k - 1]);
  668.  
    }
  669.  
    }
  670.  
    cnt = tb->n1;
  671.  
    }
  672.  
    assert(cnt == nown);
  673.  
    }
  674.  
    }
  675.  
    }
  676.  
     
  677.  
    int main()
  678.  
    {
  679.  
    //int blocknum = 102;
  680.  
    //printf("%d\n", sizeof(dxfile));
  681.  
    init();
  682.  
    Btest();
  683.  
    //printf("%d\n", sizeof(BNode));
  684.  
    //printf("%d\n", Troot->isLeaf);
  685.  
    }
  686.  
    //flush all dirty BNode to disk when being exchanged out of memory or when program exited(WriteBlock called)
学新通

    这份代码刚开始的时候是随便写的,不过后面写着写着发现挺有意思的就比较认真了(还写了测试代码),写B树主要是因为只有它没有写过。学完uCore以后我觉得当年要是读个计算机博士什么的早就毕业了。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgggcib
系列文章
更多 icon
同类精品
更多 icon
继续加载