svn commit: samba r21445 - in branches: SAMBA_3_0/source/tdb/common SAMBA_3_0_25/source/tdb/common SAMBA_3_0_25/source/tdb/include SAMBA_4_0/source/lib/tdb/common SAMBA_4_0/source/lib/tdb/include

vlendec at samba.org vlendec at samba.org
Mon Feb 19 11:45:33 GMT 2007


Author: vlendec
Date: 2007-02-19 11:45:33 +0000 (Mon, 19 Feb 2007)
New Revision: 21445

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=21445

Log:
Apply tdb_parse_record Tridges error return, merge to 3_0_25 and 4_0
Modified:
   branches/SAMBA_3_0/source/tdb/common/tdb.c
   branches/SAMBA_3_0_25/source/tdb/common/io.c
   branches/SAMBA_3_0_25/source/tdb/common/tdb.c
   branches/SAMBA_3_0_25/source/tdb/common/tdb_private.h
   branches/SAMBA_3_0_25/source/tdb/include/tdb.h
   branches/SAMBA_4_0/source/lib/tdb/common/io.c
   branches/SAMBA_4_0/source/lib/tdb/common/tdb.c
   branches/SAMBA_4_0/source/lib/tdb/common/tdb_private.h
   branches/SAMBA_4_0/source/lib/tdb/include/tdb.h


Changeset:
Modified: branches/SAMBA_3_0/source/tdb/common/tdb.c
===================================================================
--- branches/SAMBA_3_0/source/tdb/common/tdb.c	2007-02-19 11:19:53 UTC (rev 21444)
+++ branches/SAMBA_3_0/source/tdb/common/tdb.c	2007-02-19 11:45:33 UTC (rev 21445)
@@ -183,19 +183,14 @@
 {
 	tdb_off_t rec_ptr;
 	struct list_struct rec;
-	TDB_DATA data;
 	int ret;
 	u32 hash;
 
 	/* find which hash bucket it is in */
 	hash = tdb->hash_fn(&key);
 
-	rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec);
-
-	if (rec_ptr == 0) {
-		data.dptr = NULL;
-		data.dsize = 0;
-		return parser(key, data, private_data);
+	if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) {
+		return TDB_ERRCODE(TDB_ERR_NOEXIST, 0);
 	}
 
 	ret = tdb_parse_data(tdb, key, rec_ptr + sizeof(rec) + rec.key_len,
@@ -204,9 +199,7 @@
 	tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK);
 
 	return ret;
-	
 }
-		     
 
 /* check if an entry in the database exists 
 

Modified: branches/SAMBA_3_0_25/source/tdb/common/io.c
===================================================================
--- branches/SAMBA_3_0_25/source/tdb/common/io.c	2007-02-19 11:19:53 UTC (rev 21444)
+++ branches/SAMBA_3_0_25/source/tdb/common/io.c	2007-02-19 11:45:33 UTC (rev 21445)
@@ -355,6 +355,40 @@
 	return buf;
 }
 
+/* Give a piece of tdb data to a parser */
+
+int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key,
+		   tdb_off_t offset, tdb_len_t len,
+		   int (*parser)(TDB_DATA key, TDB_DATA data,
+				 void *private_data),
+		   void *private_data)
+{
+	TDB_DATA data;
+	int result;
+
+	data.dsize = len;
+
+	if ((tdb->transaction == NULL) && (tdb->map_ptr != NULL)) {
+		/*
+		 * Optimize by avoiding the malloc/memcpy/free, point the
+		 * parser directly at the mmap area.
+		 */
+		if (tdb->methods->tdb_oob(tdb, offset+len, 0) != 0) {
+			return -1;
+		}
+		data.dptr = offset + (char *)tdb->map_ptr;
+		return parser(key, data, private_data);
+	}
+
+	if (!(data.dptr = tdb_alloc_read(tdb, offset, len))) {
+		return -1;
+	}
+
+	result = parser(key, data, private_data);
+	free(data.dptr);
+	return result;
+}
+
 /* read/write a record */
 int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec)
 {

Modified: branches/SAMBA_3_0_25/source/tdb/common/tdb.c
===================================================================
--- branches/SAMBA_3_0_25/source/tdb/common/tdb.c	2007-02-19 11:19:53 UTC (rev 21444)
+++ branches/SAMBA_3_0_25/source/tdb/common/tdb.c	2007-02-19 11:45:33 UTC (rev 21445)
@@ -56,6 +56,10 @@
 	tdb_brlock(tdb, TDB_SEQNUM_OFS, F_UNLCK, F_SETLKW, 1, 1);
 }
 
+static int tdb_key_compare(TDB_DATA key, TDB_DATA data, void *private_data)
+{
+	return memcmp(data.dptr, key.dptr, data.dsize);
+}
 
 /* Returns 0 on fail.  On success, return offset of record, and fills
    in rec */
@@ -73,19 +77,12 @@
 		if (tdb_rec_read(tdb, rec_ptr, r) == -1)
 			return 0;
 
-		if (!TDB_DEAD(r) && hash==r->full_hash && key.dsize==r->key_len) {
-			char *k;
-			/* a very likely hit - read the key */
-			k = tdb_alloc_read(tdb, rec_ptr + sizeof(*r), 
-					   r->key_len);
-			if (!k)
-				return 0;
-
-			if (memcmp(key.dptr, k, key.dsize) == 0) {
-				SAFE_FREE(k);
-				return rec_ptr;
-			}
-			SAFE_FREE(k);
+		if (!TDB_DEAD(r) && hash==r->full_hash
+		    && key.dsize==r->key_len
+		    && tdb_parse_data(tdb, key, rec_ptr + sizeof(*r),
+				      r->key_len, tdb_key_compare,
+				      NULL) == 0) {
+			return rec_ptr;
 		}
 		rec_ptr = r->next;
 	}
@@ -163,6 +160,47 @@
 	return ret;
 }
 
+/*
+ * Find an entry in the database and hand the record's data to a parsing
+ * function. The parsing function is executed under the chain read lock, so it
+ * should be fast and should not block on other syscalls.
+ *
+ * DONT CALL OTHER TDB CALLS FROM THE PARSER, THIS MIGHT LEAD TO SEGFAULTS.
+ *
+ * For mmapped tdb's that do not have a transaction open it points the parsing
+ * function directly at the mmap area, it avoids the malloc/memcpy in this
+ * case. If a transaction is open or no mmap is available, it has to do
+ * malloc/read/parse/free.
+ *
+ * This is interesting for all readers of potentially large data structures in
+ * the tdb records, ldb indexes being one example.
+ */
+
+int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key,
+		     int (*parser)(TDB_DATA key, TDB_DATA data,
+				   void *private_data),
+		     void *private_data)
+{
+	tdb_off_t rec_ptr;
+	struct list_struct rec;
+	int ret;
+	u32 hash;
+
+	/* find which hash bucket it is in */
+	hash = tdb->hash_fn(&key);
+
+	if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) {
+		return TDB_ERRCODE(TDB_ERR_NOEXIST, 0);
+	}
+
+	ret = tdb_parse_data(tdb, key, rec_ptr + sizeof(rec) + rec.key_len,
+			     rec.data_len, parser, private_data);
+
+	tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK);
+
+	return ret;
+}
+
 /* check if an entry in the database exists 
 
    note that 1 is returned if the key is found and 0 is returned if not found

Modified: branches/SAMBA_3_0_25/source/tdb/common/tdb_private.h
===================================================================
--- branches/SAMBA_3_0_25/source/tdb/common/tdb_private.h	2007-02-19 11:19:53 UTC (rev 21444)
+++ branches/SAMBA_3_0_25/source/tdb/common/tdb_private.h	2007-02-19 11:45:33 UTC (rev 21445)
@@ -196,6 +196,11 @@
 int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec);
 int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct list_struct *rec);
 char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len);
+int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key,
+		   tdb_off_t offset, tdb_len_t len,
+		   int (*parser)(TDB_DATA key, TDB_DATA data,
+				 void *private_data),
+		   void *private_data);
 tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, u32 hash, int locktype,
 			   struct list_struct *rec);
 void tdb_io_init(struct tdb_context *tdb);

Modified: branches/SAMBA_3_0_25/source/tdb/include/tdb.h
===================================================================
--- branches/SAMBA_3_0_25/source/tdb/include/tdb.h	2007-02-19 11:19:53 UTC (rev 21444)
+++ branches/SAMBA_3_0_25/source/tdb/include/tdb.h	2007-02-19 11:45:33 UTC (rev 21445)
@@ -101,6 +101,10 @@
 enum TDB_ERROR tdb_error(struct tdb_context *tdb);
 const char *tdb_errorstr(struct tdb_context *tdb);
 TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key);
+int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key,
+		     int (*parser)(TDB_DATA key, TDB_DATA data,
+				   void *private_data),
+		     void *private_data);
 int tdb_delete(struct tdb_context *tdb, TDB_DATA key);
 int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag);
 int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf);

Modified: branches/SAMBA_4_0/source/lib/tdb/common/io.c
===================================================================
--- branches/SAMBA_4_0/source/lib/tdb/common/io.c	2007-02-19 11:19:53 UTC (rev 21444)
+++ branches/SAMBA_4_0/source/lib/tdb/common/io.c	2007-02-19 11:45:33 UTC (rev 21445)
@@ -353,6 +353,40 @@
 	return buf;
 }
 
+/* Give a piece of tdb data to a parser */
+
+int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key,
+		   tdb_off_t offset, tdb_len_t len,
+		   int (*parser)(TDB_DATA key, TDB_DATA data,
+				 void *private_data),
+		   void *private_data)
+{
+	TDB_DATA data;
+	int result;
+
+	data.dsize = len;
+
+	if ((tdb->transaction == NULL) && (tdb->map_ptr != NULL)) {
+		/*
+		 * Optimize by avoiding the malloc/memcpy/free, point the
+		 * parser directly at the mmap area.
+		 */
+		if (tdb->methods->tdb_oob(tdb, offset+len, 0) != 0) {
+			return -1;
+		}
+		data.dptr = offset + (unsigned char *)tdb->map_ptr;
+		return parser(key, data, private_data);
+	}
+
+	if (!(data.dptr = tdb_alloc_read(tdb, offset, len))) {
+		return -1;
+	}
+
+	result = parser(key, data, private_data);
+	free(data.dptr);
+	return result;
+}
+
 /* read/write a record */
 int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec)
 {

Modified: branches/SAMBA_4_0/source/lib/tdb/common/tdb.c
===================================================================
--- branches/SAMBA_4_0/source/lib/tdb/common/tdb.c	2007-02-19 11:19:53 UTC (rev 21444)
+++ branches/SAMBA_4_0/source/lib/tdb/common/tdb.c	2007-02-19 11:45:33 UTC (rev 21445)
@@ -56,6 +56,10 @@
 	tdb_brlock(tdb, TDB_SEQNUM_OFS, F_UNLCK, F_SETLKW, 1, 1);
 }
 
+static int tdb_key_compare(TDB_DATA key, TDB_DATA data, void *private_data)
+{
+	return memcmp(data.dptr, key.dptr, data.dsize);
+}
 
 /* Returns 0 on fail.  On success, return offset of record, and fills
    in rec */
@@ -73,19 +77,12 @@
 		if (tdb_rec_read(tdb, rec_ptr, r) == -1)
 			return 0;
 
-		if (!TDB_DEAD(r) && hash==r->full_hash && key.dsize==r->key_len) {
-			unsigned char *k;
-			/* a very likely hit - read the key */
-			k = tdb_alloc_read(tdb, rec_ptr + sizeof(*r), 
-					   r->key_len);
-			if (!k)
-				return 0;
-
-			if (memcmp(key.dptr, k, key.dsize) == 0) {
-				SAFE_FREE(k);
-				return rec_ptr;
-			}
-			SAFE_FREE(k);
+		if (!TDB_DEAD(r) && hash==r->full_hash
+		    && key.dsize==r->key_len
+		    && tdb_parse_data(tdb, key, rec_ptr + sizeof(*r),
+				      r->key_len, tdb_key_compare,
+				      NULL) == 0) {
+			return rec_ptr;
 		}
 		rec_ptr = r->next;
 	}
@@ -163,6 +160,47 @@
 	return ret;
 }
 
+/*
+ * Find an entry in the database and hand the record's data to a parsing
+ * function. The parsing function is executed under the chain read lock, so it
+ * should be fast and should not block on other syscalls.
+ *
+ * DONT CALL OTHER TDB CALLS FROM THE PARSER, THIS MIGHT LEAD TO SEGFAULTS.
+ *
+ * For mmapped tdb's that do not have a transaction open it points the parsing
+ * function directly at the mmap area, it avoids the malloc/memcpy in this
+ * case. If a transaction is open or no mmap is available, it has to do
+ * malloc/read/parse/free.
+ *
+ * This is interesting for all readers of potentially large data structures in
+ * the tdb records, ldb indexes being one example.
+ */
+
+int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key,
+		     int (*parser)(TDB_DATA key, TDB_DATA data,
+				   void *private_data),
+		     void *private_data)
+{
+	tdb_off_t rec_ptr;
+	struct list_struct rec;
+	int ret;
+	u32 hash;
+
+	/* find which hash bucket it is in */
+	hash = tdb->hash_fn(&key);
+
+	if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) {
+		return TDB_ERRCODE(TDB_ERR_NOEXIST, 0);
+	}
+
+	ret = tdb_parse_data(tdb, key, rec_ptr + sizeof(rec) + rec.key_len,
+			     rec.data_len, parser, private_data);
+
+	tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK);
+
+	return ret;
+}
+
 /* check if an entry in the database exists 
 
    note that 1 is returned if the key is found and 0 is returned if not found

Modified: branches/SAMBA_4_0/source/lib/tdb/common/tdb_private.h
===================================================================
--- branches/SAMBA_4_0/source/lib/tdb/common/tdb_private.h	2007-02-19 11:19:53 UTC (rev 21444)
+++ branches/SAMBA_4_0/source/lib/tdb/common/tdb_private.h	2007-02-19 11:45:33 UTC (rev 21445)
@@ -196,6 +196,11 @@
 int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec);
 int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct list_struct *rec);
 unsigned char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len);
+int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key,
+		   tdb_off_t offset, tdb_len_t len,
+		   int (*parser)(TDB_DATA key, TDB_DATA data,
+				 void *private_data),
+		   void *private_data);
 tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, u32 hash, int locktype,
 			   struct list_struct *rec);
 void tdb_io_init(struct tdb_context *tdb);

Modified: branches/SAMBA_4_0/source/lib/tdb/include/tdb.h
===================================================================
--- branches/SAMBA_4_0/source/lib/tdb/include/tdb.h	2007-02-19 11:19:53 UTC (rev 21444)
+++ branches/SAMBA_4_0/source/lib/tdb/include/tdb.h	2007-02-19 11:45:33 UTC (rev 21445)
@@ -101,6 +101,10 @@
 enum TDB_ERROR tdb_error(struct tdb_context *tdb);
 const char *tdb_errorstr(struct tdb_context *tdb);
 TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key);
+int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key,
+		     int (*parser)(TDB_DATA key, TDB_DATA data,
+				   void *private_data),
+		     void *private_data);
 int tdb_delete(struct tdb_context *tdb, TDB_DATA key);
 int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag);
 int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf);



More information about the samba-cvs mailing list