stoneage8.5/石器时代服务器端最新完整源代码/Serv/saac/db.c
anson1788 a5b185b7ef Revert "re upload"
This reverts commit 274b7d169c.
2020-06-23 15:23:51 +08:00

1482 lines
40 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
仿件平件弘窗 勾五犯□正矛□旦及 隶[
1999 Aug 14 Created by ringo
犯□正矛□旦反1 及伉件弁及溥匹忡绣今木月[
*/
#define _DB_C_
#include "db.h"
#include "main.h"
#include "util.h"
#include "version.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
/* 侬 巨件玄伉及 length */
//#define CHARVALUE_MAX 1024
#define MAXTABLE 16
// Spock 2000/10/12
#define CHARVALUE_MAX 256 // DB 字串资料的buffer大小
#define KEY_MAX 64 // DB Key字串的buffer大小
#define HASH_SIZE 65536 // Hash table 一次增加的Entry数量
#define HASH_PRIME 65521 // Hash function 使用的质数
#define DBINIT_SIZE 16384 // DB 每次配置Entry的数量
// Spock end
/* 犯□正矛□旦及伉件弁及邰豳1蜊毛丐日歹允 */
struct dbentry
{
int use;
// unsigned int keyhash; /* 腹绸平□及甩永扑亘戊□玉 */
int ivalue; /* 旦戊失[玄永皿 NODE 反 -1 匹}
允屯化及旦戊失反 0 动晓匹卅中午中仃卅中*/
// int nextind; /* -1 分匀凶日 毛啦 允月 */
// Spock 2000/10/12
int prev; // 前一个dbentry, -1表示此项为head
int next; // 下一个dbentry, -1表示此项为tail
char key[KEY_MAX];
char charvalue[CHARVALUE_MAX];
// char key[64]; /* 腹绸平□午卅月 侬 */
// int charvalue_index; /* 侬 田永白央毛今允index */
// Spock end
};
// Spock 2000/10/12
// Database hashtable
struct hashentry
{
char key[KEY_MAX]; // 索引key值
int use; // 是否已被使用
int dbind; // 指向 dbentry 的 index
int prev; // 同一key值的上一个 hashentry, -1为head
int next; // 同一key值的下一个 hashentry, -1为tail
};
// Spock end
typedef enum
{
DB_INT_SORTED,
DB_STRING,
}DBTYPE;
/* 1蜊及犯□正矛□旦毛丐日歹允 */
struct table
{
int use; // 0:未使用 1:已使用
DBTYPE type; /* DB及潘 */
char name[32]; /* 犯□正矛□旦及 蟆 */
int num; /* 巨件玄伉及醒 */
int toplinkindex;
// Spock 2000/10/12
struct hashentry *hashtable;
int hashsize;
int updated; // 0:dbflush後未更新 1:已更新
int ent_finder; // 指向最後一次配置的 hashentry
// Spock end
};
struct dbentry *master_buf; /* 巨件玄伉筏盛迕 */
int dbsize = 0; /* 赓0匹1,2,4,8,16...*/
static int dbent_finder = 0;
struct table dbt[MAXTABLE];
static void dbShowAllTable(void);
// Spock 2000/10/12
int dbHash(char* s)
{
char *p;
unsigned int h= 0 ,g;
for( p = s ; *p ; p ++ ){
h = ( h<< 4 ) + (*p);
if( (g = h & 0xf0000000) != 0){
h = h ^ (g>>24);
h = h ^ g;
}
}
return h % HASH_PRIME;
}
// Spock end
/* Spock deleted 2000/10/12
struct charvalue
{
int use;
char buf[CHARVALUE_MAX];
};
struct charvalue *charvalue_buf;
int charvaluesize=0;
*/
/*
侬 田永白央□毛傀舰允月
*/
/* Spock deleted 2000/10/12
int
reallocCharValue(void)
{
struct charvalue *previous = charvalue_buf;
struct charvalue *newbuf;
int new_charvaluesize;
if( charvaluesize == 0 ){
new_charvaluesize = 1;
} else {
new_charvaluesize = charvaluesize * 2;
}
newbuf = ( struct charvalue *) calloc( 1, new_charvaluesize *
sizeof( struct charvalue ));
if( newbuf == NULL ){
log( "reallocCharValue: memory shortage!! new_charvaluesize:%d\n",
new_charvaluesize );
return -1;
}
memset( newbuf, 0 , new_charvaluesize * sizeof( struct charvalue ));
if( previous) memcpy( (char*)newbuf, (char*)previous,
charvaluesize * sizeof( struct charvalue ));
free( previous );
charvaluesize = new_charvaluesize;
charvalue_buf = newbuf;
log( "reallocCharValue: "
"new_charvaluesize:%d Old address:%x New address:%x\n",
new_charvaluesize , (unsigned int )previous,
(unsigned int)newbuf );
return 0;
}
*/
/*
侬 田永白央□毛1蜊歹曰丐化月
凶曰卅仁卅匀凶日realloc允月
*/
/* Spock deleted 2000/10/12
static int charvalue_finder=0;
static int
dbAllocCharValue( void )
{
int i;
for(i=0;i<charvaluesize;i++){
charvalue_finder++;
if( charvalue_finder == charvaluesize ) charvalue_finder =0;
if( charvalue_buf[charvalue_finder].use == 0 ){
charvalue_buf[charvalue_finder].use =1;
charvalue_buf[charvalue_finder].buf[0] = 0;
return charvalue_finder;
}
}
log( "dbAllocCharValue: charvalue array full. reallocating....\n" );
if( reallocCharValue() < 0 ){
log( "dbAllocCharValue: reallocation fail\n");
} else {
return dbAllocCharValue();
}
return -1;
}
*/
/*
charvalue 井日/卞袄毛必永玄/本永玄允月
int index : charvalue index
*/
/* Spock deleted 2000/10/12
static char *
dbGetString( int index )
{
return charvalue_buf[index].buf;
}
static int
dbSetString( int index , char *data )
{
int l = strlen(data);
if( l >= (sizeof( charvalue_buf[0].buf )-1)) return -1;
memcpy( charvalue_buf[index].buf , data, l+1 );
return 0;
}
*/
/*
DB及云云五今互凶日氏仁卅匀凶日歹曰丐化卅云允中引及扔奶术及2 卞允月
0分匀凶日1卞允月
*/
static int
reallocDB( void )
{
struct dbentry *previous = master_buf;
struct dbentry *newbuf;
int new_dbsize;
/* Spock deleted 2000/10/12
if( dbsize == 0 ){
new_dbsize = 1;
} else {
new_dbsize = dbsize * 2;
}
*/
// Spock+1 2000/10/12
new_dbsize = dbsize + DBINIT_SIZE;
newbuf = (struct dbentry* ) calloc( 1, new_dbsize *
sizeof( struct dbentry) );
/* 丢乒伉凶曰卅中 */
if( newbuf == NULL ){
log( "重新分配数据: 内存不足!!! 新数据大小: %d\n", new_dbsize );
return -1;
}
/* 衙中幻丹井日蕙仄中 卞戊疋□仄化 */
memset( newbuf , 0 , new_dbsize * sizeof( struct dbentry ) );
/* Spock deleted 2000/10/19
if( previous )memcpy( (char*)newbuf, (char*)previous,
dbsize * sizeof( struct dbentry ));
// 衙中幻丹毛荸 仄
free( previous );
*/
// Spock 2000/10/19
if ( dbsize > 0 )
{
memcpy( newbuf , previous , dbsize * sizeof(struct dbentry));
free( previous );
}
// Spock end
dbent_finder = dbsize; // 将 dbent_finder 指向未使用的 entry
dbsize = new_dbsize;
master_buf = newbuf;
log( "重新分配数据: 新数据大小:%d 旧地址: %x 新地址:%x\n",
new_dbsize , (unsigned int)previous, (unsigned int)newbuf );
return 0;
}
/*
allocate a node
*/
static int
//dbAllocNode( DBTYPE type )
// Spock +1 2000/10/13
dbAllocNode()
{
int i;
for(i=0;i<dbsize;i++){
dbent_finder ++;
if( dbent_finder == dbsize ) {
dbent_finder = 0;
}
if( master_buf[dbent_finder].use == 0 ){
master_buf[dbent_finder].use = 1;
/* Spock deleted 2000/10/12
// int 匹手尥笛树 及啃卞stringbuffer毛 勾仪卞允月 kawata
if( type == DB_STRING || type == DB_INT_SORTED){
if( ( master_buf[dbent_finder].charvalue_index =
dbAllocCharValue() ) < 0 ){
// 侬 田永白央□互凶曰卅中冗
return -1;
}
}
*/
return dbent_finder;
}
}
log( "数据进入队列失败. 重新分配中....\n" );
if( reallocDB() < 0 ){
log( "重新分配失败\n" );
} else {
//return dbAllocNode( type );
// Spock 2000/10/13
master_buf[dbent_finder].use = 1;
log( "数据探测=%d\n" , dbent_finder );
return dbent_finder;
// Spock end
}
return -1;
}
static void
dbReleaseNode( int index )
{
// Spock 2000/10/12
int prev = master_buf[index].prev;
int next = master_buf[index].next;
master_buf[index].use = 0;
if ( prev >= 0 ) master_buf[prev].next = next;
if ( next >= 0 ) master_buf[next].prev = prev;
// Spock end
/* Spock deleted 2000/10/12
if( master_buf[index].charvalue_index >= 0 ) {
charvalue_buf[ master_buf[index].charvalue_index].use = 0;
}
*/
}
void
dbShowLink( int topind )
{
int cur = topind;
log( "开始从 %d 链接数据\n", cur );
/* Spock deleted 2000/10/19
for(;;){
if( cur == -1 )break;
*/
// Spock +1 2000/10/19
while ( cur >= 0 )
{
if( master_buf[cur].use == 0 ){
log( "dbShowLink: use is 0! key:%s\n", master_buf[cur].key );
return;
}
// Spock +1 2000/10/12
log( "%s %i\n", master_buf[cur].key, master_buf[cur].ivalue );
/* Spock deleted 2000/10/12
log( "%s %u %i\n", master_buf[cur].key ,
master_buf[cur].keyhash, master_buf[cur].ivalue );
*/
cur = master_buf[cur].next;
}
}
// Spock 2000/10/13
static int
reallocHash( int dbi )
{
struct hashentry *previous = dbt[dbi].hashtable;
struct hashentry *newbuf;
int new_hashsize;
new_hashsize = dbt[dbi].hashsize + HASH_SIZE;
newbuf = (struct hashentry* ) calloc( 1, new_hashsize *
sizeof( struct hashentry) );
if( newbuf == NULL ){
log( "重新分配无用信息: 内存不足!!! 新无用信息大小: %d\n", new_hashsize );
return -1;
}
memset( newbuf , 0 , new_hashsize * sizeof( struct hashentry ) );
if( previous )
{
memcpy( newbuf, previous,
dbt[dbi].hashsize * sizeof( struct hashentry ));
free( previous );
}
if ( dbt[dbi].hashsize > HASH_PRIME )
dbt[dbi].ent_finder = dbt[dbi].hashsize;
else
dbt[dbi].ent_finder = HASH_PRIME;
dbt[dbi].hashsize = new_hashsize;
dbt[dbi].hashtable = newbuf;
log( "重新分配无用信息: 新无用信息大小:%d 旧地址: %x 新地址:%x\n",
new_hashsize , (unsigned int)previous, (unsigned int)newbuf );
return 0;
}
static int tableGetEntry( int dbi , char *k )
{
int hashkey = dbHash( k );
struct hashentry *hash = dbt[dbi].hashtable;
if ( hash[hashkey].use == 0 ) return -1;
while ( 1 ) {
// if ( hash[hashkey].use == 1 && strcmp( hash[hashkey].key , k ) == 0 ){
if ( hash[hashkey].use == 1 ){
if( strcmp( hash[hashkey].key , k ) == 0 )return hashkey;
}
hashkey = hash[hashkey].next;
if ( hashkey <= 0 ){
// log("err not found hash[%x] -%s!\n", hashkey, k)
return -1;
}
}
}
static int tableInsertNode( int dbi , char *k , int dbind )
{
int hashkey = dbHash( k );
int hashnext = -1;
int i;
struct hashentry *hash = dbt[dbi].hashtable;
if ( hash[hashkey].use == 0 ) {
strcpy( hash[hashkey].key , k );
hash[hashkey].use = 1;
hash[hashkey].dbind = dbind;
hash[hashkey].prev = -1;
hash[hashkey].next = -1;
dbt[dbi].num++;
return hashkey;
}else {
for ( i=0; i<dbt[dbi].hashsize-HASH_PRIME; i++ ){
dbt[dbi].ent_finder++;
if ( dbt[dbi].ent_finder >= dbt[dbi].hashsize )
dbt[dbi].ent_finder = HASH_PRIME;
if ( hash[dbt[dbi].ent_finder].use == 0 )
{
hashnext = dbt[dbi].ent_finder;
break;
}
}
if ( hashnext < HASH_PRIME )
{
log( "tableInsertNode: hashentry array full. reallocating....\n" );
if( reallocHash( dbi ) < 0 ){
log( "tableInsertNode: reallocation fail\n" );
return -1;
}
else
{
hash = dbt[dbi].hashtable;
hashnext = dbt[dbi].ent_finder;
}
}
strcpy( hash[hashnext].key , k );
hash[hashnext].use = 1;
hash[hashnext].dbind = dbind;
hash[hashnext].prev = hashkey;
hash[hashnext].next = hash[hashkey].next;
if ( hash[hashkey].next >= 0 )
hash[hash[hashkey].next].prev = hashnext;
hash[hashkey].next = hashnext;
dbt[dbi].num++;
return hashnext;
}
}
static void
tableReleaseNode( int dbi , int ind )
{
dbt[dbi].hashtable[ind].use = 0;
if ( dbt[dbi].hashtable[ind].prev >= 0 ){
dbt[dbi].hashtable[dbt[dbi].hashtable[ind].prev].next =
dbt[dbi].hashtable[ind].next;
}
if ( dbt[dbi].hashtable[ind].next >= 0 ){
dbt[dbi].hashtable[dbt[dbi].hashtable[ind].next].prev =
dbt[dbi].hashtable[ind].prev;
}
dbt[dbi].num--;
}
// Spock end
/*
伉件弁及玄永皿毛芨尹日木凶日}平□毛 曰卞用□玉毛腹绸允月[
心勾井日卅中桦宁反巨仿□匹反卅中及匹0
*/
/* Spock deleted 2000/10/13
static int
dbExtractNodeByKey( int topind , char *k )
{
int cur = topind;
int prev = -1;
unsigned int h = hashpjw( k );
// 伉件弁互坞匹手心勾井日卅中分仃卅及匹0毛井尹允
if( topind == -1 ) return 0;
for(;;){
if( cur == -1 )break;
if( master_buf[cur].keyhash == h
&& strcmp( master_buf[cur].key , k ) == 0 ){
// prev 及 戚互 cur 及戚卞卅月方丹卞允月
if( prev == -1 ){
// 燮 分匀凶及匹伉件弁反中元日卅中
} else {
master_buf[prev].nextind = master_buf[cur].nextind;
}
// 公木匹愤坌互伉旦玄井日陆木月及匹荸 允月
dbReleaseNode( cur );
log( "find key %s deleted\n", k );
return 0;
}
prev = cur;
cur = master_buf[cur].nextind;
}
// not found
log( "dbExtractNodeBykey: %s not found\n" , k );
return 0;
}
*/
// Spock 2000/10/13
static int
dbExtractNodeByKey( int dbi , char *k )
{
int hashind = tableGetEntry( dbi , k );
if ( hashind < 0 ){
log( "dbExtractNodeByKey: tableGetEntry fail, key:%s\n" , k );
return -1;
}
if ( dbt[dbi].hashtable[hashind].dbind < 0 ){
log( "dbExtractNodeByKey: invalid dbind in hash, key:%s\n" , k );
return -1;
}
dbReleaseNode( dbt[dbi].hashtable[hashind].dbind );
tableReleaseNode( dbi , hashind );
return 0;
}
// Spock end
/* Spock deleted 2000/10/12
static int
dbGetEntryByKey( int topind , char *k )
{
int cur = topind;
unsigned int h = hashpjw( k );
if( topind == -1 ) return 0;
for(;;){
if( cur == -1 )break;
if( master_buf[cur].keyhash == h
&& strcmp( master_buf[cur].key, k ) == 0 ){
return cur;
}
cur = master_buf[cur].nextind;
}
return -1;
}
*/
/*
伉件弁及玄永皿毛芨尹日木凶日}袄毛 曰卞用□玉毛腹绸仄化
赝濠卅午仇欠卞 Insert 允月[切中今中 井日云云五中 卞卅日氏匹中月午
移烂
*/
/* Spock deleted 2000/10/13
static int
dbInsertNodeByIValue( int topind , int ins )
{
int cur = topind;
int prev = -1;
if( topind == -1 ) return -1;
for(;;){
if( cur == -1 ){
// 引匹中匀凶及匹馨笛允月
master_buf[prev].nextind = ins;
master_buf[ins].nextind = -1;
return 0;
}
if( master_buf[cur].ivalue < master_buf[ins].ivalue ){
if( prev == -1 ){
log( "top_node is badly configured\n" );
return -1;
}
master_buf[prev].nextind = ins;
master_buf[ins].nextind = cur;
return 0;
}
prev = cur;
cur = master_buf[cur].nextind;
}
return -1;
}
*/
// Spock 2000/10/13
static int
dbInsertNodeByIValue( int topind , int ins )
{
int cur = topind;
if ( (topind < 0)||(topind >= dbsize)||(ins < 0)||(ins >= dbsize ) )
return -1;
while ( master_buf[cur].next >= 0 ){
if ( master_buf[master_buf[cur].next].ivalue < master_buf[ins].ivalue )
break;
cur = master_buf[cur].next;
}
master_buf[ins].prev = cur;
master_buf[ins].next = master_buf[cur].next;
if ( master_buf[cur].next >= 0 )
master_buf[master_buf[cur].next].prev = ins;
master_buf[cur].next = ins;
return 0;
}
// Spock end
/* Spock deleted 2000/10/13
static int
dbAppendNode( int topind , int ins )
{
int cur =topind;
int prev = -1;
if( topind == -1 ) return -1;
for(;;){
if( cur == -1 ){
master_buf[prev].nextind = ins;
master_buf[ins].nextind = -1;
return 0;
}
prev = cur;
cur = master_buf[cur].nextind;
}
return -1;
}
*/
// Spock 2000/10/13
static int
dbAppendNode( int topind , int ins )
{
if ( (topind < 0)||(topind >= dbsize)||(ins < 0)||(ins >= dbsize ) )
return -1;
master_buf[ins].prev = topind;
master_buf[ins].next = master_buf[topind].next;
if ( master_buf[topind].next >= 0 )
master_buf[master_buf[topind].next].prev = ins;
master_buf[topind].next = ins;
return 0;
}
// Spock end
/*
犯□正矛□旦及 蟆毛 月db反醒互剂卅中及匹 骚卞strcmp仄化方中
DBTYPE :潘
云卅元卅引尹及 反}帮醒午 侬 及 卞绣箕允月仇午互匹五月[
*/
static int
dbGetTableIndex( char *tname , DBTYPE type )
{
int i;
for(i=0;i<MAXTABLE;i++){
if( dbt[i].use && strcmp( dbt[i].name , tname ) == 0 &&
dbt[i].type == type ){
return i ;
}
}
/* 心勾井日卅井匀凶及匹蕙筋分 */
for(i=0;i<MAXTABLE;i++){
if( dbt[i].use == 0 ){
int topind;
dbt[i].use = 1;
dbt[i].type = type;
snprintf( dbt[i].name , sizeof( dbt[i].name ) , "%s", tname );
// Spock 2000/10/16
if ( reallocHash( i ) < 0 )
{
log( "重新分配无用信息失败\n");
return -2;
}
dbt[i].ent_finder = HASH_PRIME;
// Spock end
//topind = dbAllocNode( type );
// Spock +1 2000/10/16
topind = dbAllocNode();
if( topind < 0 ){
log( "数据分配节点失败\n" );
return -2;
}
/* Spock deleted 2000/10/16
snprintf( master_buf[topind].key ,
sizeof(master_buf[topind].key), "top_node" );
master_buf[topind].keyhash = hashpjw( master_buf[topind].key );
master_buf[topind].nextind = -1;
*/
/* 玄永皿及用□玉毛赓渝祭允月卅曰[
侬 及桦宁手帮醒及桦宁手云卅元匹方中[
0x7fffffff午中丹袄反 侬 及桦宁反今幻升啦 毛手凶卅中及分[*/
master_buf[topind].ivalue = 0x7fffffff;
/* Spock deleted 2000/10/16
if( type == DB_INT_SORTED ){
master_buf[topind].charvalue_index = -1;
//dbSetString( master_buf[topind].charvalue_index, "" );
} else {
dbSetString( master_buf[topind].charvalue_index, "" );
}
*/
// Spock 2000/10/16
master_buf[topind].prev = -1;
master_buf[topind].next = -1;
strcpy( master_buf[topind].key , "top_node" );
master_buf[topind].charvalue[0] = 0;
// Spock end
dbt[i].toplinkindex = topind;
return i;
}
}
/* 互中匀天中分[ */
log( "dbGetTableIndex: table full. now tables are:\n" );
dbShowAllTable();
return -1;
}
/*
午曰丐尹内 strtol 匹五月袄仄井扔禾□玄仄卅中方
腹绸仄化苇勾仃凶用□玉卞覆仄化}
伉件弁井日 五午匀化井日}漆蘸反末□玄允月及卞银丹袄毛凶方曰卞
腹绸仄化}中中桦赭毛心勾仃凶日}公仇卞犒仄仇戈[
*/
/* Spock deleted 2000/10/16
int dbUpdateEntryInt( char *table , char *key , int value, char *info )
{
int r, dbi = dbGetTableIndex( table , DB_INT_SORTED );
int entind;
if( strlen(key) >= sizeof( master_buf[0].key) )return -1;
if( dbi < 0 ) return -1;
r = dbExtractNodeByKey( dbt[dbi].toplinkindex , key );
if( r < 0 ){
log( "dbUpdateEntryInt: dbExtractNodeByKey fail! bug!!!!\n" );
return -1;
}
entind = dbAllocNode(DB_INT_SORTED);
if( entind < 0 ) return -1;
master_buf[entind].ivalue = value;
snprintf( master_buf[entind].key ,
sizeof(master_buf[entind].key), "%s", key );
master_buf[entind].keyhash = hashpjw( master_buf[entind].key );
master_buf[entind].nextind = -1;
// 尥笛树 毛本永玄允月
dbSetString( master_buf[entind].charvalue_index, info );
r = dbInsertNodeByIValue( dbt[dbi].toplinkindex , entind );
if( r < 0 ){
log( "dbUpdateEntryInt: dbInsertNodeByIValue failed\n" );
return -1;
}
log( "dbUpdateEntryInt: successfully updated entry %s:%s:%d\n",
table, key, value );
return 0;
}
*/
// Spock 2000/10/16
int dbUpdateEntryInt( char *table , char *key , int value, char *info )
{
int dbi = dbGetTableIndex( table , DB_INT_SORTED );
int dbind, hashind, newpos;
// Spock 2000/10/23
if ( strlen( key ) >= KEY_MAX ) {
log( "dbUpdateEntryInt: key is too long, key:%s\n", key );
return -1;
}
if ( strlen( info ) >= CHARVALUE_MAX ) {
log( "dbUpdateEntryInt: charvalue is too long, charvalue:%s\n", info );
return -1;
}
// Spock end
if ( dbi < 0 ){
log( "dbUpdateEntryInt: dbGetTableIndex fail\n");
return -1;
}
hashind = tableGetEntry( dbi , key );
if ( hashind < 0 )
{
dbind = dbAllocNode();
if ( dbind < 0 )
{
log( "dbUpdateEntryInt: dbAllocNode fail\n" );
return -1;
}
master_buf[dbind].ivalue = value;
strcpy( master_buf[dbind].key , key );
strcpy( master_buf[dbind].charvalue , info );
if ( dbInsertNodeByIValue( dbt[dbi].toplinkindex , dbind ) < 0 )
{
master_buf[dbind].use = 0;
log( "dbUpdateEntryInt: dbInsertNodeByIValue fail\n" );
return -1;
}
if ( tableInsertNode( dbi , key , dbind ) < 0 )
{
dbReleaseNode( dbind );
log( "dbUpdateEntryInt: tableInsertNode fail\n" );
return -1;
}
}
else
{
dbind = dbt[dbi].hashtable[hashind].dbind;
master_buf[dbind].ivalue = value;
strcpy( master_buf[dbind].charvalue , info );
newpos = dbind;
while ( master_buf[newpos].prev >= 0 )
{
if ( value <= master_buf[master_buf[newpos].prev].ivalue )
{
break;
}
newpos = master_buf[newpos].prev;
}
if ( newpos != dbind )
{
master_buf[master_buf[dbind].prev].next = master_buf[dbind].next;
if ( master_buf[dbind].next >= 0 )
master_buf[master_buf[dbind].next].prev = master_buf[dbind].prev;
master_buf[dbind].prev = master_buf[newpos].prev;
master_buf[dbind].next = newpos;
if ( master_buf[newpos].prev >= 0 )
master_buf[master_buf[newpos].prev].next = dbind;
master_buf[newpos].prev = dbind;
dbt[dbi].updated = 1;
/*
log( "dbUpdateEntryInt: successfully updated entry %s:%s:%d\n",
table, key, value );
*/
return 0;
}
while ( master_buf[newpos].next >= 0 )
{
if ( value >= master_buf[master_buf[newpos].next].ivalue )
{
break;
}
newpos = master_buf[newpos].next;
}
if ( newpos != dbind )
{
master_buf[master_buf[dbind].prev].next = master_buf[dbind].next;
master_buf[master_buf[dbind].next].prev = master_buf[dbind].prev;
master_buf[dbind].prev = newpos;
master_buf[dbind].next = master_buf[newpos].next;
if ( master_buf[newpos].next >= 0 )
master_buf[master_buf[newpos].next].prev = dbind;
master_buf[newpos].next = dbind;
}
}
dbt[dbi].updated = 1;
/*
log( "dbUpdateEntryInt: successfully updated entry %s:%s:%d\n",
table, key, value );
*/
return 0;
}
// Spock end
int
dbDeleteEntryInt( char *table, char *key )
{
int dbi = dbGetTableIndex( table , DB_INT_SORTED );
int r;
if ( strlen( key ) >= KEY_MAX ) {
log( "dbDeleteEntryInt: key is too long, key:%s\n", key );
return -1;
}
if( dbi < 0 ) {
log( "dbDeleteEntryInt: dbGetTableIndex failed for %s\n", table );
return -1;
}
//r = dbExtractNodeByKey( dbt[dbi].toplinkindex , key );
// Spock fixed 2000/10/19
r = dbExtractNodeByKey( dbi , key );
if( r < 0 ){
log( "dbDeleteEntryInt: dbExtractNodeByKey failed for %s in %s\n",
key,table );
return -1;
}
// Spock +1 2000/10/19
dbt[dbi].updated = 1;
log( "删除人物 %s 来至表 %s\n", key, table );
return 0;
}
static void
dbShowAllTable(void)
{
int i;
for(i=0;i<MAXTABLE;i++){
if( dbt[i].use ){
log( "%d Name:%s Use:%d Type:%d\n",i,
dbt[i].name , dbt[i].num , dbt[i].type );
}
}
}
/* 犯□正毛1蜊潸曰分允
*/
int
dbGetEntryInt( char *table, char *key, int *output )
{
int dbi = dbGetTableIndex( table , DB_INT_SORTED );
int entind;
// Spock +1 2000/10/19
int hashind;
// Spock deleted 2000/10/19
//if( strlen(key) >= sizeof( master_buf[entind].key) ) return -1;
if( dbi <0 ) {
log( "dbGetEntryInt: dbGetTableIndex fail\n" );
return -1;
}
// Spock 2000/10/19
if( strlen(key) >= KEY_MAX ) {
log( "dbGetEntryInt: key is too long, key:%s\n" , key );
return -1;
}
hashind = tableGetEntry( dbi , key );
if( hashind < 0 ) return -1;
entind = dbt[dbi].hashtable[hashind].dbind;
//entind = dbGetEntryByKey( dbt[dbi].toplinkindex , key );
// Spock end
if( entind < 0 ) {
log( "dbGetEntryInt: Invalid dbind in hashtable of %s\n" , table );
return -1;
}
/* 心勾井匀凶及匹袄毛请 卞 木化忒允 */
*output = master_buf[entind].ivalue;
return 0;
}
/*
巨仿□及桦宁反 0分匀凶日岳
int *rank_out : 仿件弁及请
int *count_out : 晓井日窒蜊 井及请
int 犯□正矛□旦毁迕友
*/
int
dbGetEntryRank( char *table, char *key , int *rank_out, int *count_out)
{
int dbi = dbGetTableIndex( table , DB_INT_SORTED );
// Spock deleted 2000/10/19
//unsigned int hash = hashpjw(key);
int cur;
int now_score = 0x7fffffff; /*int 匹中切壬氏匹井中袄 */
int r = -1 , i=0;
// Spock 2000/10/23
//if( strlen(key) >= sizeof( master_buf[cur].key) ) return -1;
if( strlen(key) >= KEY_MAX ) {
log( "dbGetEntryRank: key is too long, key:%s\n" , key );
return -1;
}
if( dbi <0 ) {
log( "dbGetEntryRank: dbGetTableIndex fail\n" );
return -1;
}
// Spock end
// Spock 2000/10/23
//cur = master_buf[dbt[dbi].toplinkindex].nextind;
cur = master_buf[dbt[dbi].toplinkindex].next;
//i=0;
//for(;;){
// if( cur == -1 )break;
while ( cur >= 0 )
{
// Spock end
if( master_buf[cur].ivalue != now_score ){
r=i;
now_score = master_buf[cur].ivalue;
}
// Spock 2000/10/19
//if( hash == master_buf[cur].keyhash &&
// strcmp( master_buf[cur].key, key )== 0 ){
if( strcmp( master_buf[cur].key , key ) == 0 )
{
// Spock end
*rank_out = r;
*count_out = i;
return 0;
}
//cur = master_buf[cur].nextind;
// Spock fixed 2000/10/19
cur = master_buf[cur].next;
i++;
}
*count_out = i;
*rank_out = r;
return 0;
}
/*
int 毁迕友
*/
int
dbGetEntryRankRange( char *table,
int start, int end, char *output, int outlen )
{
#define MAXHITS 1024 /* 赝癫支卅丐[匹手仇木匹蜗坌日仄中冗 ringo */
struct hitent{ /* 仇及厌瞻 卞甲永玄仄凶支勾毛凶户化中仁 */
int entind;
int rank;
};
int r=0;
struct hitent hits[MAXHITS];
int dbi = dbGetTableIndex( table , DB_INT_SORTED );
int cur;
int hitsuse = 0,i;
int now_score = 0x7fffffff;
if( dbi <0 ) return -1;
if( outlen <= 0 )return -1;
cur = dbt[dbi].toplinkindex;
// Spock 2000/10/23
//for(;;){
// if( cur == -1 )break;
while ( cur >= 0 )
{
// Spock end
if( master_buf[cur].ivalue != now_score ){
r++;
now_score = master_buf[cur].ivalue;
}
if( r >= start && r <= end ){
hits[hitsuse].entind = cur;
hits[hitsuse].rank = r;
hitsuse++;
//if( hitsuse == MAXHITS )break;
// Spock fixed 2000/10/23
if( hitsuse >= MAXHITS ) break;
}
//cur = master_buf[cur].nextind;
// Spock fixed 2000/10/19
cur = master_buf[cur].next;
}
output[0] = 0;
for(i=0;i<hitsuse;i++){
char tmp[1024];
snprintf( tmp, sizeof(tmp),
"%d,%s,%d,%s", hits[i].rank, master_buf[hits[i].entind].key,
master_buf[hits[i].entind].ivalue,
// dbGetString( master_buf[i].charvalue_index ));
// Spock fixed 2000/10/19
master_buf[hits[i].entind].charvalue );
strcatsafe( output, outlen, tmp );
if( i != ( hitsuse -1 ) ){
strcatsafe( output, outlen, "|" );
}
}
return 0;
}
int dbFlush( char *dir )
{
int i;
for(i=0;i<MAXTABLE;i++){
FILE *fp;
char filename[1024];
int entind;
//int j;
if( !dbt[i].use ) continue;
// Spock 2000/10/23
if( dbt[i].updated == 0 )
{
log( "dbFlush: table %s not updated\n" , dbt[i].name );
continue;
}
// Spock end
if( dbt[i].type == DB_INT_SORTED ){
snprintf( filename, sizeof(filename),
"%s/int/%s", dir, dbt[i].name );
} else {
snprintf( filename, sizeof( filename),
"%s/string/%s", dir, dbt[i].name );
}
fp = fopen( filename, "w" );
if( fp == NULL ){
log( "cannot open file: %s %s\n", filename, strerror( errno ));
continue;
}
// Spock 2000/10/19
//entind = master_buf[dbt[i].toplinkindex].nextind;
entind = master_buf[dbt[i].toplinkindex].next;
//for(j=0;;j++){
// if( entind == -1 )break;
while ( entind >= 0 )
{
// Spock end
if( dbt[i].type == DB_INT_SORTED ){
fprintf( fp , "%s %d %s\n", master_buf[entind].key,
master_buf[entind].ivalue,
//makeStringFromEscaped(
// dbGetString(master_buf[entind].charvalue_index)));
// Spock fixed 2000/10/19
makeStringFromEscaped(master_buf[entind].charvalue));
} else {
fprintf( fp , "%s %s\n", master_buf[entind].key,
//makeStringFromEscaped(
// dbGetString(master_buf[entind].charvalue_index)));
// Spock fixed 2000/10/19
makeStringFromEscaped(master_buf[entind].charvalue));
}
//entind = master_buf[entind].nextind;
// Spock fixed 2000/10/19
entind = master_buf[entind].next;
}
fclose(fp);
dbt[i].updated = 0;
}
return 0;
}
int dbRead( char *dir )
{
char dirname[1024];
DIR *d;
struct dirent *de;
// Spock +1 2000/10/19
memset( dbt , 0 , MAXTABLE * sizeof(struct table) );
{
char tmp[1024];
snprintf( tmp, sizeof( tmp ), "%s/int" , dir );
if( mkdir( tmp, 0755 )==0){
log( "创建 %s\n", tmp );
}
snprintf( tmp, sizeof( tmp ), "%s/string" , dir );
if( mkdir( tmp, 0755 )==0){
log( "创建 %s\n", tmp );
}
}
snprintf( dirname, sizeof( dirname ),
"%s/int" , dir );
d = opendir(dirname);
if( d == NULL ){
log( "不能打开文件 %s\n", dirname );
return -1;
}
while(1){
de = readdir( d );
if( de == NULL )break;
if( de->d_name[0] != '.' ){
char filename[1024];
FILE *fp;
struct stat s;
snprintf( filename, sizeof(filename),"%s/%s",dirname, de->d_name );
log( "读取数据:%s\n..", filename);
if( stat( filename, &s ) < 0 ){
continue;
}
if( !( s.st_mode & S_IFREG ) ){
continue;
}
fp = fopen( filename, "r" );
if( fp == NULL ){
log( "不能打开文件 %s %s\n",
filename, strerror( errno ));
continue;
}
while(1){
char line[1024];
char k[1024] , v[1024], info[1024];
if( fgets( line , sizeof( line) , fp ) == NULL )break;
chop( line);
k[0] = '\0';
easyGetTokenFromString( line, 1, k, sizeof(k));
v[0] = '\0';
easyGetTokenFromString( line, 2, v, sizeof(v));
info[0] = '\0';
easyGetTokenFromString( line, 3, info, sizeof(info));
dbUpdateEntryInt( de->d_name, k, atoi(v), info);
}
fclose(fp);
}
}
closedir(d);
snprintf( dirname, sizeof( dirname), "%s/string" , dir );
d = opendir( dirname );
if( d == NULL ){
log( "不能打开文件 %s\n", dirname );
return -1;
}
while(1){
de = readdir( d );
if( de == NULL )break;
if( de->d_name[0] != '.' ){
char filename[1024];
FILE *fp;
struct stat s;
snprintf( filename, sizeof( filename),"%s/%s",dirname,de->d_name );
log( "读取数据:%s\n..", filename);
if( stat( filename, &s ) < 0 ){
continue;
}
if( !(s.st_mode & S_IFREG )){
continue;
}
fp = fopen( filename, "r" );
if( fp == NULL ){
log( "不能打开文件 %s %s\n",
filename, strerror(errno ));
continue;
}
while(1){
char line[CHARVALUE_MAX+1024];
char k[1024];
if( fgets( line, sizeof( line), fp ) == NULL )break;
/* chop */
chop(line);
k[0] = '\0';
easyGetTokenFromString( line, 1, k,sizeof(k));
dbUpdateEntryString( de->d_name, k, line+strlen(k)+1);
}
// Nuke +1 1027: Close for safe
fclose(fp);
}
}
closedir(d);
return 0;
}
/* 隙烂仄凶匏 井日隙烂仄凶蜊醒潸曰分允[
撩 仄凶日 }岳 仄凶日0岳 仄化手坞及请 及午五互丐月冗[
“num互0及午五午井竟癫允月巨件玄伉互卅中午五
int 犯□正矛□旦毁迕分冗
*/
int dbGetEntryCountRange( char *table, int count_start, int num,
char *output, int outlen )
{
int dbi = dbGetTableIndex( table , DB_INT_SORTED );
int cur;
int i;
int now_score = 0x7fffffff , r;
if( dbi < 0) return -1;
if( outlen < 1 ) return -1;
output[0]=0;
//cur = master_buf[dbt[dbi].toplinkindex].nextind;
// Spock fixed 2000/10/19
cur = master_buf[dbt[dbi].toplinkindex].next;
i=0;
r=0;
for(;;){
if( cur == -1 ) break;
if( master_buf[cur].ivalue != now_score ){
r=i;
now_score = master_buf[cur].ivalue;
}
if( ( i >= count_start ) &&
( i < (count_start + num ) ) ){
char tmp[1024];
if( (i !=count_start)){
strcatsafe( output, outlen, "|" );
}
snprintf( tmp, sizeof( tmp),
"%d,%d,%s,%d,%s", i, r, master_buf[cur].key,
master_buf[cur].ivalue,
//dbGetString( master_buf[cur].charvalue_index ));
// Spock fixed 2000/10/19
master_buf[cur].charvalue);
strcatsafe( output, outlen,tmp );
}
i++;
//cur = master_buf[cur].nextind;
// Spock fixed 2000/10/19
cur = master_buf[cur].next;
}
return 0;
}
/*
侬 犯□正矛□旦及质
*/
/* Spock deleted 2000/10/19
int
dbUpdateEntryString( char *table, char *key, char *value )
{
int dbi = dbGetTableIndex(table, DB_STRING);
int r, entind;
log( "dbUpdateEntryString: [%s] [%s] [%s]\n", table, key, value );
if( strlen(key) >= sizeof(master_buf[0].key) )return -1;
if( dbi < 0 )return -1;
r = dbExtractNodeByKey( dbt[dbi].toplinkindex, key );
if( r< 0 ){
log( "dbUpdateEntryString dbExtractNodeByKey fail! bug!!\n" );
return -1;
}
entind = dbAllocNode( DB_STRING );
if( entind < 0 ) return -1;
master_buf[entind].ivalue = 0;
dbSetString( master_buf[entind].charvalue_index, value );
snprintf( master_buf[entind].key,
sizeof(master_buf[0].key), "%s",key );
master_buf[entind].keyhash = hashpjw( master_buf[entind].key );
master_buf[entind].nextind = -1;
if( dbAppendNode( dbt[dbi].toplinkindex, entind ) < 0 ){
log( "dbUpdateEntryString: dbAppendNode failed\n" );
return -1;
}
log( "dbUpdateEntryString: successfully updated entry %s:%s:%s\n",
table,key,value );
return 0;
}
*/
// Spock 2000/10/19
int dbUpdateEntryString( char *table, char *key, char *value )
{
int dbi = dbGetTableIndex( table , DB_STRING );
int dbind, hashind;
if ( strlen( key ) >= KEY_MAX ) {
log( "dbUpdateEntryString: key is too long, key:%s\n", key );
return -1;
}
if ( strlen( value ) >= CHARVALUE_MAX ) {
log( "dbUpdateEntryString: charvalue is too long, charvalue:%s\n", value );
return -1;
}
if ( dbi < 0 ) {
log( "dbUpdateEntryString: dbGetTableIndex fail, table:%s\n", table );
return -1;
}
hashind = tableGetEntry( dbi , key );
if ( hashind < 0 )
{
dbind = dbAllocNode();
if ( dbind < 0 )
{
log( "dbUpdateEntryString: dbAllocNode fail\n" );
return -1;
}
strcpy( master_buf[dbind].key , key );
strcpy( master_buf[dbind].charvalue , value );
if ( dbAppendNode( dbt[dbi].toplinkindex , dbind ) < 0 )
{
master_buf[dbind].use = 0;
log( "dbUpdateEntryString: dbAppendNode fail\n" );
return -1;
}
if ( tableInsertNode( dbi , key , dbind ) < 0 )
{
dbReleaseNode( dbind );
log( "dbUpdateEntryString: tableInsertNode fail\n" );
return -1;
}
}
else
{
dbind = dbt[dbi].hashtable[hashind].dbind;
strcpy( master_buf[dbind].charvalue , value );
}
dbt[dbi].updated = 1;
/*
log( "dbUpdateEntryString: successfully updated entry %s:%s:%s\n",
table,key,value );
*/
return 0;
}
// Spock end
int
dbGetEntryString( char *table, char *key, char *output, int outlen )
{
int dbi = dbGetTableIndex( table, DB_STRING );
int entind;
// Spock +1 2000/10/19
int hashind;
// Spock 2000/10/23
//if( strlen(key) >= sizeof( master_buf[entind].key) ) return -1;
if ( strlen(key) >= KEY_MAX ) {
log( "dbGetEntryString: key is too long, key:%s\n", key );
return -1;
}
if( dbi <0 ) {
log( "dbGetEntryString: dbGetTableIndex fail\n" );
return -1;
}
// Spock 2000/10/19
hashind = tableGetEntry( dbi , key );
if ( hashind < 0 ){
log("err hashind <0\n")
return -1;
}
entind = dbt[dbi].hashtable[hashind].dbind;
if ( entind < 0 ){
log( "entind < 0 ");
return -1;
}
snprintf( output , outlen , "%s" , master_buf[entind].charvalue );
return 0;
}
int
dbDeleteEntryString( char *table, char *key )
{
int dbi = dbGetTableIndex( table, DB_STRING );
int r;
// Spock 2000/10/23
//if( strlen(key) >= sizeof( master_buf[entind].key) ) return -1;
if ( strlen(key) >= KEY_MAX ) {
log( "dbDeleteEntryString: key is too long, key:%s\n", key );
return -1;
}
if( dbi <0 ) {
log( "dbDeleteEntryString: dbGetTableIndex fail\n" );
return -1;
}
// Spock end
//r = dbExtractNodeByKey( dbt[dbi].toplinkindex, key );
// Spock fixed 2000/10/19
r = dbExtractNodeByKey( dbi , key );
if( r < 0 ){
log( "dbDeleteEntryString: dbExtractNodeByKey failed for %s in %s\n",
key,table );
return -1;
}
dbt[dbi].updated = 1;
log( "删除人物 %s 来至表 %s\n", key, table );
return 0;
}