From bc85af6b61e996976e70b020bd93c926fc379d20 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 9 Jan 2008 15:33:10 +1100 Subject: [PATCH] a compromise for freelist scanning - we now will look for other than the first fit, but get exponentially more desperate as we get deeper into the freelist (This used to be ctdb commit f3319ef84c47dc8bf0bfb4ef1c72cee58ed9d88c) --- ctdb/lib/tdb/common/freelist.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/ctdb/lib/tdb/common/freelist.c b/ctdb/lib/tdb/common/freelist.c index 358545ed575..da4586ff540 100644 --- a/ctdb/lib/tdb/common/freelist.c +++ b/ctdb/lib/tdb/common/freelist.c @@ -280,6 +280,7 @@ tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_st tdb_off_t rec_ptr, last_ptr; tdb_len_t rec_len; } bestfit; + float multiplier = 1.0; if (tdb_lock(tdb, -1, F_WRLCK) == -1) return 0; @@ -314,13 +315,27 @@ tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_st bestfit.rec_len = rec->rec_len; bestfit.rec_ptr = rec_ptr; bestfit.last_ptr = last_ptr; - break; } } /* move to the next record */ last_ptr = rec_ptr; rec_ptr = rec->next; + + /* if we've found a record that is big enough, then + stop searching if its also not too big. The + definition of 'too big' changes as we scan + through */ + if (bestfit.rec_len > 0 && + bestfit.rec_len < length * multiplier) { + break; + } + + /* this multiplier means we only extremely rarely + search more than 50 or so records. At 50 records we + accept records up to 11 times larger than what we + want */ + multiplier *= 1.05; } if (bestfit.rec_ptr != 0) {