[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