The branch, master has been updated via 91a17e5 tdb: Don't malloc for every record in traverse from c3af7a3 lib: Allow NULL blob for messaging_send()
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 91a17e54136c1ad143d8b740ea7c7592cd8a6a8d Author: Volker Lendecke <v...@samba.org> Date: Wed Jul 22 11:19:08 2015 +0200 tdb: Don't malloc for every record in traverse This gains a few percent in tdbbackup Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Michael Adam <ob...@samba.org> Autobuild-User(master): Volker Lendecke <v...@samba.org> Autobuild-Date(master): Fri Jul 15 00:52:00 CEST 2016 on sn-devel-144 ----------------------------------------------------------------------- Summary of changes: lib/tdb/common/traverse.c | 46 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) Changeset truncated at 500 lines: diff --git a/lib/tdb/common/traverse.c b/lib/tdb/common/traverse.c index e18e3c3..f33ef34 100644 --- a/lib/tdb/common/traverse.c +++ b/lib/tdb/common/traverse.c @@ -148,6 +148,13 @@ static int tdb_traverse_internal(struct tdb_context *tdb, struct tdb_record rec; int ret = 0, count = 0; tdb_off_t off; + size_t recbuf_len; + + recbuf_len = 4096; + key.dptr = malloc(recbuf_len); + if (key.dptr == NULL) { + return -1; + } /* This was in the initialization, above, but the IRIX compiler * did not like it. crh @@ -159,15 +166,44 @@ static int tdb_traverse_internal(struct tdb_context *tdb, /* tdb_next_lock places locks on the record returned, and its chain */ while ((off = tdb_next_lock(tdb, tl, &rec)) != 0) { + tdb_len_t full_len = rec.key_len + rec.data_len; + int nread; + + if (full_len > recbuf_len) { + recbuf_len = full_len; + + /* + * No realloc, we don't need the old data and thus can + * do without the memcpy + */ + free(key.dptr); + key.dptr = malloc(recbuf_len); + + if (key.dptr == NULL) { + ret = -1; + if (tdb_unlock(tdb, tl->hash, tl->lock_rw) + != 0) { + goto out; + } + if (tdb_unlock_record(tdb, tl->off) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, + "tdb_traverse: malloc " + "failed and unlock_record " + "failed!\n")); + } + goto out; + } + } + if (off == TDB_NEXT_LOCK_ERR) { ret = -1; goto out; } count++; /* now read the full record */ - key.dptr = tdb_alloc_read(tdb, tl->off + sizeof(rec), - rec.key_len + rec.data_len); - if (!key.dptr) { + nread = tdb->methods->tdb_read(tdb, tl->off + sizeof(rec), + key.dptr, full_len, 0); + if (nread == -1) { ret = -1; if (tdb_unlock(tdb, tl->hash, tl->lock_rw) != 0) goto out; @@ -184,7 +220,6 @@ static int tdb_traverse_internal(struct tdb_context *tdb, /* Drop chain lock, call out */ if (tdb_unlock(tdb, tl->hash, tl->lock_rw) != 0) { ret = -1; - SAFE_FREE(key.dptr); goto out; } if (fn && fn(tdb, key, dbuf, private_data)) { @@ -194,13 +229,12 @@ static int tdb_traverse_internal(struct tdb_context *tdb, TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_traverse: unlock_record failed!\n"));; ret = -1; } - SAFE_FREE(key.dptr); goto out; } - SAFE_FREE(key.dptr); } tdb_trace(tdb, "tdb_traverse_end"); out: + SAFE_FREE(key.dptr); tdb->travlocks.next = tl->next; if (ret < 0) return -1; -- Samba Shared Repository