1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-03 13:47:25 +03:00

r13283: 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
This commit is contained in:
Andrew Tridgell 2006-02-01 10:50:26 +00:00 committed by Gerald (Jerry) Carter
parent 2aa9fefbb3
commit a37d9434d1

View File

@ -195,7 +195,7 @@ fail:
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 @@ static int transaction_write(struct tdb_context *tdb, tdb_off_t off,
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 @@ static int transaction_write(struct tdb_context *tdb, tdb_off_t off,
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 @@ int tdb_transaction_start(struct tdb_context *tdb)
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: