From 04bc915abd1db09501bd68fe9394453c2e301b19 Mon Sep 17 00:00:00 2001 From: tidwall Date: Sat, 31 Jul 2021 19:29:49 -0700 Subject: [PATCH] Estimate last oof size on open addresses #77 --- buntdb.go | 48 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/buntdb.go b/buntdb.go index 8d86a1a..1b1224b 100644 --- a/buntdb.go +++ b/buntdb.go @@ -955,11 +955,16 @@ func (db *DB) load() error { return err } } - pos, err := db.file.Seek(n, 0) - if err != nil { + if _, err := db.file.Seek(n, 0); err != nil { return err } - db.lastaofsz = int(pos) + var estaofsz int + db.keys.Walk(func(items []interface{}) { + for _, v := range items { + estaofsz += v.(*dbItem).estAOFSetSize() + } + }) + db.lastaofsz += estaofsz return nil } @@ -1258,6 +1263,43 @@ type dbItem struct { keyless bool // keyless item for scanning } +func estIntSize(x int) int { + if x == 0 { + return 1 + } + var n int + for x > 0 { + n++ + x /= 10 + } + return n +} + +func estArraySize(count int) int { + return 1 + estIntSize(count) + 2 +} + +func estBulkStringSize(s string) int { + return 1 + estIntSize(len(s)) + 2 + len(s) + 2 +} + +func (dbi *dbItem) estAOFSetSize() (n int) { + if dbi.opts != nil && dbi.opts.ex { + n += estArraySize(5) + n += estBulkStringSize("set") + n += estBulkStringSize(dbi.key) + n += estBulkStringSize(dbi.val) + n += estBulkStringSize("ex") + n += estBulkStringSize("99") // estimate two byte bulk string + } else { + n += estArraySize(3) + n += estBulkStringSize("set") + n += estBulkStringSize(dbi.key) + n += estBulkStringSize(dbi.val) + } + return n +} + func appendArray(buf []byte, count int) []byte { buf = append(buf, '*') buf = strconv.AppendInt(buf, int64(count), 10)