[elephant-cvs] CVS update: elephant/src/libsleepycat.c
blee at common-lisp.net
blee at common-lisp.net
Thu Sep 16 04:18:28 UTC 2004
Update of /project/elephant/cvsroot/elephant/src
In directory common-lisp.net:/tmp/cvs-serv25807/src
Modified Files:
libsleepycat.c
Log Message:
need to memcpy on writers (alignment)
lisp-cmp func, assoc / btree cmp stuff
cursor pget, remove key value using cursor
length->size
Date: Thu Sep 16 06:18:27 2004
Author: blee
Index: elephant/src/libsleepycat.c
diff -u elephant/src/libsleepycat.c:1.7 elephant/src/libsleepycat.c:1.8
--- elephant/src/libsleepycat.c:1.7 Thu Sep 2 16:45:53 2004
+++ elephant/src/libsleepycat.c Thu Sep 16 06:18:27 2004
@@ -39,40 +39,48 @@
;;; to the Free Software Foundation, Inc., 59 Temple Place,
;;; Suite 330, Boston, MA 02111-1307 USA
;;;
-8?
+*/
/* Pointer arithmetic utility functions */
-
+/* should these be in network-byte order? probably not..... */
int read_int(char *buf, int offset) {
- return *(int*)(buf + offset);
+ int i;
+ memcpy(&i, buf+offset, sizeof(int));
+ return i;
}
unsigned int read_uint(char *buf, int offset) {
- return *(unsigned int*)(buf + offset);
+ unsigned int ui;
+ memcpy(&ui, buf+offset, sizeof(unsigned int));
+ return ui;
}
float read_float(char *buf, int offset) {
- return *(float*)(buf + offset);
+ float f;
+ memcpy(&f, buf+offset, sizeof(float));
+ return f;
}
double read_double(char *buf, int offset) {
- return *(double*)(buf + offset);
+ double d;
+ memcpy(&d, buf+offset, sizeof(double));
+ return d;
}
void write_int(char *buf, int num, int offset) {
- *(int*)(buf + offset) = num;
+ memcpy(buf+offset, &num, sizeof(int));
}
void write_uint(char *buf, unsigned int num, int offset) {
- *(unsigned int*)(buf + offset) = num;
+ memcpy(buf+offset, &num, sizeof(unsigned int));
}
void write_float(char *buf, float num, int offset) {
- *(float*)(buf + offset) = num;
+ memcpy(buf+offset, &num, sizeof(float));
}
void write_double(char *buf, double num, int offset) {
- *(double*)(buf + offset) = num;
+ memcpy(buf+offset, &num, sizeof(double));
}
char *offset_charp(char *p, int offset) {
@@ -172,6 +180,14 @@
return db->truncate(db, txnid, countp, flags);
}
+int db_set_flags(DB *db, u_int32_t flags) {
+ return db->set_flags(db, flags);
+}
+
+int db_get_flags(DB *db, u_int32_t *flagsp) {
+ return db->get_flags(db, flagsp);
+}
+
int db_set_pagesize(DB *db, u_int32_t pagesize) {
return db->set_pagesize(db, pagesize);
}
@@ -180,54 +196,303 @@
return db->get_pagesize(db, pagesizep);
}
+int db_set_bt_compare(DB *db,
+ int (*bt_compare_fcn)(DB *db, const DBT *dbt1,
+ const DBT *dbt2)) {
+ return db->set_bt_compare(db, bt_compare_fcn);
+}
+
+int db_set_dup_compare(DB *db,
+ int (*dup_compare_fcn)(DB *db, const DBT *dbt1,
+ const DBT *dbt2)) {
+ return db->set_dup_compare(db, dup_compare_fcn);
+}
+
+#define type_numeric(c) ((c)<8)
+#include <math.h>
+
+double read_num(char *buf);
+
+/* Inspired by the Sleepycat docs. We have to memcpy to
+ insure memory alignment. */
+int lisp_compare(DB *dbp, const DBT *a, const DBT *b) {
+ int difference;
+ double ddifference;
+ char *ad, *bd, at, bt;
+ ad = (char*)a->data;
+ bd = (char*)b->data;
+
+ /* Compare OIDs. */
+ difference = read_int(ad, 0) - read_int(bd, 0);
+ if (difference) return difference;
+
+ /* Have a type tag? */
+ if (a->size == 4)
+ if (b->size == 4)
+ return 0;
+ else
+ return -1;
+ else if (b->size == 4)
+ return 1;
+
+ at = ad[4]; bt = bd[4];
+
+ /* Compare numerics. */
+ if (type_numeric(at) && type_numeric(bt)) {
+ ddifference = read_num(ad+4) - read_num(bd+4);
+ if (ddifference > 0) return 1;
+ else if (ddifference < 0) return -1;
+ return 0;
+ }
+
+ /* Compare types. */
+ difference = at - bt;
+ if (difference) return difference;
+
+ /* Same type! */
+ switch (at) {
+ case 8: /* nil */
+ return 0;
+ case 9: /* 8-bit symbol */
+ case 10: /* 8-bit string */
+ case 11: /* 8-bit pathname */
+ return case_cmp(ad+9, read_int(ad, 5), bd+9, read_int(bd, 5));
+ case 12: /* 16-bit symbol */
+ case 13: /* 16-bit string */
+ case 14: /* 16-bit pathname */
+ return utf16_cmp(ad+9, read_int(ad, 5), bd+9, read_int(bd, 5));
+ default:
+ return lex_cmp(ad+5, (a->size)-5, bd+5, (b->size)-5);
+ }
+}
+
+int db_set_lisp_compare(DB *db) {
+ return db->set_bt_compare(db, &lisp_compare);
+}
+
+int db_set_lisp_dup_compare(DB *db) {
+ return db->set_dup_compare(db, &lisp_compare);
+}
+
+#ifndef exp2
+#define exp2(c) (pow(2,(c)))
+#endif
+
+double read_num(char *buf) {
+ char *limit;
+ double i, result, denom;
+ switch (buf[0]) {
+ case 1:
+ case 2:
+ return (double)read_int(buf, 1);
+ case 3:
+ return (double)read_float(buf, 1);
+ case 4:
+ return read_double(buf, 1);
+ case 5:
+ result = 0;
+ buf += 5;
+ limit = buf + read_uint(buf, -4);
+ for(i=0 ; buf < limit; i++, buf = buf+4) {
+ result -= exp2(i*32) * read_uint(buf, 0);
+ }
+ return result;
+ case 6:
+ result = 0;
+ buf += 5;
+ limit = buf + read_uint(buf, -4);
+ for(i=0 ; buf < limit; i++, buf = buf+4) {
+ result += exp2(i*32) * read_uint(buf, 0);
+ }
+ return result;
+ case 7:
+ switch ((++buf)[0]) {
+ case 1:
+ result = (double)read_int(++buf, 0);
+ buf += 4;
+ break;
+ case 5:
+ result = 0;
+ buf += 5;
+ limit = buf + read_uint(buf, -4);
+ for(i=0 ; buf < limit; i++, buf = buf+4) {
+ result -= exp2(i*32) - read_uint(buf, 0);
+ }
+ break;
+ case 6:
+ result = 0;
+ buf += 5;
+ limit = buf + read_uint(buf, -4);
+ for(i=0 ; buf < limit; i++, buf = buf+4) {
+ result += exp2(i*32) * read_uint(buf, 0);
+ }
+ break;
+ }
+
+ switch (buf[0]) {
+ case 1:
+ return result / read_int(++buf, 0);
+ case 5:
+ denom = 0;
+ buf += 5;
+ limit = buf + read_uint(buf, -4);
+ for(i=0 ; buf < limit; i++, buf = buf+4) {
+ denom -= exp2(i*32) * read_uint(buf, 0);
+ }
+ return result / denom;
+ case 6:
+ denom = 0;
+ buf += 5;
+ limit = buf + read_uint(buf, -4);
+ for(i=0 ; buf < limit; i++, buf = buf+4) {
+ denom += exp2(i*32) * read_uint(buf, 0);
+ }
+ return result / denom;
+ }
+ }
+}
+
+int case_cmp(const char *a, int32_t length1, const char *b, int32_t length2) {
+ int min, sizediff, diff;
+ sizediff = length1 - length2;
+ min = sizediff > 0 ? length2 : length1;
+ diff = strncasecmp(a, b, min);
+ if (diff == 0) return sizediff;
+ return diff;
+}
+
+int lex_cmp(const char *a, int32_t length1, const char *b, int32_t length2) {
+ int min, sizediff, diff;
+ sizediff = length1 - length2;
+ min = sizediff > 0 ? length2 : length1;
+ diff = memcmp(a, b, min);
+ if (diff == 0) return sizediff;
+ return diff;
+}
+/* The following is copied from
+ http://oss.software.ibm.com/cvs/icu/~checkout~/icu/source/common/ustring.c
+*/
+typedef uint16_t UChar;
+
+#define UTF_IS_LEAD(c) (((c)&0xfffffc00)==0xd800)
+#define UTF_IS_TRAIL(c) (((c)&0xfffffc00)==0xdc00)
+
+/* compare UTF-16 strings */
+/* memcmp/UnicodeString style, both length-specified */
+/* don't assume byte-aligned! */
+int utf16_cmp(const char *s1, int32_t length1,
+ const char *s2, int32_t length2) {
+ const char *start1, *start2, *limit1, *limit2;
+ UChar c1, c2;
+ int32_t lengthResult;
+
+ if(length1<length2) {
+ lengthResult=-1;
+ limit1=s1+length1;
+ } else if(length1==length2) {
+ lengthResult=0;
+ limit1=s1+length1;
+ } else /* length1>length2 */ {
+ lengthResult=1;
+ limit1=s1+length2;
+ }
+
+ if(s1==s2) return lengthResult;
+
+ start1=s1;
+ start2=s2;
+
+ for(;;) {
+ if(s1==limit1) return lengthResult;
+
+ memcpy(&c1, s1, sizeof(UChar));
+ memcpy(&c2, s2, sizeof(UChar));
+ if(c1!=c2) break;
+
+ s1 = s1 + 2;
+ s2 = s2 + 2;
+ }
+
+ limit1=start1+length1;
+ limit2=start2+length2;
+
+ if(c1>=0xd800 && c2>=0xd800) {
+ if(c1>=0xe000)
+ c1-=0x800;
+ else
+ c1+=0x2000;
+
+ if(c2>=0xe000)
+ c2-=0x800;
+ else
+ c2+=0x2000;
+
+ /* here's some newer code which i can't make work
+ if((c1<=0xdbff && (s1+1)!=limit1 && UTF_IS_TRAIL(*(s1+1))) ||
+ (UTF_IS_TRAIL(c1) && start1!=s1 && UTF_IS_LEAD(*(s1-1)))) {
+ } else {
+ c1-=0x2800;
+ }
+
+ if((c2<=0xdbff && (s2+1)!=limit2 && UTF_IS_TRAIL(*(s2+1))) ||
+ (UTF_IS_TRAIL(c2) && start2!=s2 && UTF_IS_LEAD(*(s2-1)))) {
+ } else {
+ c2-=0x2800;
+ }*/
+ }
+
+ return (int32_t)c1-(int32_t)c2;
+}
+
+
/* Accessors */
/* We manage our own buffers (DB_DBT_USERMEM). */
int db_get_raw(DB *db, DB_TXN *txnid,
- char *key, u_int32_t key_length,
+ char *key, u_int32_t key_size,
char *buffer, u_int32_t buffer_length,
- u_int32_t flags, u_int32_t *result_length) {
- DBT DBTKey, DBTDatum;
+ u_int32_t flags, u_int32_t *result_size) {
+ DBT DBTKey, DBTValue;
int ret;
memset(&DBTKey, 0, sizeof(DBT));
- memset(&DBTDatum, 0, sizeof(DBT));
+ memset(&DBTValue, 0, sizeof(DBT));
DBTKey.data = key;
- DBTKey.size = key_length;
- DBTDatum.data = buffer;
- DBTDatum.ulen = buffer_length;
- DBTDatum.flags |= DB_DBT_USERMEM;
+ DBTKey.size = key_size;
+ DBTValue.data = buffer;
+ DBTValue.ulen = buffer_length;
+ DBTValue.flags |= DB_DBT_USERMEM;
- ret = db->get(db, txnid, &DBTKey, &DBTDatum, flags);
- *result_length = DBTDatum.size;
+ ret = db->get(db, txnid, &DBTKey, &DBTValue, flags);
+ *result_size = DBTValue.size;
return ret;
}
int db_put_raw(DB *db, DB_TXN *txnid,
- char *key, u_int32_t key_length,
- char *datum, u_int32_t datum_length,
+ char *key, u_int32_t key_size,
+ char *value, u_int32_t value_size,
u_int32_t flags) {
- DBT DBTKey, DBTDatum;
+ DBT DBTKey, DBTValue;
memset(&DBTKey, 0, sizeof(DBT));
- memset(&DBTDatum, 0, sizeof(DBT));
+ memset(&DBTValue, 0, sizeof(DBT));
DBTKey.data = key;
- DBTKey.size = key_length;
- DBTDatum.data = datum;
- DBTDatum.size = datum_length;
+ DBTKey.size = key_size;
+ DBTValue.data = value;
+ DBTValue.size = value_size;
- return db->put(db, txnid, &DBTKey, &DBTDatum, flags);
+ return db->put(db, txnid, &DBTKey, &DBTValue, flags);
}
int db_del(DB *db, DB_TXN *txnid,
- char *key, u_int32_t key_length,
+ char *key, u_int32_t key_size,
u_int32_t flags) {
DBT DBTKey;
memset(&DBTKey, 0, sizeof(DBT));
DBTKey.data = key;
- DBTKey.size = key_length;
+ DBTKey.size = key_size;
return db->del(db, txnid, &DBTKey, flags);
}
@@ -255,72 +520,148 @@
}
int db_cursor_get_raw(DBC *cursor,
- char *keybuf, u_int32_t keybuf_length,
- char *buffer, u_int32_t buffer_length,
- u_int32_t flags, u_int32_t *key_length,
- u_int32_t *result_length) {
- DBT DBTKey, DBTDatum;
+ char *keybuf, u_int32_t keybuf_size,
+ u_int32_t keybuf_length,
+ char *buffer, u_int32_t buffer_size,
+ u_int32_t buffer_length,
+ u_int32_t flags, u_int32_t *ret_key_size,
+ u_int32_t *result_size) {
+ DBT DBTKey, DBTValue;
+ int ret;
+
+ memset(&DBTKey, 0, sizeof(DBT));
+ memset(&DBTValue, 0, sizeof(DBT));
+ DBTKey.data = keybuf;
+ DBTKey.size = keybuf_size;
+ DBTKey.ulen = keybuf_length;
+ DBTKey.flags |= DB_DBT_USERMEM;
+ DBTValue.data = buffer;
+ DBTValue.size = buffer_size;
+ DBTValue.ulen = buffer_length;
+ DBTValue.flags |= DB_DBT_USERMEM;
+
+ ret = cursor->c_get(cursor, &DBTKey, &DBTValue, flags);
+ *ret_key_size = DBTKey.size;
+ *result_size = DBTValue.size;
+
+ return ret;
+}
+
+int db_cursor_pget_raw(DBC *cursor,
+ char *keybuf, u_int32_t keybuf_size,
+ u_int32_t keybuf_length,
+ char *pkeybuf, u_int32_t pkeybuf_size,
+ u_int32_t pkeybuf_length,
+ char *buffer, u_int32_t buffer_size,
+ u_int32_t buffer_length,
+ u_int32_t flags,
+ u_int32_t *ret_key_size,
+ u_int32_t *ret_pkey_size,
+ u_int32_t *result_size) {
+ DBT DBTKey, DBTPKey, DBTValue;
int ret;
memset(&DBTKey, 0, sizeof(DBT));
- memset(&DBTDatum, 0, sizeof(DBT));
+ memset(&DBTPKey, 0, sizeof(DBT));
+ memset(&DBTValue, 0, sizeof(DBT));
DBTKey.data = keybuf;
+ DBTKey.size = keybuf_size;
DBTKey.ulen = keybuf_length;
DBTKey.flags |= DB_DBT_USERMEM;
- DBTDatum.data = buffer;
- DBTDatum.ulen = buffer_length;
- DBTDatum.flags |= DB_DBT_USERMEM;
-
- ret = cursor->c_get(cursor, &DBTKey, &DBTDatum, flags);
- *key_length = DBTKey.size;
- *result_length = DBTDatum.size;
+ DBTPKey.data = pkeybuf;
+ DBTPKey.size = pkeybuf_size;
+ DBTPKey.ulen = pkeybuf_length;
+ DBTPKey.flags |= DB_DBT_USERMEM;
+ DBTValue.data = buffer;
+ DBTValue.size = buffer_size;
+ DBTValue.ulen = buffer_length;
+ DBTValue.flags |= DB_DBT_USERMEM;
+
+ ret = cursor->c_pget(cursor, &DBTKey, &DBTPKey, &DBTValue, flags);
+ *ret_key_size = DBTKey.size;
+ *ret_pkey_size = DBTPKey.size;
+ *result_size = DBTValue.size;
return ret;
}
int db_cursor_put_raw(DBC *cursor,
- char *key, u_int32_t key_length,
- char *datum, u_int32_t datum_length,
+ char *key, u_int32_t key_size,
+ char *value, u_int32_t value_size,
u_int32_t flags) {
- DBT DBTKey, DBTDatum;
+ DBT DBTKey, DBTValue;
memset(&DBTKey, 0, sizeof(DBT));
- memset(&DBTDatum, 0, sizeof(DBT));
+ memset(&DBTValue, 0, sizeof(DBT));
DBTKey.data = key;
- DBTKey.size = key_length;
- DBTDatum.data = datum;
- DBTDatum.size = datum_length;
+ DBTKey.size = key_size;
+ DBTValue.data = value;
+ DBTValue.size = value_size;
- return cursor->c_put(cursor, &DBTKey, &DBTDatum, flags);
+ return cursor->c_put(cursor, &DBTKey, &DBTValue, flags);
}
+/* Silently does nothing if the key/value isn't found.
+ Can't use auto-commit here! */
+int db_del_kv(DB *db, DB_TXN *tid,
+ char *key, u_int32_t key_size,
+ char *value, u_int32_t value_size) {
+ DBT DBTKey, DBTValue;
+ DBC *cursor;
+ int ret, c_ret;
+
+ memset(&DBTKey, 0, sizeof(DBT));
+ DBTKey.data = key;
+ DBTKey.size = key_size;
+ memset(&DBTValue, 0, sizeof(DBT));
+ DBTValue.data = value;
+ DBTValue.size = value_size;
+
+ if ((ret = db->cursor(db, tid, &cursor, 0)) != 0)
+ return ret;
+
+ if ((ret = cursor->c_get(cursor, &DBTKey, &DBTValue, DB_GET_BOTH)) != 0)
+ goto fail;
+
+ ret = cursor->c_del(cursor, 0);
+
+ fail:
+ if ((c_ret = cursor->c_close(cursor)) != 0)
+ return c_ret;
+ return ret;
+}
+
/* Bulk retrieval */
int db_cursor_get_multiple_key(DBC *cursor,
- char *keybuf, u_int32_t keybuf_length,
- char *buffer, u_int32_t buffer_length,
- u_int32_t flags, u_int32_t *key_length,
- u_int32_t *result_length,
+ char *keybuf, u_int32_t keybuf_size,
+ u_int32_t keybuf_length,
+ char *buffer, u_int32_t buffer_size,
+ u_int32_t buffer_length,
+ u_int32_t flags, u_int32_t *ret_key_size,
+ u_int32_t *result_size,
void **pointer, DBT **data) {
- DBT DBTKey, DBTDatum;
+ DBT DBTKey, DBTValue;
int ret;
memset(&DBTKey, 0, sizeof(DBT));
- memset(&DBTDatum, 0, sizeof(DBT));
+ memset(&DBTValue, 0, sizeof(DBT));
DBTKey.data = keybuf;
+ DBTKey.size = keybuf_size;
DBTKey.ulen = keybuf_length;
DBTKey.flags |= DB_DBT_USERMEM;
- DBTDatum.data = buffer;
- DBTDatum.ulen = buffer_length;
- DBTDatum.flags |= DB_DBT_USERMEM;
+ DBTValue.data = buffer;
+ DBTValue.size = buffer_size;
+ DBTValue.ulen = buffer_length;
+ DBTValue.flags |= DB_DBT_USERMEM;
flags |= DB_MULTIPLE_KEY;
- ret = cursor->c_get(cursor, &DBTKey, &DBTDatum, flags);
- *key_length = DBTKey.size;
- *result_length = DBTDatum.size;
- if ((DBTKey.size <= DBTKey.ulen) && (DBTDatum.size <= DBTDatum.ulen)) {
- **data = DBTDatum;
+ ret = cursor->c_get(cursor, &DBTKey, &DBTValue, flags);
+ *ret_key_size = DBTKey.size;
+ *result_size = DBTValue.size;
+ if ((DBTKey.size <= DBTKey.ulen) && (DBTValue.size <= DBTValue.ulen)) {
+ **data = DBTValue;
DB_MULTIPLE_INIT(*pointer, *data);
}
@@ -328,11 +669,11 @@
}
void db_multiple_key_next(void *pointer, DBT *data,
- char **key, u_int32_t *key_length,
- char **result, u_int32_t *result_length) {
+ char **key, u_int32_t *ret_key_size,
+ char **result, u_int32_t *result_size) {
DB_MULTIPLE_KEY_NEXT(pointer, data,
- *key, *key_length,
- *result, *result_length);
+ *key, *ret_key_size,
+ *result, *result_size);
}
/* Transactions */
@@ -373,12 +714,12 @@
}
int db_env_lock_get(DB_ENV *env, u_int32_t locker,
- u_int32_t flags, char *object, u_int32_t object_length,
+ u_int32_t flags, char *object, u_int32_t object_size,
const db_lockmode_t lock_mode, DB_LOCK *lock) {
DBT DBTObject;
memset(&DBTObject, 0, sizeof(DBT));
DBTObject.data = object;
- DBTObject.size = object_length;
+ DBTObject.size = object_size;
return env->lock_get(env, locker, flags, &DBTObject, lock_mode, lock);
}
@@ -414,11 +755,28 @@
return env->lock_detect(env, flags, atype, aborted);
}
+/* Secondary indices */
+
+int db_associate(DB *primary, DB_TXN *txnid, DB *secondary,
+ int (*callback)(DB *, const DBT *, const DBT *, DBT *),
+ u_int32_t flags) {
+ return primary->associate(primary, txnid, secondary, callback, flags);
+}
+
+int never_index(DB *db, const DBT *key, const DBT *data, DBT *result) {
+ return DB_DONOTINDEX;
+}
+
+int db_fake_associate(DB *primary, DB_TXN *txnid, DB *secondary,
+ u_int32_t flags) {
+ return primary->associate(primary, txnid, secondary, &never_index, flags);
+}
+
/* Poor man's counters */
int next_counter(DB_ENV *env, DB *db, DB_TXN *parent,
- char *key, u_int32_t key_length,
- char *lockid, u_int32_t lockid_length) {
+ char *key, u_int32_t key_size,
+ char *lockid, u_int32_t lockid_size) {
DB_LOCK lock;
DBT DBTKey, DBTData;
DB_TXN *tid;
@@ -430,9 +788,9 @@
memset(&DBTKey, 0, sizeof(DBTKey));
memset(&DBTData, 0, sizeof(DBTData));
DBTKey.data = key;
- DBTKey.size = key_length;
+ DBTKey.size = key_size;
DBTData.data = lockid;
- DBTData.size = lockid_length;
+ DBTData.size = lockid_size;
tries = 0;
More information about the Elephant-cvs
mailing list