这是tokyo cabinet的一个BUG么

这是tokyo cabinet的一个BUG么

最近在研读tokyo cabinet的代码,但是发现一个问题。
目前在跟进的是使用hash table实现的数据库文件,在项目的examples目录下面有一些作者写的demo文件演示如何使用的。我使用这里的tchdbex.c文件跟踪代码的运行情况,不过在里面加入了下面两行代码:
/*  store records  */
  
if ( ! tchdbput2(hdb,  " foo " " hop " ||
     
! tchdbput2(hdb,  " bar " " step " ||
     
! tchdbput2(hdb,  " baz " " jump " )){
    ecode 
=  tchdbecode(hdb);
    fprintf(stderr, 
" put error: %s\n " , tchdberrmsg(ecode));
  }

+   tchdbout2(hdb,  " foo " );
+   tchdbput2(hdb,  " foo " " hop " );

(代码前面加上+号的是我加上的两行代码)

可以看到,我在加入了记录(“foo”, “hop”)之后,对它进行了删除操作,在这之后紧跟着再次插入相同的记录。
tokyo cabinet的hash-table实现中,删除一条记录时会将塌存放到一个free pool类型的数组中,这里面保存了这条删除记录的大小和在文件中的偏移量。

问题在于,在加入记录时,记录的大小是32byte,删除记录时理所当然的也是删除一条大小为32byte的记录了,但是呢,紧跟着再次插入同样的记录时,代码中(tchdb.c):
3417       rec.rsiz  =  HDBMAXHSIZ  +  ksiz  +  vsiz;
3418       if ( ! tchdbfbpsearch(hdb,  & re
3417行算出这条新插入的记录应该是38byte,于是走入下面的函数tchdbfbpsearch 查找能满足这个大小的freepool,之前返回的freepool是32,于是这个查找失败了,不得不重新分配空间来存放这个新的记录,而不是复用已经返回的空间---尽管前后两次插入的数据大小是一样的。
其实,在上面的代码中,第二次插入记录的时候,查找可用的freepool失败之后继续往下走,最后真正插入到文件中的数据记录大小还是32的。

我给作者发去邮件,咨询这个问题,作者的回答大意是说我描述的这个现象确实存在,不过是有一定的考虑在里面的,后期会进行一些改进。我没有完全的把这部分代码阅读完毕,所以也就不好多说什么了,下面附上邮件内容,做一个记录,也为可能会发现这个问题的朋友提个醒吧。

我使用的版本是1.4.19。
chuang
 发送至 hirarin
    
显示详细信息 
15 : 10  ( 6  小时前)
    
Hi, hirarin,recently, I 
try  to read and trace the tokyocabinet source.
when I use the examples
/ tchdbex.c to trace hash - table, I find a problem.

In the file tchdbex.c, I add two lines:
  
/*  store records  */
  
if ( ! tchdbput2(hdb,  " foo " " hop " ||
     
! tchdbput2(hdb,  " bar " " step " ||
     
! tchdbput2(hdb,  " baz " " jump " )){
    ecode 
=  tchdbecode(hdb);
    fprintf(stderr, 
" put error: %s\n " , tchdberrmsg(ecode));
  }

+   tchdbout2(hdb,  " foo " );
+   tchdbput2(hdb,  " foo " " hop " );

so, you can see that after insert key 
" foo " , " bar "  and  " baz " , I  try  to remove the record with the key  " foo " , and then insert record ( " foo " , " hop " ) again.

But, when i use gdb to trace the program, i find that, when i first insert the record (
" foo " " hop " ), the record size  is   32 .
and then, when i remove the record (
" foo " " hop " ), the record size  is   32 , it  is  ok, then a free block with size  32   is  inserted into the free block arrays.
But, when I insert record (
" foo " " hop " ) once again,  in  the file tchdb.c: 3417 :
3417       rec.rsiz  =  HDBMAXHSIZ  +  ksiz  +  vsiz;
then the record size 
is   38
and then the next line it tries to find a free block fix to 
this  size, but there  is  only free block with size  32 , so it  is  falied to find a free block.

I mean that, 
if  I remove the record ( " foo " " hop " ) and then  try  to insert it again, seems that it should use the free block with size  32 .Otherwise, there will be missing retrieval of the free block.

So, 
is  it a bug ??

BTW: the version 
is   1.4 . 19
 
|
Mikio Hirabayashi
 发送至 我
    
显示详细信息 
16 : 37  ( 5  小时前)
    
Hi,

Thanks 
for  the report.
It
' s not a bug but on purpose.
The header size  is  not calcurated at the line, I estimate it the
maximum size 
in  theory.
However, I hit on an idia thanks to you.  I
' ll change the logic to
reduce the file size.

Regards.



你可能感兴趣的:(这是tokyo cabinet的一个BUG么)