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 }