You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
243 lines
7.7 KiB
243 lines
7.7 KiB
/******************************************************************************
|
|
* Copyright © 2014-2015 The SuperNET Developers. *
|
|
* *
|
|
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
|
|
* the top-level directory of this distribution for the individual copyright *
|
|
* holder information and the developer policies on copyright and licensing. *
|
|
* *
|
|
* Unless otherwise agreed in a custom licensing agreement, no part of the *
|
|
* SuperNET software, including this file may be copied, modified, propagated *
|
|
* or distributed except according to the terms contained in the LICENSE file *
|
|
* *
|
|
* Removal or modification of this copyright notice is prohibited. *
|
|
* *
|
|
******************************************************************************/
|
|
|
|
#include "peggy.h"
|
|
|
|
void ramkv777_lock(struct ramkv777 *kv)
|
|
{
|
|
if ( kv->threadsafe != 0 )
|
|
portable_mutex_lock(&kv->mutex);
|
|
}
|
|
|
|
void ramkv777_unlock(struct ramkv777 *kv)
|
|
{
|
|
if ( kv->threadsafe != 0 )
|
|
portable_mutex_unlock(&kv->mutex);
|
|
}
|
|
|
|
int32_t ramkv777_delete(struct ramkv777 *kv,void *key)
|
|
{
|
|
int32_t retval = -1; struct ramkv777_item *ptr = 0;
|
|
if ( kv == 0 )
|
|
return(-1);
|
|
ramkv777_lock(kv);
|
|
HASH_FIND(hh,kv->table,key,kv->keysize,ptr);
|
|
if ( ptr != 0 )
|
|
{
|
|
HASH_DELETE(hh,kv->table,ptr);
|
|
free(ptr);
|
|
retval = 0;
|
|
}
|
|
ramkv777_lock(kv);
|
|
return(retval);
|
|
}
|
|
|
|
void *ramkv777_read(int32_t *valuesizep,struct ramkv777 *kv,void *key)
|
|
{
|
|
struct ramkv777_item *item = 0;
|
|
if ( kv == 0 )
|
|
{
|
|
printf("ramkv777_read: null ramkv??\n");
|
|
return(0);
|
|
}
|
|
//printf("search for [%llx] keysize.%d\n",*(long long *)key,keysize);
|
|
ramkv777_lock(kv);
|
|
HASH_FIND(hh,kv->table,key,kv->keysize,item);
|
|
ramkv777_unlock(kv);
|
|
if ( item != 0 )
|
|
{
|
|
if ( valuesizep != 0 )
|
|
*valuesizep = item->valuesize;
|
|
return(ramkv777_itemvalue(kv,item));
|
|
} //else printf("cant find key.%llx keysize.%d\n",*(long long *)key,kv->keysize);
|
|
if ( valuesizep != 0 )
|
|
*valuesizep = 0;
|
|
return(0);
|
|
}
|
|
|
|
void *ramkv777_write(struct ramkv777 *kv,void *key,void *value,int32_t valuesize)
|
|
{
|
|
struct ramkv777_item *item = 0; int32_t keysize = kv->keysize;
|
|
if ( kv == 0 )
|
|
return(0);
|
|
ramkv777_lock(kv);
|
|
HASH_FIND(hh,kv->table,key,keysize,item);
|
|
if ( item != 0 )
|
|
{
|
|
printf("item being added, already there\n");
|
|
if ( valuesize == item->valuesize )
|
|
{
|
|
if ( memcmp(ramkv777_itemvalue(kv,item),value,valuesize) != 0 )
|
|
{
|
|
vupdate_sha256(kv->sha256.bytes,&kv->state,key,kv->keysize);
|
|
vupdate_sha256(kv->sha256.bytes,&kv->state,value,valuesize);
|
|
memcpy(ramkv777_itemvalue(kv,item),value,valuesize);
|
|
}
|
|
ramkv777_unlock(kv);
|
|
return(item);
|
|
}
|
|
HASH_DELETE(hh,kv->table,item);
|
|
free(item);
|
|
vupdate_sha256(kv->sha256.bytes,&kv->state,key,kv->keysize);
|
|
}
|
|
item = calloc(1,ramkv777_itemsize(kv,valuesize));
|
|
memcpy(item->keyvalue,key,kv->keysize);
|
|
memcpy(ramkv777_itemvalue(kv,item),value,valuesize);
|
|
item->valuesize = valuesize;
|
|
item->rawind = (kv->numkeys++ * ACCTS777_MAXRAMKVS) | kv->kvind;
|
|
//printf("add.(%s) kv->numkeys.%d keysize.%d valuesize.%d [%llx]\n",kv->name,kv->numkeys,keysize,valuesize,*(long long *)ramkv777_itemkey(item));
|
|
HASH_ADD_KEYPTR(hh,kv->table,ramkv777_itemkey(item),kv->keysize,item);
|
|
vupdate_sha256(kv->sha256.bytes,&kv->state,key,kv->keysize);
|
|
vupdate_sha256(kv->sha256.bytes,&kv->state,value,valuesize);
|
|
ramkv777_unlock(kv);
|
|
if ( kv->dispflag != 0 )
|
|
fprintf(stderr,"%016llx ramkv777_write numkeys.%d kv.%p table.%p write kep.%p key.%llx size.%d, value.(%08x) size.%d\n",(long long)kv->sha256.txid,kv->numkeys,kv,kv->table,key,*(long long *)key,keysize,calc_crc32(0,value,valuesize),valuesize);
|
|
return(ramkv777_itemvalue(kv,item));
|
|
}
|
|
|
|
void *ramkv777_iterate(struct ramkv777 *kv,void *args,void *(*iterator)(struct ramkv777 *kv,void *args,void *key,void *value,int32_t valuesize))
|
|
{
|
|
struct ramkv777_item *item,*tmp; void *retval = 0;
|
|
if ( kv == 0 )
|
|
return(0);
|
|
ramkv777_lock(kv);
|
|
HASH_ITER(hh,kv->table,item,tmp)
|
|
{
|
|
if ( (retval= (*iterator)(kv,args!=0?args:item,item->keyvalue,ramkv777_itemvalue(kv,item),item->valuesize)) != 0 )
|
|
{
|
|
ramkv777_unlock(kv);
|
|
return(retval);
|
|
}
|
|
}
|
|
ramkv777_unlock(kv);
|
|
return(0);
|
|
}
|
|
|
|
void *ramkv777_saveiterator(struct ramkv777 *kv,void *args,void *key,void *value,int32_t valuesize)
|
|
{
|
|
FILE *fp = args;
|
|
if ( args != 0 )
|
|
{
|
|
if ( fwrite(key,1,kv->keysize,fp) != kv->keysize )
|
|
{
|
|
printf("Error saving key.[%d]\n",kv->keysize);
|
|
return(key);
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
/*char *OS_mvstr()
|
|
{
|
|
#ifdef __WIN32
|
|
return("rename");
|
|
#else
|
|
return("mv");
|
|
#endif
|
|
}*/
|
|
char *OS_mvstr();
|
|
long ramkv777_save(struct ramkv777 *kv)
|
|
{
|
|
FILE *fp; long retval = -1; char fname[512],oldfname[512],cmd[512];
|
|
sprintf(fname,"%s.tmp",kv->name);
|
|
if ( (fp= fopen(fname,"wb")) != 0 )
|
|
{
|
|
if ( ramkv777_iterate(kv,fp,ramkv777_saveiterator) == 0 )
|
|
{
|
|
printf("save %ld to HDD\n",ftell(fp));
|
|
retval = ftell(fp);
|
|
}
|
|
else printf("error saving item at %ld\n",ftell(fp));
|
|
fclose(fp);
|
|
} else printf("error creating(%s)\n",fname);
|
|
if ( retval > 0 )
|
|
{
|
|
sprintf(oldfname,"%s.%u",kv->name,(uint32_t)time(NULL));
|
|
sprintf(cmd,"%s %s %s",OS_mvstr(),kv->name,oldfname), system(cmd);
|
|
sprintf(cmd,"%s %s %s",OS_mvstr(),fname,kv->name), system(cmd);
|
|
}
|
|
return(retval);
|
|
}
|
|
|
|
struct ramkv777 *ramkv777_init(int32_t kvind,char *name,int32_t keysize,int32_t threadsafe)
|
|
{
|
|
struct ramkv777 *kv;
|
|
printf("ramkv777_init.(%s)\n",name);
|
|
kv = calloc(1,sizeof(*kv));
|
|
strcpy(kv->name,name);
|
|
kv->threadsafe = threadsafe, kv->keysize = keysize, kv->kvind = kvind;//, kv->dispflag = 1;
|
|
portable_mutex_init(&kv->mutex);
|
|
vupdate_sha256(kv->sha256.bytes,&kv->state,0,0);
|
|
return(kv);
|
|
}
|
|
|
|
int32_t ramkv777_disp(struct ramkv777 *kv)
|
|
{
|
|
struct ramkv777_item *item,*tmp; int32_t n = 0;
|
|
printf("ramkv777_disp.(%s)\n",kv->name);
|
|
if ( kv == 0 )
|
|
return(0);
|
|
ramkv777_lock(kv);
|
|
HASH_ITER(hh,kv->table,item,tmp)
|
|
{
|
|
n++;
|
|
printf("%llx: %llx\n",*(long long *)ramkv777_itemkey(item),*(long long *)ramkv777_itemvalue(kv,item));
|
|
}
|
|
ramkv777_unlock(kv);
|
|
printf("ramkv777_disp.(%s) n.%d items\n",kv->name,n);
|
|
return(n);
|
|
}
|
|
|
|
void ramkv777_free(struct ramkv777 *kv)
|
|
{
|
|
struct ramkv777_item *ptr,*tmp;
|
|
if ( kv != 0 )
|
|
{
|
|
HASH_ITER(hh,kv->table,ptr,tmp)
|
|
{
|
|
HASH_DEL(kv->table,ptr);
|
|
free(ptr);
|
|
}
|
|
free(kv);
|
|
}
|
|
}
|
|
|
|
int32_t ramkv777_clone(struct ramkv777 *clone,struct ramkv777 *kv)
|
|
{
|
|
struct ramkv777_item *item,*tmp; int32_t n = 0;
|
|
if ( kv != 0 )
|
|
{
|
|
HASH_ITER(hh,kv->table,item,tmp)
|
|
{
|
|
ramkv777_write(clone,item->keyvalue,ramkv777_itemvalue(kv,item),item->valuesize);
|
|
n++;
|
|
}
|
|
}
|
|
return(n);
|
|
}
|
|
|
|
struct ramkv777_item *ramkv777_itemptr(struct ramkv777 *kv,void *value)
|
|
{
|
|
struct ramkv777_item *item = 0;
|
|
if ( kv != 0 && value != 0 )
|
|
{
|
|
value = (void *)((long)value - (kv)->keysize);
|
|
item = (void *)((long)value - ((long)item->keyvalue - (long)item));
|
|
}
|
|
return(item);
|
|
}
|
|
|
|
|
|
|
|
|