mirror of
https://github.com/radareorg/sdb.git
synced 2026-11-09 04:29:36 -10:00
159 lines
3.7 KiB
C
159 lines
3.7 KiB
C
/* Copyleft 2011-2014 - mcsdb (aka memcache-SimpleDB) - pancake */
|
|
|
|
#include "mcsdb.h"
|
|
|
|
McSdb *mcsdb_new(const char *file) {
|
|
McSdb *ms;
|
|
Sdb *s = sdb_new (NULL, file, 0);
|
|
if (!s) return NULL;
|
|
ms = R_NEW (McSdb);
|
|
if (!ms) {
|
|
sdb_free (s);
|
|
return NULL;
|
|
}
|
|
ms->sdb = s;
|
|
ms->time = sdb_now ();
|
|
ms->gets = ms->sets = 0LL;
|
|
ms->evictions = ms->hits = ms->misses = 0LL;
|
|
ms->bread = ms->bwrite = 0LL;
|
|
ms->nfds = ms->tfds = 0;
|
|
return ms;
|
|
}
|
|
|
|
void mcsdb_flush(McSdb *ms) {
|
|
sdb_reset (ms->sdb);
|
|
}
|
|
|
|
void mcsdb_free(McSdb *ms) {
|
|
int i;
|
|
for (i=0; i<ms->nfds; i++)
|
|
net_close (ms->fds[i].fd);
|
|
sdb_sync (ms->sdb);
|
|
sdb_free (ms->sdb);
|
|
free (ms);
|
|
}
|
|
|
|
char *mcsdb_incr(McSdb *ms, const char *key, ut64 val) {
|
|
if (!sdb_num_exists (ms->sdb, key))
|
|
return NULL;
|
|
if (sdb_num_inc (ms->sdb, key, val, 0) == 0LL)
|
|
return NULL;
|
|
ms->sets++;
|
|
return sdb_get (ms->sdb, key, 0);
|
|
}
|
|
|
|
char *mcsdb_decr(McSdb *ms, const char *key, ut64 val) {
|
|
if (!sdb_num_exists (ms->sdb, key))
|
|
return NULL;
|
|
sdb_num_dec (ms->sdb, key, val, 0);
|
|
ms->sets++;
|
|
return sdb_get (ms->sdb, key, 0);
|
|
}
|
|
|
|
int mcsdb_set(McSdb *ms, const char *key, const char *value, ut64 exptime, ut32 cas) {
|
|
int ret = sdb_set (ms->sdb, key, value, cas);
|
|
sdb_expire_set (ms->sdb, key, exptime, cas);
|
|
ms->sets++;
|
|
return ret;
|
|
}
|
|
|
|
int mcsdb_add(McSdb *ms, const char *key, ut64 exptime, const char *body) {
|
|
if (!sdb_exists (ms->sdb, key)) {
|
|
sdb_set (ms->sdb, key, body, 0);
|
|
sdb_expire_set (ms->sdb, key, exptime, 0);
|
|
ms->sets++;
|
|
ms->hits++;
|
|
return 1;
|
|
}
|
|
ms->misses++;
|
|
return 0;
|
|
}
|
|
|
|
void mcsdb_append(McSdb *ms, const char *key, ut64 exptime, const char *body) {
|
|
int len = strlen (body);
|
|
char *a, *b;
|
|
a = sdb_get (ms->sdb, key, NULL);
|
|
if (a) {
|
|
int alen = strlen (a);
|
|
b = malloc (1 + len + alen);
|
|
memcpy (b, a, alen);
|
|
strcpy (b+alen, body);
|
|
sdb_set (ms->sdb, key, b, 0);
|
|
free (b);
|
|
free (a);
|
|
} else sdb_set (ms->sdb, key, body, 0);
|
|
sdb_expire_set (ms->sdb, key, exptime, 0);
|
|
ms->sets++;
|
|
}
|
|
|
|
void mcsdb_prepend(McSdb *ms, const char *key, ut64 exptime, const char *body) {
|
|
int len = strlen (body);
|
|
char *a, *b;
|
|
a = sdb_get (ms->sdb, key, 0);
|
|
if (a) {
|
|
int alen = strlen (a);
|
|
b = malloc (1 + len + alen);
|
|
strcpy (b, body);
|
|
strcpy (b+len, a);
|
|
sdb_set (ms->sdb, key, b, 0);
|
|
free (b);
|
|
free (a);
|
|
} else sdb_set (ms->sdb, key, body, 0);
|
|
sdb_expire_set (ms->sdb, key, exptime, 0);
|
|
ms->sets++;
|
|
}
|
|
|
|
int mcsdb_replace(McSdb *ms, const char *key, ut64 exptime, const char *body) {
|
|
if (sdb_exists (ms->sdb, key)) {
|
|
sdb_set (ms->sdb, key, body, 0);
|
|
sdb_expire_set (ms->sdb, key, exptime, 0);
|
|
ms->sets++;
|
|
ms->hits++;
|
|
return 1;
|
|
}
|
|
ms->misses++;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
NOT IMPLEMENTED
|
|
"cas" is a check and set operation which means "store this data but
|
|
only if no one else has updated since I last fetched it."
|
|
*/
|
|
// cas <key> <flags> <exptime> <bytes> <cas unqiue> [noreply]\r\n
|
|
int mcsdb_cas(McSdb *ms, const char *key, const char *value, ut64 exptime, ut32 cas) {
|
|
return mcsdb_set (ms, key, value, exptime, cas);
|
|
}
|
|
|
|
/* retrieval */
|
|
char *mcsdb_get(McSdb *ms, const char *key, ut64 *exptime, ut32 *cas) {
|
|
ut32 n;
|
|
char *s = sdb_get (ms->sdb, key, &n);
|
|
if (s) ms->hits++;
|
|
else ms->misses++;
|
|
ms->gets++;
|
|
if (cas) *cas = n;
|
|
*exptime = sdb_expire_get (ms->sdb, key, NULL);
|
|
return s;
|
|
}
|
|
|
|
int mcsdb_remove(McSdb *ms, const char *key, ut64 exptime) {
|
|
if (!sdb_exists (ms->sdb, key))
|
|
return 0;
|
|
if (exptime>0) {
|
|
sdb_expire_set (ms->sdb, key, exptime, 0);
|
|
return 0;
|
|
}
|
|
if (sdb_expire_get (ms->sdb, key, NULL) > 0) {
|
|
ms->evictions++;
|
|
}
|
|
return sdb_unset (ms->sdb, key, 0);
|
|
}
|
|
|
|
int mcsdb_touch(McSdb *ms, const char *key, ut64 exptime) {
|
|
if (!sdb_exists (ms->sdb, key)) {
|
|
return 0;
|
|
}
|
|
return sdb_expire_set (ms->sdb, key, exptime, 0);
|
|
}
|