[PATCH] three small ones from my attic
Volker Lendecke
vl at samba.org
Thu Jul 14 17:00:58 UTC 2016
On Thu, Jul 14, 2016 at 05:17:41PM +0200, Michael Adam wrote:
> Style-wise, I would like it better with tdb_read call
> outside the if(...), and a helper variable for the ret,
> but maybe you have good reasons for it?
Introduced a helper variable.
> (similar comments to the above calls to
> tdb_unlock and tdb_unlock_record).
Those two are copy&paste from further down in the code. I opted for
style consistency in the function rather than README.Coding coherence.
> Regarding the call, the DOCONV() seems to be at least
> different from the prior call to tdb_alloc_read()
> (which internally sets 0 to the slot).
> Is that something where the new code is better and
> the alloc_read code needs fixing?
That was a bug in my code, thanks!
New patch attached.
Thanks, Volker
-------------- next part --------------
>From 98e03f87549379f1dbfc9c133fe16891a4f16b1c Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Wed, 22 Jul 2015 11:19:08 +0200
Subject: [PATCH] tdb: Don't malloc for every record in traverse
This gains a few percent in tdbbackup
Signed-off-by: Volker Lendecke <vl at samba.org>
---
lib/tdb/common/traverse.c | 46 ++++++++++++++++++++++++++++++++++++++++------
1 file changed, 40 insertions(+), 6 deletions(-)
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;
--
1.9.1
More information about the samba-technical
mailing list