github.com/piotrnar/gocoin@v0.0.0-20240512203912-faa0448c5e96/lib/others/qdb/db_test.go (about)

     1  package qdb
     2  
     3  import (
     4  	"os"
     5  	"fmt"
     6  	"time"
     7  	"bytes"
     8  	"testing"
     9  	mr "math/rand"
    10  	cr "crypto/rand"
    11  	"encoding/hex"
    12  )
    13  
    14  const (
    15  	dbname = "test"
    16  	oneRound = 10000
    17  	delRound = 1000
    18  )
    19  
    20  func getRecSize() int {
    21  	return 4
    22  	//return mr.Intn(4096)
    23  }
    24  
    25  
    26  func kim(v []byte) bool {
    27  	return (mr.Int63()&1)==0
    28  }
    29  
    30  
    31  func dumpidx(db *DB) {
    32  	println("index")
    33  	for k, v := range db.Idx.Index {
    34  		println(k2s(k), v.datpos, v.datlen)
    35  	}
    36  }
    37  
    38  
    39  func TestDatabase(t *testing.T) {
    40  	var key KeyType
    41  	var val, v []byte
    42  	var db *DB
    43  	var e error
    44  
    45  	os.RemoveAll(dbname)
    46  	mr.Seed(time.Now().UnixNano())
    47  
    48  	db, e = NewDB(dbname, true)
    49  	if e != nil {
    50  		t.Error("Cannot create db")
    51  		return
    52  	}
    53  
    54  	// Add oneRound random records
    55  	for i:=0; i<oneRound; i++ {
    56  		vlen := getRecSize()
    57  		val = make([]byte, vlen)
    58  		key = KeyType(mr.Int63())
    59  		cr.Read(val[:])
    60  		db.Put(key, val)
    61  	}
    62  	db.Close()
    63  
    64  	// Reopen DB, verify, defrag and close
    65  	db, e = NewDB(dbname, true)
    66  	if e != nil {
    67  		t.Error("Cannot reopen db")
    68  		return
    69  	}
    70  	if db.Count()!=oneRound {
    71  		t.Error("Bad count", db.Count(), oneRound)
    72  		return
    73  	}
    74  	//dumpidx(db)
    75  	v = db.Get(key)
    76  	if !bytes.Equal(val, v) {
    77  		t.Error("Key data mismatch ", k2s(key), "/", hex.EncodeToString(val), "/", hex.EncodeToString(v))
    78  		return
    79  	}
    80  	if db.Count() != oneRound {
    81  		t.Error("Wrong number of records", db.Count(), oneRound)
    82  	}
    83  	db.Defrag(false)
    84  	db.Close()
    85  
    86  	// Reopen DB, verify, add oneRound more records and Close
    87  	db, e = NewDB(dbname, true)
    88  	if e != nil {
    89  		t.Error("Cannot reopen db")
    90  		return
    91  	}
    92  	v = db.Get(key)
    93  	if !bytes.Equal(val[:], v[:]) {
    94  		t.Error("Key data mismatch")
    95  	}
    96  	if db.Count() != oneRound {
    97  		t.Error("Wrong number of records", db.Count())
    98  	}
    99  	db.NoSync()
   100  	for i:=0; i<oneRound; i++ {
   101  		vlen := getRecSize()
   102  		val = make([]byte, vlen)
   103  		key = KeyType(mr.Int63())
   104  		cr.Read(val[:])
   105  		db.Put(key, val)
   106  	}
   107  	db.Sync()
   108  	db.Close()
   109  
   110  	// Reopen DB, verify, defrag and close
   111  	db, e = NewDB(dbname, true)
   112  	if e != nil {
   113  		t.Error("Cannot reopen db")
   114  		return
   115  	}
   116  	v = db.Get(key)
   117  	if !bytes.Equal(val[:], v[:]) {
   118  		t.Error("Key data mismatch")
   119  	}
   120  	if db.Count() != 2*oneRound {
   121  		t.Error("Wrong number of records", db.Count())
   122  		return
   123  	}
   124  	db.Defrag(true)
   125  	db.Close()
   126  
   127  	// Reopen DB, verify, close...
   128  	db, e = NewDB(dbname, true)
   129  	if e != nil {
   130  		t.Error("Cannot reopen db")
   131  		return
   132  	}
   133  	v = db.Get(key)
   134  	if !bytes.Equal(val[:], v[:]) {
   135  		t.Error("Key data mismatch")
   136  	}
   137  	if db.Count() != 2*oneRound {
   138  		t.Error("Wrong number of records", db.Count())
   139  	}
   140  	db.Close()
   141  
   142  	// Reopen, delete 100 records, close...
   143  	db, e = NewDB(dbname, true)
   144  	if e != nil {
   145  		t.Error("Cannot reopen db")
   146  		return
   147  	}
   148  
   149  	var keys []KeyType
   150  	db.Browse(func (key KeyType, v []byte) uint32 {
   151  		keys = append(keys, key)
   152  		if len(keys)<delRound {
   153  			return 0
   154  		} else {
   155  			return BR_ABORT
   156  		}
   157  	})
   158  	for i := range keys {
   159  		db.Del(keys[i])
   160  	}
   161  	db.Close()
   162  
   163  	// Reopen DB, verify, close...
   164  	db, e = NewDB(dbname, true)
   165  	if db.Count() != 2*oneRound-delRound {
   166  		t.Error("Wrong number of records", db.Count())
   167  	}
   168  	db.Close()
   169  
   170  	// Reopen DB, verify, close...
   171  	db, e = NewDB(dbname, true)
   172  	db.Defrag(false)
   173  	if db.Count() != 2*oneRound-delRound {
   174  		t.Error("Wrong number of records", db.Count())
   175  	}
   176  	db.Close()
   177  
   178  	// Reopen DB, verify, close...
   179  	db, e = NewDB(dbname, true)
   180  	if db.Count() != 2*oneRound-delRound {
   181  		t.Error("Wrong number of records", db.Count())
   182  	}
   183  	db.Close()
   184  
   185  	os.RemoveAll(dbname)
   186  }
   187  
   188  func k2s(k KeyType) string {
   189  	return fmt.Sprintf("%16x", k)
   190  }