Update sdb and fix configure

This commit is contained in:
pancake 2013-04-01 05:52:21 +02:00
parent ba7c3b8896
commit d39af2028d
43 changed files with 465 additions and 269 deletions

2
configure vendored
View File

@ -36,7 +36,7 @@ while : ; do
ENVWORDS="${ENVWORDS} $1_CPU $1_OS"
STR=`eval "echo ${S}$1"`
SPLIT_CPU="`echo "$STR" | cut -d - -f 1`"
SPLIT_OS="`echo "$STR" | awk -F - '{if(NF==4){print $4}else{print $2}}'`"
SPLIT_OS="`echo "$STR" | awk -F - '{if(NF==4){print $4}else{print $3}}'`"
eval "$1_CPU=\"$SPLIT_CPU\""
eval "$1_OS=\"$SPLIT_OS\""
shift

View File

@ -26,8 +26,7 @@ sdbclean:
$(SDBLIB):
cd sdb ; ${MAKE} src/sdb-version.h
cd sdb/src ; ${MAKE} ARCH=xxx \
RANLIB="${RANLIB}" \
cd sdb/src ; ${MAKE} ARCH=xxx RANLIB="${RANLIB}" \
CC="${CC}" CFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}" libsdb.a
.PHONY: sdb-sync sync-sdb sdbclean

View File

@ -4,10 +4,11 @@ VALADIR=bindings/vala
PWD=$(shell pwd)
PFX=${DESTDIR}${PREFIX}
HGFILES=`find sdb-${VERSION} -type f | grep -v hg | grep -v swp`
MANDIR=${PFX}/share/man/man1
all: src/sdb-version.h
cd src && ${MAKE}
cd memcache && ${MAKE}
${MAKE} -C src
${MAKE} -C memcache
ifneq (${HAVE_VALA},)
cd ${VALADIR} && ${MAKE}
cd ${VALADIR}/types && ${MAKE}
@ -33,10 +34,11 @@ dist:
rm -rf sdb-${VERSION}
install-dirs:
mkdir -p ${PFX}/lib/pkgconfig ${PFX}/bin
mkdir -p ${MANDIR} ${PFX}/lib/pkgconfig ${PFX}/bin
mkdir -p ${PFX}/share/vala/vapi ${PFX}/include/sdb
install: install-dirs
cp -f src/sdb.1 ${MANDIR}
cp -f src/libsdb.* ${PFX}/lib
cp -f src/sdb.h ${PFX}/include/sdb
cp -f src/sdb-version.h ${PFX}/include/sdb
@ -69,6 +71,7 @@ deinstall uninstall:
rm -f ${PFX}/lib/libmcsdb.a
rm -f ${PFX}/lib/pkgconfig/sdb.pc
rm -f ${PFX}/lib/pkgconfig/mcsdb.pc
rm -f ${MANDIR}/sdb.1
ifneq (${HAVE_VALA},)
rm -f ${PFX}/share/vala/vapi/sdb.vapi
rm -f ${PFX}/share/vala/vapi/mcsdb.vapi
@ -78,6 +81,7 @@ endif
symstall: install-dirs
cd src ; for a in libsdb.* ; do \
ln -fs ${PWD}/src/$$a ${PFX}/lib/$$a ; done
ln -fs ${PWD}/src/sdb.1 ${MANDIR}/sdb.1
ln -fs ${PWD}/src/sdb ${PFX}/bin
ln -fs ${PWD}/src/sdb.h ${PFX}/include/sdb
ln -fs ${PWD}/src/sdb-version.h ${PFX}/include/sdb
@ -98,4 +102,12 @@ ifneq (${HAVE_VALA},)
cd ${VALADIR}/types && ${MAKE} symstall PFX=${PFX}
endif
.PHONY: all ${VALADIR} clean dist install uninstall deinstall
# windows compiler prefix
WCP=i386-mingw32
w32: src/sdb-version.h
cd src ; \
${MAKE} OS=w32 WCP=${WCP} CC=${WCP}-gcc AR=${WCP}-ar RANLIB=${WCP}-ranlib sdb.exe
.PHONY: all ${VALADIR} clean dist w32
.PHONY: install-dirs install uninstall deinstall symstall

View File

@ -1,27 +1,27 @@
SDB (simple database)
=====================
author: pancake
Description
-----------
sdb is a simple key/value database with disk storage.
sdb is a simple string key/value database based on djb's cdb
disk storage and supports JSON and arrays introspection.
mcsdbd is a memcache server with disk storage based on sdb.
sdbtypes is a vala library that implements several data
structures on top of an sdb or memcache instance.
It is distributed as a standalone binary and a library.
json is supported in the core api. You can store json
objects as value for a specific key and access the members
using a path expression (get and set).
There's also the sdbtypes: a vala library that implements
several data structures on top of an sdb or a memcache instance.
namespace are also supported using the sdb_ns api, which
permits to store various references to other Sdb instances
from a single one.
Author
------
pancake <pancake@nopcode.org>
Contains
--------
* vala, luvit, newlisp and nodejs bindings
* namespaces (multiple sdb paths)
* atomic database sync (never corrupted)
* bindings for vala, luvit, newlisp and nodejs
* commandline frontend for sdb databases
* memcache client and server with sdb backend
* arrays support (syntax sugar)
* json parser/getter (js0n.c)
Rips
@ -32,8 +32,8 @@ Rips
Changes
-------
I have slightly modified the cdb code to get smaller databases
and be memory leak free.
I have modified cdb code a little to create smaller databases and
be memory leak free in order to use it from a library.
The sdb's cdb database format is 10% smaller than the original
one. This is because keylen and valuelen are encoded in 4 bytes:
@ -42,24 +42,38 @@ one. This is because keylen and valuelen are encoded in 4 bytes:
In a test case, a 4.3MB cdb database takes only 3.9MB after this
file format change.
Example
-------
Usage example
-------------
Let's create a database!
$ sdb d hello=world
$ sdb d hello
world
Using arrays (>=0.6):
$ sdb - '()list=1,2' '(0)list' '(0)list=foo' '()list' '(+1)list=bar'
1
foo
2
foo
fuck
2
Let's play with json:
$ sdb d g='{"foo":1,"bar":{"cow":3}}'
$ sdb d g?bar.cow
3
$ sdb - user='{"id":123}' +user?id user?id
123
124
$ sdb - user='{"id":123}' user?id=99 user?id
99
Use the prompt:
Using the commandline without any disk database:
$ sdb - foo=bar foo a=3 +a -a
bar
4
3
$ sdb -
foo=bar
@ -67,15 +81,13 @@ Use the prompt:
bar
a=3
+a
3
a
4
-a
4
3
Remove the database
$ rm -f d # :)
$ rm -f d
Backups
-------

View File

@ -1,26 +1,56 @@
DESTDIR?=
PREFIX?=/usr
VERSION=0.6
VERSION=0.6.1
CFLAGS+=-DVERSION=\"${VERSION}\"
CFLAGS_STD?=-D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700
CFLAGS+=${CFLAGS_STD}
CFLAGS+=-Wall
#CFLAGS+=-O3
#CFLAGS+=-ggdb -g -Wall -O0
HAVE_VALA=$(shell valac --version)
HAVE_VALA=$(shell valac --version 2> /dev/null)
# This is hacky
OS=$(shell uname)
ARCH=$(shell uname -m)
HOST_CC?=gcc
RANLIB?=ranlib
OS?=$(shell uname)
ARCH?=$(shell uname -m)
ifeq (${OS},w32)
WCP?=i386-mingw32
CC=${WCP}-gcc
AR?=${WCP}-ar
CFLAGS_SHARED?=-fPIC -shared
EXEXT=.exe
else
CFLAGS_SHARED?=-fPIC -shared -fvisibility=hidden
CC?=gcc
EXEXT=
endif
# create .d files
CFLAGS+=-MMD
ifeq (${OS},Darwin)
SOEXT=dylib
LDFLAGS+=-dynamic
LDFLAGS_SHARED?=-fPIC -shared
ifeq (${ARCH},i386)
CC+=-arch i386 -arch x86_64
#CC+=-arch i386
CC+=-arch x86_64
endif
else
SOEXT=so
SOVERSION=0
SOEXT=so.0.0.0
LDFLAGS_SHARED?=-fPIC -shared
LDFLAGS_SHARED+=-Wl,-soname,libsdb.so.$(SOVERSION)
endif
ifeq ($(MAKEFLAGS),s)
SILENT=1
else
SILENT=
endif
RANLIB?=ranlib
EXEXT=

View File

@ -1,9 +1,11 @@
include ../config.mk
CFLAGS+= -g -ggdb
LDFLAGS+= -g -ggdb
#CFLAGS+=-DOLDFMT=1
OBJ=cdb.o buffer.o cdb_make.o ls.o ht.o sdb.o sdbn.o sdba.o query.o
OBJ+=json.o json/js0n.o json/json.o json/rangstr.o ns.o lock.o
OBJ+=json.o json/js0n.o json/json.o json/rangstr.o ns.o lock.o util.o
SOBJ=$(subst .o,._o,${OBJ})
BIN=sdb${EXEXT}
@ -23,35 +25,52 @@ static: sdb-version.h
${MAKE} libsdb.a
libsdb.a: ${OBJ}
@#ar qf libasb.a ${OBJ}
ifneq ($(SILENT),)
@echo AR libsdb.a
endif
rm -f libsdb.a
${AR} -r libsdb.a ${OBJ}
${RANLIB} libsdb.a
libsdb.${SOEXT}: ${OBJ}
${CC} ${CFLAGS} ${LDFLAGS} -o $@ $(subst .o,.c,${OBJ}) -fPIC -shared
t:
rm -f foo
./sdb foo a=3 b=200
hexdump -C foo
./sdb foo
./sdb foo a
tdd test:
sh tdd.sh
xxx:
rm -f foo
./sdb foo a=3
valgrind ./sdb foo a
valgrind ./sdb foo a=3 b=4
valgrind ./sdb foo a=9 b=2
main.c:
libsdb.${SOEXT}: ${SOBJ}
ifneq ($(SILENT),)
@echo LIB libsdb.${SOEXT}
endif
${CC} ${LDFLAGS} $(LDFLAGS_SHARED) -o $@ ${SOBJ}
${BIN}: libsdb.a main.o
${CC} ${CFLAGS} -o ${BIN} main.o ${OBJ}
ifneq ($(SILENT),)
@echo BIN ${BIN}
endif
${CC} ${LDFLAGS} -o ${BIN} main.o ${OBJ}
clean:
rm -rf ${OBJ} libsdb.a a.out sdb sdb.dSYM *.sdb *.db *.${SOEXT}
rm -rf ${OBJ} ${SOBJ} main.o libsdb.a a.out ${BIN} sdb.dSYM
rm -rf *.d *._d json/*.d json/*._d *.sdb *.db *.${SOEXT}
# rules #
.c:
ifneq ($(SILENT),)
@echo LD $<
endif
$(CC) $(LDFLAGS) -c $(CFLAGS) -o $@ $<
S=$
%.o: %.c
ifneq ($(SILENT),)
@echo CC $<
endif
${CC} -c ${CPPFLAGS} ${CFLAGS} ${CFLAGS_SHARED} -o $@ $<
%._o: %.c
ifneq ($(SILENT),)
@echo CC PIC $<
endif
@mv `echo $<|sed -e 's,\.c$S,\.d,g'` $<.tmp 2>/dev/null || true
${CC} -c ${CPPFLAGS} ${CFLAGS} ${CFLAGS_SHARED} -o $@ $<
@mv `echo $<|sed -e 's,\.c$S,\.d,g'` `echo $<|sed -e 's,\.c$S,\._d,g'` 2>/dev/null || true
@mv $<.tmp `echo $<|sed -e 's,\.c$S,\.d,g'` 2>/dev/null ||true
-include ${OBJ:.o=.d}
-include ${OBJ:.o=._d}

View File

@ -1,8 +0,0 @@
#ifndef ALLOC_H
#define ALLOC_H
extern /*@null@*//*@out@*/char *alloc();
extern void alloc_free();
extern int alloc_re();
#endif

View File

@ -13,7 +13,8 @@ void buffer_init(buffer *s, BufferOp op, int fd, char *buf, ut32 len) {
static int allwrite(BufferOp op, int fd, const char *buf, ut32 len) {
int w;
while (len > 0) {
if ((w = op (fd, buf, len)) != len)
w = op (fd, buf, len);
if (w < 0)
return 0;
buf += w;
len -= w;

View File

@ -10,7 +10,7 @@ typedef struct buffer {
unsigned int p;
unsigned int n;
int fd;
int (*op)();
BufferOp op;
} buffer;
#define BUFFER_INIT(op,fd,buf,len) { (buf), 0, (len), (fd), (op) }

View File

@ -37,7 +37,7 @@ void cdb_init(struct cdb *c, int fd) {
c->map = NULL;
cdb_findstart (c);
c->fd = fd;
if (fd != -1 && !fstat (fd, &st) && st.st_size != UT32_MAX) {
if (fd != -1 && !fstat (fd, &st) && st.st_size != (off_t)UT32_MAX) {
#if USE_MMAN
char *x = mmap (0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
#else
@ -62,8 +62,8 @@ int cdb_read(struct cdb *c, char *buf, ut32 len, ut32 pos) {
if (!seek_set (c->fd, pos))
return 0;
while (len > 0) {
int r = read (c->fd, buf, len);
if (r!=len) return 0;
ssize_t r = read (c->fd, buf, len);
if (r < 0) return 0;
buf += r;
len -= r;
}
@ -72,7 +72,7 @@ int cdb_read(struct cdb *c, char *buf, ut32 len, ut32 pos) {
static int match(struct cdb *c, const char *key, ut32 len, ut32 pos) {
char buf[32];
const int szb = sizeof buf;
const size_t szb = sizeof buf;
while (len > 0) {
int n = (szb>len)? len: szb;
if (!cdb_read (c, buf, n, pos))
@ -89,6 +89,7 @@ static int match(struct cdb *c, const char *key, ut32 len, ut32 pos) {
int cdb_findnext(struct cdb *c, ut32 u, const char *key, unsigned int len) {
char buf[8];
ut32 pos;
int m;
if (!c->loop) {
if (!cdb_read (c, buf, 8, (u << 3) & 2047))
@ -121,8 +122,7 @@ int cdb_findnext(struct cdb *c, ut32 u, const char *key, unsigned int len) {
if (!getkvlen (c->fd, &u, &c->dlen))
return -1;
if (u == len) {
int m = match (c, key, len, pos + KVLSZ);
if (m == -1)
if ((m = match (c, key, len, pos + KVLSZ))==-1)
return 0;
if (m == 1) {
c->dpos = pos + KVLSZ + len;

View File

@ -16,6 +16,10 @@
#define USE_MMAN 1
#endif
extern char *alloc(unsigned int n);
extern void alloc_free(void*);
extern int alloc_re(void);
/* TODO THIS MUST GTFO! */
int getkvlen(int fd, ut32 *klen, ut32 *vlen);
#define CDB_HASHSTART 5381

View File

@ -1,16 +1,12 @@
/* Public domain. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "alloc.h"
#include "sdb.h"
#include "cdb.h"
#include "cdb_make.h"
/****/
#include <stdlib.h>
#include "alloc.h"
#define ALIGNMENT 16 /* XXX: assuming that this alignment is enough */
#define SPACE 4096 /* must be multiple of ALIGNMENT */

View File

@ -44,7 +44,7 @@
* free to avoid exponential performance degradation as the hash table fills
*/
static const ut32 deleted_data;
static ut32 deleted_data;
static const struct {
ut32 max_entries, size, rehash;
@ -110,7 +110,7 @@ SdbHashEntry* ht_search(SdbHash *ht, ut32 hash) {
}
static int rehash = 0;
static void ht_rehash(SdbHash *ht, int new_size_index) {
static void ht_rehash(SdbHash *ht, ut32 new_size_index) {
SdbHash old_ht = *ht;
SdbHashEntry *e;
if (new_size_index >= ARRAY_SIZE (hash_sizes))

View File

@ -21,7 +21,7 @@ typedef struct ht_t {
SdbHash* ht_new(void);
void ht_free(SdbHash *ht);
void ht_set(SdbHash *ht, ut32 hash, void *data);
//void ht_set(SdbHash *ht, ut32 hash, void *data);
SdbHashEntry* ht_search(SdbHash *ht, ut32 hash);
void *ht_lookup(SdbHash *ht, ut32 hash);
void ht_set(SdbHash *ht, ut32 hash, void *data);

View File

@ -1,4 +1,4 @@
/* Copyleft 2012-2013 - sdb - pancake */
/* sdb - LGPLv3 - Copyright 2012-2013 - pancake */
#include <stdarg.h>
#include "sdb.h"
@ -28,7 +28,7 @@ static void __itoa(int value, char *string) {
*ptr = 0;
}
char *sdb_json_get (Sdb *s, const char *k, const char *p, ut32 *cas) {
SDB_VISIBLE char *sdb_json_get (Sdb *s, const char *k, const char *p, ut32 *cas) {
Rangstr rs;
char *u, *v = sdb_get (s, k, cas);
if (!v) return NULL;
@ -38,19 +38,19 @@ char *sdb_json_get (Sdb *s, const char *k, const char *p, ut32 *cas) {
return u;
}
int sdb_json_inc(Sdb *s, const char *k, const char *p, int n, ut32 cas) {
SDB_VISIBLE int sdb_json_inc(Sdb *s, const char *k, const char *p, int n, ut32 cas) {
int cur = sdb_json_geti (s, k, p);
sdb_json_seti (s, k, p, cur+n, cas);
return cur;
return cur+n;
}
int sdb_json_dec(Sdb *s, const char *k, const char *p, int n, ut32 cas) {
SDB_VISIBLE int sdb_json_dec(Sdb *s, const char *k, const char *p, int n, ut32 cas) {
int cur = sdb_json_geti (s, k, p);
sdb_json_seti (s, k, p, cur-n, cas);
return cur;
return cur-n;
}
int sdb_json_geti (Sdb *s, const char *k, const char *p) {
SDB_VISIBLE int sdb_json_geti (Sdb *s, const char *k, const char *p) {
char *v = sdb_get (s, k, 0); // XXX cas
if (v) {
Rangstr rs = json_get (v, p);
@ -59,13 +59,13 @@ int sdb_json_geti (Sdb *s, const char *k, const char *p) {
return 0;
}
int sdb_json_seti (Sdb *s, const char *k, const char *p, int v, ut32 cas) {
SDB_VISIBLE int sdb_json_seti (Sdb *s, const char *k, const char *p, int v, ut32 cas) {
char str[64];
__itoa (v, str);
return sdb_json_set (s, k, p, str, cas);
}
int sdb_json_set (Sdb *s, const char *k, const char *p, const char *v, ut32 cas) {
SDB_VISIBLE int sdb_json_set (Sdb *s, const char *k, const char *p, const char *v, ut32 cas) {
const char *beg[3];
const char *end[3];
int l, idx, len[3];
@ -114,7 +114,7 @@ int sdb_json_set (Sdb *s, const char *k, const char *p, const char *v, ut32 cas)
return 1;
}
char *sdb_json_indent(const char *s) {
SDB_VISIBLE char *sdb_json_indent(const char *s) {
int indent = 0;
int i, instr = 0;
char *o, *O = malloc (strlen (s)*2);
@ -162,7 +162,7 @@ char *sdb_json_indent(const char *s) {
return O;
}
char *sdb_json_unindent(const char *s) {
SDB_VISIBLE char *sdb_json_unindent(const char *s) {
int instr = 0;
int len = strlen (s);
char *o, *O = malloc (len);
@ -190,7 +190,7 @@ char *sdb_json_unindent(const char *s) {
return O;
}
const char *sdb_json_format(SdbJsonString* s, const char *fmt, ...) {
SDB_VISIBLE const char *sdb_json_format(SdbJsonString* s, const char *fmt, ...) {
va_list ap;
char *arg_s, *x, tmp[128];
float arg_f;

View File

@ -7,9 +7,9 @@
#define PUSH(i) if(depth == 1) prev = *out++ = ((cur+i) - js)
#define CAP(i) if(depth == 1) prev = *out++ = ((cur+i) - (js + prev) + 1)
int js0n(unsigned char *js, unsigned int len, unsigned short *out) {
int js0n(const unsigned char *js, unsigned int len, unsigned short *out) {
unsigned short prev = 0;
unsigned char *cur, *end;
const unsigned char *cur, *end;
int depth = 0, utf8_remain = 0;
static void *gostruct[] = {
[0 ... 255] = &&l_bad,

View File

@ -1,17 +1,18 @@
/* Copyleft 2012-2013 - sdb - pancake */
/* sdb - LGPLv3 - Copyright 2012-2013 - pancake */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rangstr.h"
#include "json.h"
#include "../types.h"
void json_path_first(Rangstr *s) {
char *p;
if (!s->p) return;
p = strchr (s->p, '.');
s->f = 0;
s->t = p? p-s->p: strlen (s->p);
s->t = p? (size_t)(p-s->p): strlen (s->p);
}
int json_path_next(Rangstr *s) {
@ -49,14 +50,15 @@ rep:
return 1;
}
#if 0
typedef int (*JSONCallback)();
int json_foreach(const char *s, JSONCallback cb) {
int json_foreach(const char *s, JSONCallback cb __unused) {
int i, len, ret;
unsigned short *res = NULL;
len = strlen (s);
res = malloc (len);
ret = js0n ((unsigned char *)s, len, res);
ret = js0n ((const unsigned char *)s, len, res);
if (!ret) return 0;
if (*s=='[') {
for (i=0; res[i]; i+=2) {
@ -70,13 +72,14 @@ int json_foreach(const char *s, JSONCallback cb) {
}
return 1;
}
#endif
int json_walk (const char *s) {
int i, len, ret;
unsigned short *res;
len = strlen (s);
res = malloc (len);
ret = js0n ((unsigned char *)s, len, res);
ret = js0n ((const unsigned char *)s, len, res);
if (!ret) return 0;
if (*s=='[' || *s=='{') {
for (i=0; res[i]; i+=2) {
@ -96,12 +99,12 @@ Rangstr json_find (const char *s, Rangstr *rs) {
unsigned short resfix[RESFIXSZ];
unsigned short *res = NULL;
int i, j, n, len, ret;
Rangstr rs2;
Rangstr rsn;
if (!s) return rangstr_null ();
len = strlen (s);
res = (len<RESFIXSZ)? resfix: malloc (len);
ret = js0n ((unsigned char *)s, len, res);
ret = js0n ((const unsigned char *)s, len, res);
#define PFREE(x) if (x&&x!=resfix) free (x)
if (ret>0) {
PFREE (res);
@ -113,16 +116,16 @@ Rangstr json_find (const char *s, Rangstr *rs) {
if (n<0) goto beach;
for (i=j=0; res[i] && j<n; i+=2, j++);
if (j<n) goto beach;
rs2 = rangstr_news (s, res, i-2);
rsn = rangstr_news (s, res, i-2);
PFREE (res);
return rs2;
return rsn;
} else {
for (i=0; res[i]; i+=4) {
Rangstr rs2 = rangstr_news (s, res, i);
if (!rangstr_cmp (rs, &rs2)) {
rs2 = rangstr_news (s, res, i+2);
Rangstr rsn = rangstr_news (s, res, i);
if (!rangstr_cmp (rs, &rsn)) {
rsn = rangstr_news (s, res, i+2);
PFREE (res);
return rs2;
return rsn;
}
}
}
@ -132,7 +135,8 @@ beach:
}
Rangstr json_get (const char *js, const char *p) {
int x, rst, n = 0;
int x, n = 0;
size_t rst;
Rangstr rj2, rj = rangstr_new (js);
Rangstr rs = rangstr_new (p);
json_path_first (&rs);
@ -180,6 +184,8 @@ return rj;
return rj;
}
char *json_set (const char *s, const char *k, const char *v) {
#if 0
char *json_set (const char *s __unused, const char *k __unused, const char *v __unused) {
return NULL;
}
#endif

View File

@ -3,7 +3,7 @@
#include "rangstr.h"
int js0n(unsigned char *js, unsigned int len, unsigned short *out);
int js0n(const unsigned char *js, unsigned int len, unsigned short *out);
Rangstr json_get (const char *s, const char *path);
/* string based api */

View File

@ -20,7 +20,7 @@ Rangstr rangstr_new (const char *s) {
return rs;
}
Rangstr rangstr_null() {
Rangstr rangstr_null(void) {
Rangstr rs = {0};
return rs;
}
@ -28,7 +28,8 @@ Rangstr rangstr_null() {
int rangstr_int (Rangstr *s) {
const int base = 10;
int mul = 1;
int ch, i = 0, n = 0;
int ch, n = 0;
size_t i = 0;
if (s->p[s->f]=='[')
i++;
if (s->p[s->f]=='-') {
@ -73,9 +74,9 @@ int rangstr_cmp (Rangstr *a, Rangstr *b) {
}
int rangstr_find (Rangstr* a, char ch) {
int i = a->f;
size_t i = a->f;
while (a->p[i] && i<a->t && a->p[i] != ch) i++;
return a->p[i]? i: -1;
return a->p[i]? (int)i: -1;
}
const char *rangstr_str (Rangstr* rs) {

View File

@ -9,13 +9,13 @@
typedef struct {
int type;
int next;
int f, t;
size_t f, t;
const char *p;
} Rangstr;
void rangstr_print (Rangstr *s);
Rangstr rangstr_new (const char *s);
Rangstr rangstr_null();
Rangstr rangstr_null(void);
int rangstr_int (Rangstr *s);
char *rangstr_dup (Rangstr *rs);
Rangstr rangstr_news (const char *s, ut16 *res, int i);

View File

@ -1,15 +1,18 @@
/* Copyleft 2011-2013 - sdb (aka SimpleDB) - pancake<nopcode.org> */
/* sdb - LGPLv3 - Copyright 2012-2013 - pancake */
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
//#include <sys/file.h>
#include "sdb.h"
#if WINDOWS
#include <windows.h>
#endif
static char buf[128];
const char *sdb_lockfile(const char *f) {
int len;
SDB_VISIBLE const char *sdb_lockfile(const char *f) {
size_t len;
if (!f || !*f)
return NULL;
len = strlen (f);
@ -20,7 +23,7 @@ const char *sdb_lockfile(const char *f) {
return buf;
}
int sdb_lock(const char *s) {
SDB_VISIBLE int sdb_lock(const char *s) {
int ret;
if (!s) return 0;
ret = open (s, O_CREAT | O_TRUNC | O_WRONLY | O_EXCL, 0644);
@ -30,19 +33,19 @@ int sdb_lock(const char *s) {
return 1;
}
void sdb_lock_wait(const char *s) {
SDB_VISIBLE void sdb_lock_wait(const char *s __unused) {
// TODO use flock() here
#if __WIN32__ || __CYGWIN__ || MINGW32
while (!sdb_lock (s)) {
// usleep (100); // hack
#if WINDOWS
Sleep (500); // hack
}
#else
// TODO flock (fd, LOCK_EX);
// usleep (100); // hack
#endif
}
}
void sdb_unlock(const char *s) {
SDB_VISIBLE void sdb_unlock(const char *s) {
//flock (fd, LOCK_UN);
unlink (s);
}

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2007-2012 pancake<nopcode.org> */
/* sdb - LGPLv3 - Copyright 2007-2013 - pancake */
#include <string.h>
#include "ls.h"

View File

@ -4,7 +4,9 @@
#include <stdio.h>
#include "types.h"
#ifndef R_API
#define R_API
#endif
// TODO: implement ls_foreach_prev
typedef void (*SdbListFree)(void *ptr);
@ -37,7 +39,7 @@ typedef int (*SdbListComparator)(void *a, void *b);
#define ls_iter_next(x) (x?1:0)
#define ls_iter_cur(x) x->p
#define ls_iter_unref(x) x
R_API SdbList *ls_new();
R_API SdbList *ls_new(void);
R_API SdbListIter *ls_append(SdbList *list, void *data);
R_API SdbListIter *ls_prepend(SdbList *list, void *data);
R_API int ls_length(SdbList *list);

View File

@ -1,4 +1,4 @@
/* Public domain -- pancake @ 2011-2013 */
/* sdb - LGPLv3 - Copyright 2011-2013 - pancake */
#include <signal.h>
#include <stdio.h>
@ -10,7 +10,7 @@
static int save = 0;
static Sdb *s = NULL;
static void terminate(int sig) {
static void terminate(int sig __unused) {
if (!s) return;
if (save) sdb_sync (s);
sdb_free (s);
@ -18,7 +18,7 @@ static void terminate(int sig) {
}
#if USE_MMAN
static void syncronize(int sig) {
static void syncronize(int sig __unused) {
// TODO: must be in sdb_sync() or wat?
Sdb *n;
sdb_sync (s);
@ -50,8 +50,7 @@ static void createdb(const char *f) {
exit (1);
}
for (;;) {
fgets (line, sizeof line, stdin);
if (feof (stdin))
if (!fgets (line, sizeof line, stdin) || feof (stdin))
break;
line[strlen (line)-1] = 0;
if ((eq = strchr (line, '='))) {
@ -63,22 +62,22 @@ static void createdb(const char *f) {
}
static void showusage(int o) {
printf ("usage: sdb [-fhv] [file.db] [-=]|[-+][(idx)key[?path|=value] ..]\n");
printf ("usage: sdb [-fhv] [db] [-=]|[-+][(idx)key[?path|=value] ..]\n");
exit (o);
}
static void showversion() {
static void showversion(void) {
printf ("sdb "VERSION"\n");
exit (0);
}
static void showfeatures() {
static void showfeatures(void) {
// TODO lock
printf ("ns json array\n");
exit (0);
}
int main(int argc, char **argv) {
int main(int argc, const char **argv) {
int i;
if (argc<2) showusage (1);
@ -104,8 +103,7 @@ int main(int argc, char **argv) {
char line[SDB_VSZ+SDB_KSZ]; // XXX can overflow stack
if ((s = sdb_new (argv[1], 0)))
for (;;) {
fgets (line, sizeof line, stdin);
if (feof (stdin))
if (!fgets (line, sizeof line, stdin) || feof (stdin))
break;
line[strlen (line)-1] = 0;
save = sdb_query (s, line);

View File

@ -1,8 +1,8 @@
/* Copyleft 2012-2013 - sdb (aka SimpleDB) - pancake<nopcode.org> */
/* sdb - LGPLv3 - Copyright 2011-2013 - pancake */
#include "sdb.h"
void sdb_ns_free(Sdb *s) {
SDB_VISIBLE void sdb_ns_free(Sdb *s) {
SdbNs *ns;
SdbListIter *it;
ls_foreach (s->ns, it, ns) {
@ -19,7 +19,7 @@ SdbNs *sdb_ns_new (const char *name, ut32 hash) {
return ns;
}
Sdb *sdb_ns(Sdb *s, const char *name) {
SDB_VISIBLE Sdb *sdb_ns(Sdb *s, const char *name) {
SdbNs *ns;
SdbListIter *it;
ut32 hash = sdb_hashstr (name);
@ -32,7 +32,7 @@ Sdb *sdb_ns(Sdb *s, const char *name) {
return ns->sdb;
}
void sdb_ns_sync (Sdb *s) {
SDB_VISIBLE void sdb_ns_sync (Sdb *s) {
SdbNs *ns;
SdbListIter *it;
ls_foreach (s->ns, it, ns) {

View File

@ -1,4 +1,4 @@
/* Copyleft 2011-2013 - sdb - pancake */
/* sdb - LGPLv3 - Copyright 2011-2013 - pancake */
#include <stdio.h>
#include <string.h>
@ -6,7 +6,7 @@
#include <stdlib.h>
#include "sdb.h"
int sdb_queryf (Sdb *s, const char *fmt, ...) {
SDB_VISIBLE int sdb_queryf (Sdb *s, const char *fmt, ...) {
char string[4096];
int ret;
va_list ap;
@ -17,7 +17,7 @@ int sdb_queryf (Sdb *s, const char *fmt, ...) {
return ret;
}
char *sdb_querysf (Sdb *s, char *buf, int buflen, const char *fmt, ...) {
SDB_VISIBLE char *sdb_querysf (Sdb *s, char *buf, size_t buflen, const char *fmt, ...) {
char string[4096];
char *ret;
va_list ap;
@ -28,21 +28,27 @@ char *sdb_querysf (Sdb *s, char *buf, int buflen, const char *fmt, ...) {
return ret;
}
char *sdb_querys (Sdb *s, char *buf, int len, const char *cmd) {
SDB_VISIBLE char *sdb_querys (Sdb *s, char *buf, size_t len, const char *cmd) {
const char *q;
char *p, *eq, *ask = strchr (cmd, '?');
int i, ok, w, alength;
ut64 n;
if (*cmd == '+' || *cmd == '-') {
n = (*cmd=='+')?(
ask? sdb_json_inc (s, cmd+1, ask, 1, 0):
sdb_inc (s, cmd+1, 1, 0)):(
ask? sdb_json_dec (s, cmd+1, ask, 1, 0):
sdb_dec (s, cmd+1, 1, 0));
w = snprintf (buf, sizeof (buf), "%"ULLFMT"d\n", n);
if (w>len) {
*buf = 0;
if (ask) {
*ask = 0;
if (*cmd=='+') n = sdb_json_inc (s, cmd+1, ask+1, 1, 0);
else n = sdb_json_dec (s, cmd+1, ask+1, 1, 0);
*ask = '?';
} else {
if (*cmd=='+') n = sdb_inc (s, cmd+1, 1, 0);
else n = sdb_dec (s, cmd+1, 1, 0);
}
w = snprintf (buf, sizeof (buf), "%"ULLFMT"d", n);
if (w<0 || (size_t)w>len) {
buf = malloc (64);
snprintf (buf, 64, "%"ULLFMT"d\n", n);
snprintf (buf, 64, "%"ULLFMT"d", n);
}
return buf;
} else if (*cmd == '(') {
@ -56,7 +62,7 @@ char *sdb_querys (Sdb *s, char *buf, int len, const char *cmd) {
if (cmd[1]=='?') {
alength = sdb_alength (s, p+1);
w = snprintf (buf, len, "%d", alength);
if (w>len) {
if (w<0 || (size_t)w>len) {
buf = malloc (32);
snprintf (buf, 32, "%d", alength);
}
@ -89,9 +95,10 @@ char *sdb_querys (Sdb *s, char *buf, int len, const char *cmd) {
}
} else {
const char *out = sdb_getc (s, p+1, 0);
size_t wl;
if (!out) return NULL;
w = strlen (out);
if (w>len) buf = malloc (w+2);
wl = strlen (out);
if (wl>len) buf = malloc (wl+2);
for (i=0; out[i]; i++)
buf[i] = out[i]==SDB_RS? '\n': out[i];
buf[i] = 0;
@ -122,10 +129,10 @@ char *sdb_querys (Sdb *s, char *buf, int len, const char *cmd) {
return p;
} else {
// sdbget
const char *p = sdb_getc (s, cmd, 0);
if (!p) return NULL;
if (strlen (p)> len) return strdup (p);
strcpy (buf, p);
if (!(q = sdb_getc (s, cmd, 0)))
return NULL;
if (strlen (q)> len) return strdup (q);
strcpy (buf, q);
return buf;
}
}
@ -133,7 +140,7 @@ char *sdb_querys (Sdb *s, char *buf, int len, const char *cmd) {
return NULL;
}
int sdb_query (Sdb *s, const char *cmd) {
SDB_VISIBLE int sdb_query (Sdb *s, const char *cmd) {
char buf[1024], *out = sdb_querys (s, buf, sizeof (buf), cmd);
if (!out) return 0;
if (*out) puts (out);

View File

@ -1 +1 @@
#define SDB_VERSION "0.6"
#define SDB_VERSION "0.6.1"

56
libr/db/sdb/src/sdb.1 Normal file
View File

@ -0,0 +1,56 @@
.Dd Mar 30, 2013
.Dt SDB 1
.Os
.Sh NAME
.Nm sdb
.Nd simple key-value database with json and arrays
.Sh SYNOPSIS
.Nm sdb
.Op Fl fhv
.Ar db
.Ar -=
.Ar [expr ..]
.Sh DESCRIPTION
SDB is a simple disk and memory string-based key-value database. It is based on CDB and uses
.Bl -tag -width Fl
.It Fl h
Show help message
.It Fl f
Show features string
.It Fl v
Show version
.El
.Sh EXAMPLES
Some useful ways to run it:
.Pp
$ sdb - ; in memory database
.Pp
$ sdb test.db = < test.txt ; create database from text file
.Pp
$ sdb test.db ; dump contents of database
.Pp
$ sdb test.db a=b a ; inline queries
.Pp
Append those quoted commands to 'sdb -' to test these sdb_query expressions:
.Pp
a=hello b=world a b # hello world
.Pp
a=1 +a -a # 2 1 ; key inc/dec
.Pp
a={"a":122} a?a=O a # {"a":0} ; json set
.Pp
a={"foo":122} +a?foo # 123 ; json increment
.Pp
()a=1,2,3,4,5 (?)a # 5 ; count array
.Pp
()a=1,2,3,4,5 (0)a # 1 ; get element
.Pp
()a=1,2 (0)a=X a # X2 ; replace
.Pp
()a=1,2 (+0)a=0 a # 012 ; prepend
.Pp
()a=1,2 (-1)a=3 a # 123 ; append
.Pp
.Sh AUTHORS
.Pp
pancake <pancake@nopcode.org>

View File

@ -1,4 +1,4 @@
/* Copyleft 2011-2013 - sdb - pancake */
/* sdb - LGPLv3 - Copyright 2011-2013 - pancake */
#include <stdio.h>
#include <string.h>
@ -21,7 +21,7 @@ static inline int nextcas() {
}
// TODO: use mmap instead of read.. much faster!
Sdb* sdb_new (const char *dir, int lock) {
SDB_VISIBLE Sdb* sdb_new (const char *dir, int lock) {
Sdb* s;
if (lock && !sdb_lock (sdb_lockfile (dir)))
return NULL;
@ -47,7 +47,7 @@ Sdb* sdb_new (const char *dir, int lock) {
return s;
}
void sdb_file (Sdb* s, const char *dir) {
SDB_VISIBLE void sdb_file (Sdb* s, const char *dir) {
if (s->lock)
sdb_unlock (sdb_lockfile (s->dir));
free (s->dir);
@ -56,7 +56,7 @@ void sdb_file (Sdb* s, const char *dir) {
sdb_lock (sdb_lockfile (s->dir));
}
void sdb_free (Sdb* s) {
SDB_VISIBLE void sdb_free (Sdb* s) {
if (!s) return;
cdb_free (&s->db);
if (s->lock)
@ -70,7 +70,7 @@ void sdb_free (Sdb* s) {
free (s);
}
const char *sdb_getc (Sdb* s, const char *key, ut32 *cas) {
SDB_VISIBLE const char *sdb_getc (Sdb* s, const char *key, ut32 *cas) {
ut32 hash, pos, len, keylen;
SdbKv *kv;
ut64 now = 0LL;
@ -110,7 +110,7 @@ const char *sdb_getc (Sdb* s, const char *key, ut32 *cas) {
return s->db.map+pos;
}
char *sdb_get (Sdb* s, const char *key, ut32 *cas) {
SDB_VISIBLE char *sdb_get (Sdb* s, const char *key, ut32 *cas) {
char *buf;
ut32 hash, pos, len, keylen;
SdbKv *kv;
@ -156,18 +156,18 @@ char *sdb_get (Sdb* s, const char *key, ut32 *cas) {
return buf;
}
int sdb_remove (Sdb* s, const char *key, ut32 cas) {
SDB_VISIBLE int sdb_remove (Sdb* s, const char *key, ut32 cas) {
return key? sdb_set (s, key, "", cas): 0;
}
// set if not defined
int sdb_add (Sdb *s, const char *key, const char *val, ut32 cas) {
SDB_VISIBLE int sdb_add (Sdb *s, const char *key, const char *val, ut32 cas) {
if (sdb_exists (s, key))
return 0;
return sdb_set (s, key, val, cas);
}
int sdb_exists (Sdb* s, const char *key) {
SDB_VISIBLE int sdb_exists (Sdb* s, const char *key) {
char ch;
SdbKv *kv;
int klen = strlen (key);
@ -185,14 +185,14 @@ int sdb_exists (Sdb* s, const char *key) {
return 0;
}
void sdb_reset (Sdb *s) {
SDB_VISIBLE void sdb_reset (Sdb *s) {
ht_free (s->ht);
s->ht = ht_new ();
}
// TODO: too many allocs here. use slices
struct sdb_kv* sdb_kv_new (const char *k, const char *v) {
struct sdb_kv *kv = R_NEW (struct sdb_kv);
SdbKv* sdb_kv_new (const char *k, const char *v) {
SdbKv *kv = R_NEW (struct sdb_kv);
strncpy (kv->key, k, sizeof (kv->key)-1);
strncpy (kv->value, v, sizeof (kv->value)-1);
kv->cas = nextcas ();
@ -200,11 +200,11 @@ struct sdb_kv* sdb_kv_new (const char *k, const char *v) {
return kv;
}
void sdb_kv_free (struct sdb_kv *kv) {
SDB_VISIBLE void sdb_kv_free (struct sdb_kv *kv) {
free (kv);
}
int sdb_set (Sdb* s, const char *key, const char *val, ut32 cas) {
SDB_VISIBLE int sdb_set (Sdb* s, const char *key, const char *val, ut32 cas) {
SdbHashEntry *e;
SdbKv *kv;
ut32 hash, klen;
@ -230,7 +230,7 @@ int sdb_set (Sdb* s, const char *key, const char *val, ut32 cas) {
return *val? kv->cas: 0;
}
int sdb_sync (Sdb* s) {
SDB_VISIBLE int sdb_sync (Sdb* s) {
SdbKv *kv;
SdbListIter it, *iter;
char k[SDB_KSZ];
@ -285,7 +285,7 @@ static int getbytes(int fd, char *b, int len) {
return len;
}
void sdb_dump_begin (Sdb* s) {
SDB_VISIBLE void sdb_dump_begin (Sdb* s) {
if (s->fd != -1) {
seek_set (s->fd, 0);
eod = getnum (s->fd);
@ -296,7 +296,7 @@ void sdb_dump_begin (Sdb* s) {
// XXX: overflow if caller doesnt respects sizes
// TODO: add support for readonly dump next here
int sdb_dump_next (Sdb* s, char *key, char *value) {
SDB_VISIBLE int sdb_dump_next (Sdb* s, char *key, char *value) {
ut32 dlen, klen;
if (s->fd==-1 || !getkvlen (s->fd, &klen, &dlen))
return 0;
@ -311,13 +311,13 @@ int sdb_dump_next (Sdb* s, char *key, char *value) {
return 0;
}
ut64 sdb_now () {
SDB_VISIBLE ut64 sdb_now () {
struct timeval now;
gettimeofday (&now, NULL);
return now.tv_sec;
}
ut64 sdb_unow () {
SDB_VISIBLE ut64 sdb_unow () {
ut64 x;
struct timeval now;
gettimeofday (&now, NULL);
@ -333,7 +333,7 @@ static ut64 parse_expire (ut64 e) {
return e;
}
int sdb_expire(Sdb* s, const char *key, ut64 expire) {
SDB_VISIBLE int sdb_expire(Sdb* s, const char *key, ut64 expire) {
char *buf;
ut32 hash, pos, len;
SdbKv *kv;
@ -366,7 +366,7 @@ int sdb_expire(Sdb* s, const char *key, ut64 expire) {
return sdb_expire (s, key, expire); // recursive
}
ut64 sdb_get_expire(Sdb* s, const char *key) {
SDB_VISIBLE ut64 sdb_get_expire(Sdb* s, const char *key) {
SdbKv *kv;
ut32 hash = sdb_hash (key, 0);
kv = (SdbKv*)ht_lookup (s->ht, hash);
@ -375,17 +375,7 @@ ut64 sdb_get_expire(Sdb* s, const char *key) {
return 0LL;
}
ut32 sdb_hash(const char *s, int len) {
ut32 h = CDB_HASHSTART;
if (len<1) len = strlen (s)+1; // XXX slow
while (len--) {
h += (h<<5);
h ^= *s++;
}
return h;
}
void sdb_flush(Sdb* s) {
SDB_VISIBLE void sdb_flush(Sdb* s) {
ht_free (s->ht);
s->ht = ht_new ();
close (s->fd);
@ -393,7 +383,7 @@ void sdb_flush(Sdb* s) {
}
/* sdb-create api */
int sdb_create (Sdb *s) {
SDB_VISIBLE int sdb_create (Sdb *s) {
int nlen;
char *str;
if (!s || !s->dir || s->fdump != -1) return 0; // cannot re-create
@ -412,14 +402,14 @@ int sdb_create (Sdb *s) {
return 1;
}
int sdb_append (Sdb *s, const char *key, const char *val) {
SDB_VISIBLE int sdb_append (Sdb *s, const char *key, const char *val) {
struct cdb_make *c = &s->m;
if (!key || !val) return 0;
//if (!*val) return 0; //undefine variable if no value
return cdb_make_add (c, key, strlen (key)+1, val, strlen (val)+1);
}
int sdb_finish (Sdb *s) {
SDB_VISIBLE int sdb_finish (Sdb *s) {
cdb_make_finish (&s->m);
#if USE_MMAN
fsync (s->fdump);

View File

@ -1,6 +1,12 @@
#ifndef _INCLUDE_SDB_H_
#define _INCLUDE_SDB_H_
#if defined(__GNUC__)
#define SDB_VISIBLE __attribute__((visibility("default")))
#else
#define SDB_VISIBLE
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -55,8 +61,8 @@ void sdb_reset (Sdb *s);
int sdb_query (Sdb *s, const char *cmd);
int sdb_queryf (Sdb *s, const char *fmt, ...);
char *sdb_querys (Sdb *s, char *buf, int len, const char *cmd);
char *sdb_querysf (Sdb *s, char *buf, int buflen, const char *fmt, ...);
char *sdb_querys (Sdb *s, char *buf, size_t len, const char *cmd);
char *sdb_querysf (Sdb *s, char *buf, size_t buflen, const char *fmt, ...);
int sdb_exists (Sdb*, const char *key);
int sdb_nexists (Sdb*, const char *key);
int sdb_remove (Sdb*, const char *key, ut32 cas);
@ -93,8 +99,8 @@ void sdb_unlock(const char *s);
int sdb_expire(Sdb* s, const char *key, ut64 expire);
ut64 sdb_get_expire(Sdb* s, const char *key);
// int sdb_get_cas(Sdb* s, const char *key) -> takes no sense at all..
ut64 sdb_now ();
ut64 sdb_unow ();
ut64 sdb_now (void);
ut64 sdb_unow (void);
ut32 sdb_hash (const char *key, int klen);
#define sdb_hashstr(x) sdb_hash(x,strlen(x))
@ -112,8 +118,8 @@ char *sdb_json_unindent(const char *s);
typedef struct {
char *buf;
int blen;
int len;
size_t blen;
size_t len;
} SdbJsonString;
const char *sdb_json_format(SdbJsonString* s, const char *fmt, ...);
@ -131,7 +137,6 @@ char *sdb_aget(Sdb *s, const char *key, int idx, ut32 *cas);
int sdb_ains(Sdb *s, const char *key, int idx, const char *val, ut32 cas);
int sdb_adel(Sdb *s, const char *key, int n, ut32 cas);
// helpers
const char *sdb_anext(const char *str);
char *sdb_astring(char *str, int *hasnext);
int sdb_alen(const char *str);
int sdb_alength(Sdb *s, const char *key);

View File

@ -1,26 +1,37 @@
/* Copyleft 2011-2013 - sdb - pancake */
/* sdb - LGPLv3 - Copyright 2011-2013 - pancake */
#include "sdb.h"
const char *sdb_anext(const char *str) {
static char *sdb_aindex_nc(char *str, int idx) {
int len = 0;
char *n, *p = str;
for (len=0; ; len++) {
if (len == idx)
return p;
n = strchr (p, SDB_RS);
if (n) p = n+1;
else break;
}
return NULL;
}
SDB_VISIBLE const char *sdb_anext(const char *str) {
return str+strlen (str)+1;
}
char *sdb_astring(char *str, int *hasnext) {
SDB_VISIBLE char *sdb_astring(char *str, int *hasnext) {
int nxt = 0;
char *p = strchr (str, SDB_RS);
if (!p) {
if (hasnext) *hasnext = 0;
return str;
}
*p = 0;
if (hasnext) *hasnext = 1;
if (p) { *p = 0; nxt = 1; }
if (hasnext) *hasnext = nxt;
return str;
}
char *sdb_aget(Sdb *s, const char *key, int idx, ut32 *cas) {
SDB_VISIBLE char *sdb_aget(Sdb *s, const char *key, int idx, ut32 *cas) {
const char *str = sdb_getc (s, key, 0); // XXX cas
const char *p = str;
char *o, *n;
int i, len;
const char *str = sdb_getc (s, key, cas);
char *o, *n, *p = (char*)str;
if (!str || !*str) return NULL;
if (idx==0) {
n = strchr (str, SDB_RS);
@ -47,7 +58,7 @@ char *sdb_aget(Sdb *s, const char *key, int idx, ut32 *cas) {
}
// TODO: done, but there's room for improvement
int sdb_ains(Sdb *s, const char *key, int idx, const char *val, ut32 cas) {
SDB_VISIBLE int sdb_ains(Sdb *s, const char *key, int idx, const char *val, ut32 cas) {
const char *str = sdb_getc (s, key, 0);
int lnstr, lstr, lval, ret;
char *x, *ptr, *nstr = NULL;
@ -66,7 +77,7 @@ int sdb_ains(Sdb *s, const char *key, int idx, const char *val, ut32 cas) {
memcpy (x+lval+1, str, lstr+1);
} else {
nstr = strdup (str);
ptr = (char*)sdb_aindex (nstr, idx);
ptr = sdb_aindex_nc (nstr, idx);
if (ptr) {
*(ptr-1) = 0;
lnstr = strlen (nstr);
@ -84,7 +95,7 @@ int sdb_ains(Sdb *s, const char *key, int idx, const char *val, ut32 cas) {
}
// set/replace
int sdb_aset(Sdb *s, const char *key, int idx, const char *val, ut32 cas) {
SDB_VISIBLE int sdb_aset(Sdb *s, const char *key, int idx, const char *val, ut32 cas) {
char *nstr, *ptr;
const char *usr, *str = sdb_getc (s, key, 0);
int lval, len, ret = 0;
@ -94,7 +105,7 @@ int sdb_aset(Sdb *s, const char *key, int idx, const char *val, ut32 cas) {
if (idx<0 || idx>len) // append
return sdb_ains (s, key, -1, val, cas);
nstr = strdup (str);
ptr = (char *)sdb_aindex (nstr, idx);
ptr = sdb_aindex_nc (nstr, idx);
if (ptr) {
lval = strlen (val);
memcpy (ptr, val, lval+1);
@ -109,7 +120,7 @@ int sdb_aset(Sdb *s, const char *key, int idx, const char *val, ut32 cas) {
return ret;
}
int sdb_adel(Sdb *s, const char *key, int idx, ut32 cas) {
SDB_VISIBLE int sdb_adel(Sdb *s, const char *key, int idx, ut32 cas) {
int i;
char *p, *n, *str = sdb_get (s, key, 0);
p = str;
@ -128,7 +139,7 @@ int sdb_adel(Sdb *s, const char *key, int idx, ut32 cas) {
return 1;
}
const char *sdb_aindex(const char *str, int idx) {
SDB_VISIBLE const char *sdb_aindex(const char *str, int idx) {
int len = 0;
const char *n, *p = str;
for (len=0; ; len++) {
@ -142,7 +153,7 @@ const char *sdb_aindex(const char *str, int idx) {
}
// TODO: make static inline?
int sdb_alen(const char *str) {
SDB_VISIBLE int sdb_alen(const char *str) {
int len = 1;
const char *n, *p = str;
if (!p|| !*p) return 0;
@ -155,14 +166,14 @@ int sdb_alen(const char *str) {
return len;
}
int sdb_alength(Sdb *s, const char *key) {
SDB_VISIBLE int sdb_alength(Sdb *s, const char *key) {
const char *str = sdb_getc (s, key, 0);
return sdb_alen (str);
}
#if 0
// XXX: totally unefficient. do not use, replace SDB_RS for '\n' may be enought
int sdb_alist(Sdb *s, const char *key) {
SDB_VISIBLE int sdb_alist(Sdb *s, const char *key) {
int len = 0, hasnext = 1;
char *list = sdb_get (s, key, 0);
char *ptr = list;

View File

@ -1,16 +1,8 @@
/* Copyleft 2011-2013 - sdb - pancake */
/* sdb - LGPLv3 - Copyright 2011-2013 - pancake */
#include "sdb.h"
#include "types.h"
int sdb_nexists (Sdb *s, const char *key) {
char c;
const char *o = sdb_getc (s, key, NULL);
if (!o) return 0;
c = *o;
return c>='0' && c<='9';
}
static void __strrev(char *s, int len) {
int i, j = len -1;
for (i=0; i<j; i++, j--) {
@ -28,7 +20,15 @@ static void __ulltoa(ut64 n, char *s) {
__strrev (s, i);
}
ut64 sdb_getn(Sdb *s, const char *key, ut32 *cas) {
SDB_VISIBLE int sdb_nexists (Sdb *s, const char *key) {
char c;
const char *o = sdb_getc (s, key, NULL);
if (!o) return 0;
c = *o;
return c>='0' && c<='9';
}
SDB_VISIBLE ut64 sdb_getn(Sdb *s, const char *key, ut32 *cas) {
ut64 n;
char *p;
const char *v = sdb_getc (s, key, cas);
@ -39,13 +39,13 @@ ut64 sdb_getn(Sdb *s, const char *key, ut32 *cas) {
return n;
}
int sdb_setn(Sdb *s, const char *key, ut64 v, ut32 cas) {
SDB_VISIBLE int sdb_setn(Sdb *s, const char *key, ut64 v, ut32 cas) {
char b[128];
__ulltoa (v, b);
return sdb_set (s, key, b, cas);
}
ut64 sdb_inc(Sdb *s, const char *key, ut64 n2, ut32 cas) {
SDB_VISIBLE ut64 sdb_inc(Sdb *s, const char *key, ut64 n2, ut32 cas) {
ut32 c;
ut64 n = sdb_getn (s, key, &c);
if (cas && c != cas) return 0LL;
@ -55,7 +55,7 @@ ut64 sdb_inc(Sdb *s, const char *key, ut64 n2, ut32 cas) {
return n;
}
ut64 sdb_dec(Sdb *s, const char *key, ut64 n2, ut32 cas) {
SDB_VISIBLE ut64 sdb_dec(Sdb *s, const char *key, ut64 n2, ut32 cas) {
ut32 c;
ut64 n = sdb_getn (s, key, &c);
if (cas && c != cas)

View File

@ -1,10 +1,26 @@
#ifndef UINT32_H
#define UINT32_H
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifndef __unused
#ifdef __GNUC__
#define __unused __attribute__((unused))
#else
#define __unused
#endif
#endif
#if __WIN32__ || __CYGWIN__ || MINGW32
#define WINDOWS 1
#else
#define WINDOWS 0
#endif
#ifndef ut8
#define ut8 unsigned char
#define ut32 unsigned int

14
libr/db/sdb/src/util.c Normal file
View File

@ -0,0 +1,14 @@
/* sdb - LGPLv3 - Copyright 2011-2013 - pancake */
#include "sdb.h"
// XXX: must be sdb_str_hash
SDB_VISIBLE ut32 sdb_hash(const char *s, int len) {
ut32 h = CDB_HASHSTART;
if (len<1) len = strlen (s)+1; // XXX slow
while (len--) {
h += (h<<5);
h ^= *s++;
}
return h;
}

View File

@ -1,8 +0,0 @@
#ifndef ALLOC_H
#define ALLOC_H
extern /*@null@*//*@out@*/char *alloc();
extern void alloc_free();
extern int alloc_re();
#endif

View File

@ -10,7 +10,7 @@ typedef struct buffer {
unsigned int p;
unsigned int n;
int fd;
int (*op)();
BufferOp op;
} buffer;
#define BUFFER_INIT(op,fd,buf,len) { (buf), 0, (len), (fd), (op) }

View File

@ -16,6 +16,10 @@
#define USE_MMAN 1
#endif
extern char *alloc(unsigned int n);
extern void alloc_free(void*);
extern int alloc_re(void);
/* TODO THIS MUST GTFO! */
int getkvlen(int fd, ut32 *klen, ut32 *vlen);
#define CDB_HASHSTART 5381

View File

@ -21,7 +21,7 @@ typedef struct ht_t {
SdbHash* ht_new(void);
void ht_free(SdbHash *ht);
void ht_set(SdbHash *ht, ut32 hash, void *data);
//void ht_set(SdbHash *ht, ut32 hash, void *data);
SdbHashEntry* ht_search(SdbHash *ht, ut32 hash);
void *ht_lookup(SdbHash *ht, ut32 hash);
void ht_set(SdbHash *ht, ut32 hash, void *data);

View File

@ -39,7 +39,7 @@ typedef int (*SdbListComparator)(void *a, void *b);
#define ls_iter_next(x) (x?1:0)
#define ls_iter_cur(x) x->p
#define ls_iter_unref(x) x
R_API SdbList *ls_new();
R_API SdbList *ls_new(void);
R_API SdbListIter *ls_append(SdbList *list, void *data);
R_API SdbListIter *ls_prepend(SdbList *list, void *data);
R_API int ls_length(SdbList *list);

View File

@ -1 +1 @@
#define SDB_VERSION "0.6"
#define SDB_VERSION "0.6.1"

View File

@ -1,6 +1,12 @@
#ifndef _INCLUDE_SDB_H_
#define _INCLUDE_SDB_H_
#if defined(__GNUC__)
#define SDB_VISIBLE __attribute__((visibility("default")))
#else
#define SDB_VISIBLE
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -55,8 +61,8 @@ void sdb_reset (Sdb *s);
int sdb_query (Sdb *s, const char *cmd);
int sdb_queryf (Sdb *s, const char *fmt, ...);
char *sdb_querys (Sdb *s, char *buf, int len, const char *cmd);
char *sdb_querysf (Sdb *s, char *buf, int buflen, const char *fmt, ...);
char *sdb_querys (Sdb *s, char *buf, size_t len, const char *cmd);
char *sdb_querysf (Sdb *s, char *buf, size_t buflen, const char *fmt, ...);
int sdb_exists (Sdb*, const char *key);
int sdb_nexists (Sdb*, const char *key);
int sdb_remove (Sdb*, const char *key, ut32 cas);
@ -93,8 +99,8 @@ void sdb_unlock(const char *s);
int sdb_expire(Sdb* s, const char *key, ut64 expire);
ut64 sdb_get_expire(Sdb* s, const char *key);
// int sdb_get_cas(Sdb* s, const char *key) -> takes no sense at all..
ut64 sdb_now ();
ut64 sdb_unow ();
ut64 sdb_now (void);
ut64 sdb_unow (void);
ut32 sdb_hash (const char *key, int klen);
#define sdb_hashstr(x) sdb_hash(x,strlen(x))
@ -112,8 +118,8 @@ char *sdb_json_unindent(const char *s);
typedef struct {
char *buf;
int blen;
int len;
size_t blen;
size_t len;
} SdbJsonString;
const char *sdb_json_format(SdbJsonString* s, const char *fmt, ...);
@ -131,7 +137,6 @@ char *sdb_aget(Sdb *s, const char *key, int idx, ut32 *cas);
int sdb_ains(Sdb *s, const char *key, int idx, const char *val, ut32 cas);
int sdb_adel(Sdb *s, const char *key, int n, ut32 cas);
// helpers
const char *sdb_anext(const char *str);
char *sdb_astring(char *str, int *hasnext);
int sdb_alen(const char *str);
int sdb_alength(Sdb *s, const char *key);

View File

@ -1,10 +1,26 @@
#ifndef UINT32_H
#define UINT32_H
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifndef __unused
#ifdef __GNUC__
#define __unused __attribute__((unused))
#else
#define __unused
#endif
#endif
#if __WIN32__ || __CYGWIN__ || MINGW32
#define WINDOWS 1
#else
#define WINDOWS 0
#endif
#ifndef ut8
#define ut8 unsigned char
#define ut32 unsigned int

View File

@ -16,6 +16,9 @@ CFLAGS_OPT2=-O2
CFLAGS_OPT3=-O3
CFLAGS_DEBUG=-g
ifeq ($(OSTYPE),auto)
OSTYPE=$(shell uname | tr 'A-Z' 'a-z')
endif
ifeq ($(OSTYPE),darwin)
ARCH=$(shell uname -m)
#CFLAGS+=-arch ${ARCH}
@ -29,6 +32,8 @@ LDFLAGS_LIB=-shared
#endif
LDFLAGS_SONAME=-Wl,-soname=
endif
# XXX
#LDFLAGS_SONAME=-D_
CC_LIB=${CC} ${LDFLAGS_LIB} -o ${LIBSO}
endif