github.com/rosedblabs/rosedb/v2@v2.3.7-0.20240423093736-a89ea823e5b9/batch_test.go (about)

     1  package rosedb
     2  
     3  import (
     4  	"os"
     5  	"testing"
     6  
     7  	"github.com/rosedblabs/rosedb/v2/utils"
     8  	"github.com/stretchr/testify/assert"
     9  )
    10  
    11  func destroyDB(db *DB) {
    12  	_ = db.Close()
    13  	_ = os.RemoveAll(db.options.DirPath)
    14  	_ = os.RemoveAll(mergeDirPath(db.options.DirPath))
    15  }
    16  
    17  func TestBatch_Put_Normal(t *testing.T) {
    18  	// value 128B
    19  	batchPutAndIterate(t, 1*GB, 10000, 128)
    20  	// value 1KB
    21  	batchPutAndIterate(t, 1*GB, 10000, KB)
    22  	// value 32KB
    23  	batchPutAndIterate(t, 1*GB, 1000, 32*KB)
    24  }
    25  
    26  func TestBatch_Put_IncrSegmentFile(t *testing.T) {
    27  	batchPutAndIterate(t, 64*MB, 2000, 32*KB)
    28  	options := DefaultOptions
    29  	options.SegmentSize = 64 * MB
    30  	db, err := Open(options)
    31  	assert.Nil(t, err)
    32  	defer destroyDB(db)
    33  
    34  	generateData(t, db, 1, 2000, 32*KB)
    35  
    36  	// write more data to rotate new segment file
    37  	batch := db.NewBatch(DefaultBatchOptions)
    38  	for i := 0; i < 1000; i++ {
    39  		err := batch.Put(utils.GetTestKey(i*100), utils.RandomValue(32*KB))
    40  		assert.Nil(t, err)
    41  	}
    42  	err = batch.Commit()
    43  	assert.Nil(t, err)
    44  }
    45  
    46  func TestBatch_Get_Normal(t *testing.T) {
    47  	options := DefaultOptions
    48  	db, err := Open(options)
    49  	assert.Nil(t, err)
    50  	defer destroyDB(db)
    51  
    52  	batch1 := db.NewBatch(DefaultBatchOptions)
    53  	err = batch1.Put(utils.GetTestKey(12), utils.RandomValue(128))
    54  	assert.Nil(t, err)
    55  	val1, err := batch1.Get(utils.GetTestKey(12))
    56  	assert.Nil(t, err)
    57  	assert.NotNil(t, val1)
    58  	_ = batch1.Commit()
    59  
    60  	generateData(t, db, 400, 500, 4*KB)
    61  
    62  	batch2 := db.NewBatch(DefaultBatchOptions)
    63  	err = batch2.Delete(utils.GetTestKey(450))
    64  	assert.Nil(t, err)
    65  	val, err := batch2.Get(utils.GetTestKey(450))
    66  	assert.Nil(t, val)
    67  	assert.Equal(t, ErrKeyNotFound, err)
    68  	_ = batch2.Commit()
    69  
    70  	// reopen
    71  	_ = db.Close()
    72  	db2, err := Open(options)
    73  	assert.Nil(t, err)
    74  	defer func() {
    75  		_ = db2.Close()
    76  	}()
    77  	assertKeyExistOrNot(t, db2, utils.GetTestKey(12), true)
    78  	assertKeyExistOrNot(t, db2, utils.GetTestKey(450), false)
    79  }
    80  
    81  func TestBatch_Delete_Normal(t *testing.T) {
    82  	options := DefaultOptions
    83  	db, err := Open(options)
    84  	assert.Nil(t, err)
    85  	defer destroyDB(db)
    86  
    87  	err = db.Delete([]byte("not exist"))
    88  	assert.Nil(t, err)
    89  
    90  	generateData(t, db, 1, 100, 128)
    91  	err = db.Delete(utils.GetTestKey(99))
    92  	assert.Nil(t, err)
    93  
    94  	exist, err := db.Exist(utils.GetTestKey(99))
    95  	assert.Nil(t, err)
    96  	assert.False(t, exist)
    97  
    98  	batch := db.NewBatch(DefaultBatchOptions)
    99  	err = batch.Put(utils.GetTestKey(200), utils.RandomValue(100))
   100  	assert.Nil(t, err)
   101  	err = batch.Delete(utils.GetTestKey(200))
   102  	assert.Nil(t, err)
   103  	exist1, err := batch.Exist(utils.GetTestKey(200))
   104  	assert.Nil(t, err)
   105  	assert.False(t, exist1)
   106  	_ = batch.Commit()
   107  
   108  	// reopen
   109  	_ = db.Close()
   110  	db2, err := Open(options)
   111  	assert.Nil(t, err)
   112  	defer func() {
   113  		_ = db2.Close()
   114  	}()
   115  	assertKeyExistOrNot(t, db2, utils.GetTestKey(200), false)
   116  }
   117  
   118  func TestBatch_Exist_Normal(t *testing.T) {
   119  	options := DefaultOptions
   120  	db, err := Open(options)
   121  	assert.Nil(t, err)
   122  	defer destroyDB(db)
   123  
   124  	generateData(t, db, 1, 100, 128)
   125  	batch := db.NewBatch(DefaultBatchOptions)
   126  	ok1, err := batch.Exist(utils.GetTestKey(99))
   127  	assert.Nil(t, err)
   128  	assert.True(t, ok1)
   129  	ok2, err := batch.Exist(utils.GetTestKey(5000))
   130  	assert.Nil(t, err)
   131  	assert.False(t, ok2)
   132  	_ = batch.Commit()
   133  
   134  	_ = db.Close()
   135  	db2, err := Open(options)
   136  	assert.Nil(t, err)
   137  	defer func() {
   138  		_ = db2.Close()
   139  	}()
   140  	assertKeyExistOrNot(t, db2, utils.GetTestKey(99), true)
   141  }
   142  
   143  func generateData(t *testing.T, db *DB, start, end int, valueLen int) {
   144  	for ; start < end; start++ {
   145  		err := db.Put(utils.GetTestKey(start), utils.RandomValue(valueLen))
   146  		assert.Nil(t, err)
   147  	}
   148  }
   149  
   150  func batchPutAndIterate(t *testing.T, segmentSize int64, size int, valueLen int) {
   151  	options := DefaultOptions
   152  	options.SegmentSize = segmentSize
   153  	db, err := Open(options)
   154  	assert.Nil(t, err)
   155  	defer destroyDB(db)
   156  
   157  	batch := db.NewBatch(BatchOptions{})
   158  
   159  	for i := 0; i < size; i++ {
   160  		err := batch.Put(utils.GetTestKey(i), utils.RandomValue(valueLen))
   161  		assert.Nil(t, err)
   162  	}
   163  	err = batch.Commit()
   164  	assert.Nil(t, err)
   165  
   166  	for i := 0; i < size; i++ {
   167  		value, err := db.Get(utils.GetTestKey(i))
   168  		assert.Nil(t, err)
   169  		assert.Equal(t, len(utils.RandomValue(valueLen)), len(value))
   170  	}
   171  
   172  	// reopen
   173  	_ = db.Close()
   174  	db2, err := Open(options)
   175  	assert.Nil(t, err)
   176  	defer func() {
   177  		_ = db2.Close()
   178  	}()
   179  	for i := 0; i < size; i++ {
   180  		value, err := db2.Get(utils.GetTestKey(i))
   181  		assert.Nil(t, err)
   182  		assert.Equal(t, len(utils.RandomValue(valueLen)), len(value))
   183  	}
   184  }
   185  
   186  func assertKeyExistOrNot(t *testing.T, db *DB, key []byte, exist bool) {
   187  	val, err := db.Get(key)
   188  	if exist {
   189  		assert.Nil(t, err)
   190  		assert.NotNil(t, val)
   191  	} else {
   192  		assert.Nil(t, val)
   193  		assert.Equal(t, ErrKeyNotFound, err)
   194  	}
   195  }
   196  
   197  func TestBatch_Rollback(t *testing.T) {
   198  	options := DefaultOptions
   199  	db, err := Open(options)
   200  	assert.Nil(t, err)
   201  	defer destroyDB(db)
   202  
   203  	key := []byte("rosedb")
   204  	value := []byte("val")
   205  
   206  	batcher := db.NewBatch(DefaultBatchOptions)
   207  	err = batcher.Put(key, value)
   208  	assert.Nil(t, err)
   209  
   210  	err = batcher.Rollback()
   211  	assert.Nil(t, err)
   212  
   213  	resp, err := db.Get(key)
   214  	assert.Equal(t, ErrKeyNotFound, err)
   215  	assert.Empty(t, resp)
   216  }
   217  
   218  func TestBatch_SetTwice(t *testing.T) {
   219  	options := DefaultOptions
   220  	db, err := Open(options)
   221  	assert.Nil(t, err)
   222  	defer destroyDB(db)
   223  
   224  	batch := db.NewBatch(DefaultBatchOptions)
   225  	key := []byte("rosedb")
   226  	value1 := []byte("val1")
   227  	value2 := []byte("val2")
   228  	_ = batch.Put(key, value1)
   229  	_ = batch.Put(key, value2)
   230  
   231  	res, err := batch.Get(key)
   232  	assert.Nil(t, err)
   233  	assert.Equal(t, res, value2)
   234  
   235  	_ = batch.Commit()
   236  	res2, err := db.Get(key)
   237  	assert.Nil(t, err)
   238  	assert.Equal(t, res2, value2)
   239  }