官方文档针对不同类型的存储一股脑地介绍了一大堆选项,至于哪个选项适用于哪种类型的存储并不清楚(可能是我没看清楚),下面只说一下影响memory db的参数选项:
参考源码:
 
bool  tcadbopen(TCADB *adb,  const   char  *name){     …     } else   if (!tcstricmp(path,  "*" )){          adb->mdb = bnum > 0 ? tcmdbnew2(bnum) : tcmdbnew();         adb->capnum = capnum;         adb->capsiz = capsiz;         adb->capcnt = 0;         adb->omode = ADBOMDB;     } else   if (!tcstricmp(path,  "+" )){          …     } }  
 
		
		
			
			
				
					
				
					
				 
						/* Open an abstract database. */   bool   tcadbopen ( TCADB * adb ,   const   char   *name ) {           . . .           }   else   if ( ! tcstricmp ( path ,   " *" ) ) {                   adb -> mdb   =  bnum   >   0   ?   tcmdbnew2 ( bnum )   :   tcmdbnew ( ) ;                   adb -> capnum   =  capnum ;                   adb -> capsiz   =  capsiz ;                   adb -> capcnt   =  0 ;                   adb -> omode   =  ADBOMDB ;           }   else   if ( ! tcstricmp ( path ,   " +" ) ) {                   . . .           }   } 
 
				
			 
		 
 
 
说明: bnum : 总的bucket的数量; 注意map有8个(固定的);8个map中共有bnum个bucketcapnum : 最大允许的记录数; capsize : 最大允许的key-value使用的存储的大小;
下面解释一下capnum与capsize的使用逻辑:
 
bool  tcadbput(TCADB *adb,  const   void  *kbuf,  int  ksiz,  const   void  *vbuf,  int  vsiz){     assert(adb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0);     bool  err =  false ;      char  numbuf[TCNUMBUFSIZ];      ADBSKEL *skel;     switch (adb->omode){          case  ADBOMDB:          if (adb->capnum > 0 || adb->capsiz > 0){              tcmdbput3(adb->mdb, kbuf, ksiz, vbuf, vsiz);             adb->capcnt++;             if ((adb->capcnt & 0xff) == 0){                   if (adb->capnum > 0 && tcmdbrnum(adb->mdb) > adb->capnum + 0x100)                      tcmdbcutfront(adb->mdb, 0x100);                     if (adb->capsiz > 0 && tcmdbmsiz(adb->mdb) > adb->capsiz)                          tcmdbcutfront(adb->mdb, 0x200);             }               } else  {              tcmdbput(adb->mdb, kbuf, ksiz, vbuf, vsiz);         }               break ;           case  ADBONDB:          …         } }  
 
		
		
			
			
				
					
				
					
				 
						/* Store a record into an abstract database object. */   bool   tcadbput ( TCADB * adb ,   const   void   *kbuf ,   int   ksiz ,   const   void   *vbuf ,   int   vsiz ) {           assert ( adb   & &   kbuf   & &   ksiz   > =  0   & &   vbuf   & &   vsiz   > =  0 ) ;           bool   err   =  false ;           char   numbuf [ TCNUMBUFSIZ ] ;           ADBSKEL * skel ;           switch ( adb -> omode ) {                   case   ADBOMDB :                   if ( adb -> capnum   >   0   | |   adb -> capsiz   >   0 ) {                           tcmdbput3 ( adb -> mdb ,   kbuf ,   ksiz ,   vbuf ,   vsiz ) ;                           adb -> capcnt ++;                           if ( ( adb -> capcnt   &   0xff )   ==  0 ) {   // 256的倍数时才检查,否则会比较影响性能                 if(adb->capnum > 0 && tcmdbrnum(adb->mdb) > adb->capnum + 0x100)                     tcmdbcutfront(adb->mdb, 0x100);                     if(adb->capsiz > 0 && tcmdbmsiz(adb->mdb) > adb->capsiz)                         tcmdbcutfront(adb->mdb, 0x200);             }               } else {             tcmdbput(adb->mdb, kbuf, ksiz, vbuf, vsiz);         }               break;          case ADBONDB:         ...         } } 
 
				
			 
		 
 
 
说明:
或许你测试发现删除的并非恰好256条记录,原因是这样的,先看源码:
 
void  tcmdbcutfront(TCMDB *mdb,  int  num){     assert(mdb && num >= 0);     num = num / TCMDBMNUM + 1;     for ( int  i = 0; i < TCMDBMNUM; i++){          if (pthread_rwlock_wrlock((pthread_rwlock_t *)mdb->mmtxs + i) == 0){              tcmapcutfront(mdb->maps, num);              pthread_rwlock_unlock((pthread_rwlock_t *)mdb->mmtxs + i);         }       } }  
 
		
		
			
			
				
					
				
					
				 
						void   tcmdbcutfront ( TCMDB * mdb ,   int   num ) {           assert ( mdb   & &   num   > =  0 ) ;           num   =  num   /  TCMDBMNUM   +  1 ;           for ( int   i   =  0 ;   i   <   TCMDBMNUM ;   i ++) {                   if ( pthread_rwlock_wrlock ( ( pthread_rwlock_t * ) mdb -> mmtxs   +  i )   ==  0 ) {                           tcmapcutfront ( mdb -> maps < i > ,   num ) ;                           pthread_rwlock_unlock ( ( pthread_rwlock_t * ) mdb -> mmtxs   +  i ) ;                   }               }   } 
 
				
			 
		 
 
 
说明:
关于从map中删除记录tcmapcutfront的说明:
 
void  tcmapcutfront(TCMAP *map,  int  num){     assert(map && num >= 0);     tcmapiterinit(map);     while (num– > 0){          int  ksiz;          const   char  *kbuf = tcmapiternext(map, &ksiz);          if (!kbuf)  break ;          tcmapout(map, kbuf, ksiz);     } }  
 
		
		
			
			
				
					
				
					
				 
						/* Remove front records of a map object. */   void   tcmapcutfront ( TCMAP * map ,   int   num ) {           assert ( map   & &   num   > =  0 ) ;           tcmapiterinit ( map ) ;           while ( num --  >   0 ) {                   int   ksiz ;                   const   char   *kbuf   =  tcmapiternext ( map ,   & ksiz ) ;                   if ( ! kbuf )   break ;                   tcmapout ( map ,   kbuf ,   ksiz ) ;           }   } 
 
				
			 
		 
 
 
说明:
在tc的memory db的实现中,获取数据时,完全可以把获取的数据调整到链表的尾部(在非全内存的btree的map中是这么实现的,见tcutil.c:tcmapget3()),这样剔除的时候就不至于把热数据给删除掉了
————————-