svn commit: samba r13283 - in branches/SAMBA_4_0/source/lib/tdb/common: .

tridge at samba.org tridge at samba.org
Wed Feb 1 10:50:26 GMT 2006


Author: tridge
Date: 2006-02-01 10:50:26 +0000 (Wed, 01 Feb 2006)
New Revision: 13283

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

Log:

added two optimisations to the tdb transactions code. The first is to
more agressively coalesce entries in the linked list of the undo
log. The second is to ensure that writes during a transaction into the
hash table don't cause the size of the undo log linked list to grow.

These optimisations don't affect Samba much, but they make a huge
difference to the use of ldb in kde

Modified:
   branches/SAMBA_4_0/source/lib/tdb/common/transaction.c


Changeset:
Modified: branches/SAMBA_4_0/source/lib/tdb/common/transaction.c
===================================================================
--- branches/SAMBA_4_0/source/lib/tdb/common/transaction.c	2006-02-01 10:04:55 UTC (rev 13282)
+++ branches/SAMBA_4_0/source/lib/tdb/common/transaction.c	2006-02-01 10:50:26 UTC (rev 13283)
@@ -195,7 +195,7 @@
 static int transaction_write(struct tdb_context *tdb, tdb_off_t off, 
 			     const void *buf, tdb_len_t len)
 {
-	struct tdb_transaction_el *el;
+	struct tdb_transaction_el *el, *best_el=NULL;
 
 	if (len == 0) {
 		return 0;
@@ -213,6 +213,10 @@
 	for (el=tdb->transaction->elements_last;el;el=el->prev) {
 		tdb_len_t partial;
 
+		if (best_el == NULL && off == el->offset+el->length) {
+			best_el = el;
+		}
+
 		if (off+len <= el->offset) {
 			continue;
 		}
@@ -248,6 +252,28 @@
 		return 0;
 	}
 
+	/* see if we can append the new entry to an existing entry */
+	if (best_el && best_el->offset + best_el->length == off && 
+	    (off+len < tdb->transaction->old_map_size ||
+	     off > tdb->transaction->old_map_size)) {
+		unsigned char *data = best_el->data;
+		el = best_el;
+		el->data = realloc(el->data, el->length + len);
+		if (el->data == NULL) {
+			tdb->ecode = TDB_ERR_OOM;
+			tdb->transaction->transaction_error = 1;
+			el->data = data;
+			return -1;
+		}
+		if (buf) {
+			memcpy(el->data + el->length, buf, len);
+		} else {
+			memset(el->data + el->length, TDB_PAD_BYTE, len);
+		}
+		el->length += len;
+		return 0;
+	}
+
 	/* add a new entry at the end of the list */
 	el = malloc(sizeof(*el));
 	if (el == NULL) {
@@ -433,6 +459,15 @@
 	tdb->transaction->io_methods = tdb->methods;
 	tdb->methods = &transaction_methods;
 
+	/* by calling this transaction write here, we ensure that we don't grow the
+	   transaction linked list due to hash table updates */
+	if (transaction_write(tdb, FREELIST_TOP, tdb->transaction->hash_heads, 
+			      TDB_HASHTABLE_SIZE(tdb)) != 0) {
+		TDB_LOG((tdb, 0, "tdb_transaction_start: failed to prime hash table\n"));
+		tdb->ecode = TDB_ERR_IO;
+		goto fail;
+	}
+
 	return 0;
 	
 fail:



More information about the samba-cvs mailing list