dbm数据库源代码分析(6):bucket.c

   现在解剖bucket.c的源代码。文件中包含了操作散列桶的_gdbm_new_bucket函数、_gdbm_get_bucket函数、_gdbm_split_bucket函数、_gdbm_write_bucket函数。
   (1)void _gdbm_new_bucket(dbf, bucket, bits)函数。初始化一个新的hash_bucket,会设置其av_count和count为0,bucket_bits为bits,设置桶中的所有dbf->header->bucket_elems个桶元素的hash_value为-1。

   (2)void _gdbm_get_bucket(dbf,index):根据给出的目录索引,获取此目录项指示的散列桶。操作流程:
      1)设置dbf的当前桶目录索引bucket_dir,根据目录项获得我们需要的散列桶的偏移地址;
      2)如果dbf中初始的桶偏移地址指示的不是我们要找的桶,则扫描每一个缓存项,找到我们需要的桶,并设置dbf中的当前桶指针和当前缓存项指针,返回;
      3)如果不在缓存中,则从磁盘上读取,把它放到最近最久未使用的缓存项处,设置好dbf中的当前桶指针和当前缓存项指针后,返回。

   (3)void _gdbm_split_bucket(dbf,next_insert)函数。对dbf->bucket指向的当前桶(即旧桶)进行分裂,分裂成2个新桶,相应的散列目录表的长度也会增一倍。旧桶中所有的项会复制到其中一个新桶中去。新桶会插入到磁盘文件的新位置处,而原来的旧桶空间成为一个新的可用块,描述这个可用块的avail_elem会被插入到新桶的avail_elem元素列表中。next_insert是一个目录索引,其目录项中指示的是要插入的新桶的偏移地址。操作流程:
     1)在桶缓存数组中找到旧桶所在的缓存项,在它的下一位置初始化两个新桶;
     2)为新桶0和新桶1分配磁盘空间,返回它在磁盘上的偏移地址,并设置到相应缓存项的ca_adr域中去;
     3)让散列目录表长度增一倍,为新目录表分配磁盘空间以获得其偏移地址,然后复制目录表项,把增长的部分复制为原来部分的值;
     4)更新文件头中的域,如dir指针和dir_size等,使之成为新目录表的相应值;
     5)更新dbf中的域,包括当前目录索引bucket_dir,指向新目录表指针dir等,然后释放内存中的旧目录表空间;
     6)把旧桶中的所有桶元素复制到两个新桶中;
     7)为新桶1对应的可用块分配磁盘空间, 而把旧桶对应的每个可用块元素复制到新桶0中,注意如果新桶0对应的可用块数达到最大,则把其可用块插入到新桶1的可用块列表中。
     8)由于两个新桶有新的偏移地址,因此要更新新目录表中目录项;
     9)设置dbf中的一些改变标志;
     10)保存旧桶的地址和大小,以作为一个新的可用块;
     11)根据next_insert目录项中指示的是那个新桶地址,让dbf->bucket指向这个新桶,让当前缓存项指针指向这个新桶所在的缓存项;
     12)最后释放磁盘上所有旧目录表的空间。

   (4)void _gdbm_write_bucket(dbf,ca_entry)函数。把桶缓存中的桶写入到磁盘上,是做桶写入的唯一函数。ca_entry指向了包含要写入桶的缓存项。主要操作有:用lseek定位到要写入的位置、用write做写入操作、写入完成后重置缓存项中的一些标志。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值