Files
sdb/memcache/memcache.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);
}