github.com/flower-corp/rosedb@v1.1.2-0.20230117132829-21dc4f7b319a/zset_test.go (about)

     1  package rosedb
     2  
     3  import (
     4  	"github.com/stretchr/testify/assert"
     5  	"path/filepath"
     6  	"testing"
     7  )
     8  
     9  func TestRoseDB_ZAdd(t *testing.T) {
    10  	path := filepath.Join("/tmp", "rosedb")
    11  	opts := DefaultOptions(path)
    12  	opts.IoType = MMap
    13  	opts.IndexMode = KeyOnlyMemMode
    14  	db, err := Open(opts)
    15  	assert.Nil(t, err)
    16  	defer destroyDB(db)
    17  
    18  	type args struct {
    19  		key    []byte
    20  		score  float64
    21  		member []byte
    22  	}
    23  	tests := []struct {
    24  		name    string
    25  		db      *RoseDB
    26  		args    args
    27  		wantErr bool
    28  	}{
    29  		{
    30  			"normal-1", db, args{key: GetKey(1), score: 100, member: GetValue16B()}, false,
    31  		},
    32  		{
    33  			"normal-2", db, args{key: GetKey(1), score: 100, member: GetValue16B()}, false,
    34  		},
    35  		{
    36  			"normal-3", db, args{key: GetKey(1), score: 200, member: GetValue16B()}, false,
    37  		},
    38  	}
    39  	for _, tt := range tests {
    40  		t.Run(tt.name, func(t *testing.T) {
    41  			if err := tt.db.ZAdd(tt.args.key, tt.args.score, tt.args.member); (err != nil) != tt.wantErr {
    42  				t.Errorf("ZAdd() error = %v, wantErr %v", err, tt.wantErr)
    43  			}
    44  		})
    45  	}
    46  }
    47  
    48  func TestRoseDB_ZScore(t *testing.T) {
    49  	t.Run("fileio", func(t *testing.T) {
    50  		testRoseDBZScore(t, FileIO, KeyOnlyMemMode)
    51  	})
    52  	t.Run("mmap", func(t *testing.T) {
    53  		testRoseDBZScore(t, MMap, KeyValueMemMode)
    54  	})
    55  }
    56  
    57  func testRoseDBZScore(t *testing.T, ioType IOType, mode DataIndexMode) {
    58  	path := filepath.Join("/tmp", "rosedb")
    59  	opts := DefaultOptions(path)
    60  	opts.IoType = ioType
    61  	opts.IndexMode = mode
    62  	db, err := Open(opts)
    63  	assert.Nil(t, err)
    64  	defer destroyDB(db)
    65  
    66  	zsetKey := []byte("my_zset")
    67  	ok1, score1 := db.ZScore(zsetKey, GetKey(0))
    68  	assert.Equal(t, false, ok1)
    69  	assert.Equal(t, float64(0), score1)
    70  
    71  	err = db.ZAdd(zsetKey, 123.33, GetKey(0))
    72  	assert.Nil(t, err)
    73  
    74  	ok2, score2 := db.ZScore(zsetKey, GetKey(0))
    75  	assert.Equal(t, true, ok2)
    76  	assert.Equal(t, 123.33, score2)
    77  
    78  	err = db.ZAdd(zsetKey, 223.33, GetKey(0))
    79  	assert.Nil(t, err)
    80  
    81  	ok3, score3 := db.ZScore(zsetKey, GetKey(0))
    82  	assert.Equal(t, true, ok3)
    83  	assert.Equal(t, 223.33, score3)
    84  
    85  	// reopen and get
    86  	err = db.Close()
    87  	assert.Nil(t, err)
    88  	db2, err := Open(opts)
    89  	assert.Nil(t, err)
    90  	defer func() {
    91  		_ = db2.Close()
    92  	}()
    93  	ok4, score4 := db2.ZScore(zsetKey, GetKey(0))
    94  	assert.Equal(t, true, ok4)
    95  	assert.Equal(t, 223.33, score4)
    96  }
    97  
    98  func TestRoseDB_ZRem(t *testing.T) {
    99  	t.Run("fileio", func(t *testing.T) {
   100  		testRoseDBZRem(t, FileIO, KeyOnlyMemMode)
   101  	})
   102  	t.Run("mmap", func(t *testing.T) {
   103  		testRoseDBZRem(t, MMap, KeyValueMemMode)
   104  	})
   105  }
   106  
   107  func testRoseDBZRem(t *testing.T, ioType IOType, mode DataIndexMode) {
   108  	path := filepath.Join("/tmp", "rosedb")
   109  	opts := DefaultOptions(path)
   110  	opts.IoType = ioType
   111  	opts.IndexMode = mode
   112  	db, err := Open(opts)
   113  	assert.Nil(t, err)
   114  	defer destroyDB(db)
   115  
   116  	zsetKey := []byte("my_zset")
   117  	err = db.ZAdd(zsetKey, 11.33, GetKey(0))
   118  	assert.Nil(t, err)
   119  	err = db.ZAdd(zsetKey, 21.33, GetKey(1))
   120  	assert.Nil(t, err)
   121  	err = db.ZAdd(zsetKey, 31.33, GetKey(2))
   122  	assert.Nil(t, err)
   123  
   124  	c1 := db.ZCard(zsetKey)
   125  	assert.Equal(t, 3, c1)
   126  
   127  	err = db.ZRem(zsetKey, GetKey(1))
   128  	assert.Nil(t, err)
   129  
   130  	c2 := db.ZCard(zsetKey)
   131  	assert.Equal(t, 2, c2)
   132  	ok, _ := db.ZScore(zsetKey, GetKey(1))
   133  	assert.Equal(t, false, ok)
   134  }
   135  
   136  func TestRoseDB_ZCard(t *testing.T) {
   137  	path := filepath.Join("/tmp", "rosedb")
   138  	opts := DefaultOptions(path)
   139  	db, err := Open(opts)
   140  	assert.Nil(t, err)
   141  	defer destroyDB(db)
   142  
   143  	zsetKey := []byte("my_zset")
   144  	c1 := db.ZCard(zsetKey)
   145  	assert.Equal(t, 0, c1)
   146  
   147  	err = db.ZAdd(zsetKey, 11.33, GetKey(0))
   148  	assert.Nil(t, err)
   149  	err = db.ZAdd(zsetKey, 21.33, GetKey(1))
   150  	assert.Nil(t, err)
   151  	err = db.ZAdd(zsetKey, 31.33, GetKey(2))
   152  	assert.Nil(t, err)
   153  
   154  	c2 := db.ZCard(zsetKey)
   155  	assert.Equal(t, 3, c2)
   156  }
   157  
   158  func TestRoseDB_ZRange(t *testing.T) {
   159  	t.Run("fileio", func(t *testing.T) {
   160  		testRoseDBZRange(t, FileIO, KeyValueMemMode)
   161  	})
   162  	t.Run("mmap", func(t *testing.T) {
   163  		testRoseDBZRange(t, MMap, KeyOnlyMemMode)
   164  	})
   165  }
   166  
   167  func testRoseDBZRange(t *testing.T, ioType IOType, mode DataIndexMode) {
   168  	path := filepath.Join("/tmp", "rosedb")
   169  	opts := DefaultOptions(path)
   170  	opts.IoType = ioType
   171  	opts.IndexMode = mode
   172  	db, err := Open(opts)
   173  	assert.Nil(t, err)
   174  	defer destroyDB(db)
   175  
   176  	zsetKey := []byte("my_zset")
   177  	err = db.ZAdd(zsetKey, 32.55, GetKey(0))
   178  	assert.Nil(t, err)
   179  	err = db.ZAdd(zsetKey, 99.34, GetKey(1))
   180  	assert.Nil(t, err)
   181  	err = db.ZAdd(zsetKey, 31.33, GetKey(2))
   182  	assert.Nil(t, err)
   183  	err = db.ZAdd(zsetKey, 54.10, GetKey(3))
   184  	assert.Nil(t, err)
   185  
   186  	values, err := db.ZRange(zsetKey, 0, 100)
   187  	assert.Nil(t, err)
   188  	assert.Equal(t, 4, len(values))
   189  }
   190  
   191  func TestRoseDB_ZRevRange(t *testing.T) {
   192  	t.Run("fileio", func(t *testing.T) {
   193  		testRoseDBZRevRange(t, FileIO, KeyValueMemMode)
   194  	})
   195  	t.Run("mmap", func(t *testing.T) {
   196  		testRoseDBZRevRange(t, MMap, KeyOnlyMemMode)
   197  	})
   198  }
   199  
   200  func testRoseDBZRevRange(t *testing.T, ioType IOType, mode DataIndexMode) {
   201  	path := filepath.Join("/tmp", "rosedb")
   202  	opts := DefaultOptions(path)
   203  	opts.IoType = ioType
   204  	opts.IndexMode = mode
   205  	db, err := Open(opts)
   206  	assert.Nil(t, err)
   207  	defer destroyDB(db)
   208  
   209  	zsetKey := []byte("my_zset")
   210  	for i := 0; i < 100; i++ {
   211  		err := db.ZAdd(zsetKey, float64(i+100), GetKey(i))
   212  		assert.Nil(t, err)
   213  	}
   214  
   215  	ok, score := db.ZScore(zsetKey, GetKey(3))
   216  	assert.True(t, ok)
   217  	assert.Equal(t, float64(103), score)
   218  
   219  	values, err := db.ZRevRange(zsetKey, 1, 10)
   220  	assert.Nil(t, err)
   221  	assert.Equal(t, 10, len(values))
   222  }
   223  
   224  func TestRoseDB_ZRank(t *testing.T) {
   225  	t.Run("fileio", func(t *testing.T) {
   226  		testRoseDBZRank(t, FileIO, KeyValueMemMode)
   227  	})
   228  	t.Run("mmap", func(t *testing.T) {
   229  		testRoseDBZRank(t, MMap, KeyOnlyMemMode)
   230  	})
   231  }
   232  
   233  func testRoseDBZRank(t *testing.T, ioType IOType, mode DataIndexMode) {
   234  	path := filepath.Join("/tmp", "rosedb")
   235  	opts := DefaultOptions(path)
   236  	opts.IoType = ioType
   237  	opts.IndexMode = mode
   238  	db, err := Open(opts)
   239  	assert.Nil(t, err)
   240  	defer destroyDB(db)
   241  
   242  	zsetKey := []byte("my_zset")
   243  	for i := 0; i < 100; i++ {
   244  		err := db.ZAdd(zsetKey, float64(i+100), GetKey(i))
   245  		assert.Nil(t, err)
   246  	}
   247  
   248  	ok, r1 := db.ZRank(zsetKey, GetKey(-1))
   249  	assert.False(t, ok)
   250  	assert.Equal(t, 0, r1)
   251  
   252  	ok, r2 := db.ZRank(zsetKey, GetKey(3))
   253  	assert.True(t, ok)
   254  	assert.Equal(t, 3, r2)
   255  	ok, r3 := db.ZRevRank(zsetKey, GetKey(1))
   256  	assert.True(t, ok)
   257  	assert.Equal(t, 98, r3)
   258  }
   259  
   260  func TestRoseDB_ZSetGC(t *testing.T) {
   261  	path := filepath.Join("/tmp", "rosedb")
   262  	opts := DefaultOptions(path)
   263  	opts.LogFileSizeThreshold = 32 << 20
   264  	db, err := Open(opts)
   265  	assert.Nil(t, err)
   266  	defer destroyDB(db)
   267  
   268  	zsetKey := []byte("my_zset")
   269  	writeCount := 500000
   270  	for i := 0; i < writeCount; i++ {
   271  		err := db.ZAdd(zsetKey, float64(i+100), GetKey(i))
   272  		assert.Nil(t, err)
   273  	}
   274  
   275  	for i := 0; i < writeCount/2; i++ {
   276  		err := db.ZRem(zsetKey, GetKey(i))
   277  		assert.Nil(t, err)
   278  	}
   279  
   280  	err = db.RunLogFileGC(ZSet, 0, 0.1)
   281  	assert.Nil(t, err)
   282  
   283  	card := db.ZCard(zsetKey)
   284  	assert.Equal(t, writeCount/2, card)
   285  }