Skip to content

Commit

Permalink
Merge pull request DiceDB#1341 from DiceDB/rem-encoding
Browse files Browse the repository at this point in the history
Remove encoding and supporting only Type
  • Loading branch information
arpitbbhayani authored Dec 2, 2024
2 parents ef85040 + c177ed5 commit 41867aa
Show file tree
Hide file tree
Showing 23 changed files with 439 additions and 824 deletions.
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,16 @@ build: ## generate the dicedb binary for the current OS and architecture
@echo "Building for $(GOOS)/$(GOARCH)"
CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o ./dicedb

build-debug: ## generate the dicedb binary for the current OS and architecture
@echo "Building for $(GOOS)/$(GOARCH)"
CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) go build -gcflags="all=-N -l" -o ./dicedb

##@ Testing

# Changing the parallel package count to 1 due to a possible race condition which causes the tests to get stuck.
# TODO: Fix the tests to run in parallel, and remove the -p=1 flag.
test: ## run the integration tests
go test -v -race -count=1 -p=1 ./integration_tests/...
go test -race -count=1 -p=1 ./integration_tests/...

test-one: ## run a single integration test function by name (e.g. make test-one TEST_FUNC=TestSetGet)
go test -v -race -count=1 --run $(TEST_FUNC) ./integration_tests/...
Expand Down
12 changes: 0 additions & 12 deletions docs/src/content/docs/commands/OBJECT.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ OBJECT <subcommand> <key>
- `<subcommand>`: The specific operation you want to perform on the key. The available subcommands are:

- `REFCOUNT`: Returns the number of references of the value associated with the specified key.
- `ENCODING`: Returns the internal representation (encoding) used to store the value associated with the specified key.
- `IDLETIME`: Returns the number of seconds since the object was last accessed.
- `FREQ`: Returns the access frequency of a key, if the LFU (Least Frequently Used) eviction policy is enabled.

Expand All @@ -27,7 +26,6 @@ OBJECT <subcommand> <key>
The return value depends on the subcommand used:

- `REFCOUNT`: Returns an integer representing the reference count of the key.
- `ENCODING`: Returns a string representing the encoding type of the key.
- `IDLETIME`: Returns an integer representing the idle time in seconds.
- `FREQ`: Returns an integer representing the access frequency of the key.

Expand All @@ -38,7 +36,6 @@ When the `OBJECT` command is executed, DiceDB inspects the specified key and ret
### Subcommand Behaviours

- `REFCOUNT`: This subcommand returns the number of references to the key's value. A higher reference count indicates that the value is being shared among multiple keys or clients.
- `ENCODING`: This subcommand reveals the internal representation of the key's value, such as `int`, `embstr`, `raw`, `ziplist`, `linkedlist`, etc.
- `IDLETIME`: This subcommand provides the time in seconds since the key was last accessed. It is useful for identifying stale keys.
- `FREQ`: This subcommand returns the access frequency of the key, which is useful when using the LFU eviction policy.

Expand All @@ -61,15 +58,6 @@ OBJECT REFCOUNT mykey

This response indicates that the value associated with `mykey` has a reference count of 1.

### Using the `ENCODING` Subcommand

```bash
OBJECT ENCODING mykey
"embstr"
```

This response indicates that the value associated with `mykey` is stored using the `embstr` encoding.

### Using the `IDLETIME` Subcommand

```bash
Expand Down
5 changes: 0 additions & 5 deletions docs/src/pages/redis-compatability.astro
Original file line number Diff line number Diff line change
Expand Up @@ -776,11 +776,6 @@ const description = "";
<td>MSETNX</td>
<td><a href="/commands/"></a></td>
</tr>
<tr>
<td><a href="/commands/"></a></td>
<td>OBJECT|ENCODING</td>
<td><a href="/commands/"></a></td>
</tr>
<tr>
<td><a href="/commands/"></a></td>
<td>OBJECT|FREQ</td>
Expand Down
4 changes: 2 additions & 2 deletions integration_tests/commands/resp/deque_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ func TestLInsert(t *testing.T) {
{
name: "LINSERT wrong type",
cmds: []string{"SET k1 val1", "LINSERT k1 before val1 val2"},
expect: []any{"OK", "WRONGTYPE Operation against a key holding the wrong kind of value"},
expect: []any{"OK", "-WRONGTYPE Operation against a key holding the wrong kind of value"},
},
}

Expand Down Expand Up @@ -512,7 +512,7 @@ func TestLRange(t *testing.T) {
{
name: "LRANGE wrong type",
cmds: []string{"SET k1 val1", "LRANGE k1 0 100"},
expect: []any{"OK", "WRONGTYPE Operation against a key holding the wrong kind of value"},
expect: []any{"OK", "-WRONGTYPE Operation against a key holding the wrong kind of value"},
},
}

Expand Down
81 changes: 0 additions & 81 deletions integration_tests/commands/resp/object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ func TestObjectCommand(t *testing.T) {
conn := getLocalConnection()
defer conn.Close()
defer FireCommand(conn, "FLUSHDB")
simpleJSON := `{"name":"John","age":30}`

testCases := []struct {
name string
Expand All @@ -29,86 +28,6 @@ func TestObjectCommand(t *testing.T) {
delay: []time.Duration{0, 2 * time.Second, 3 * time.Second, 0, 0},
cleanup: []string{"DEL foo"},
},
{
name: "Object Encoding check for raw",
commands: []string{"SET foo foobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobar", "OBJECT ENCODING foo"},
expected: []interface{}{"OK", "raw"},
assertType: []string{"equal", "equal"},
delay: []time.Duration{0, 0},
cleanup: []string{"DEL foo"},
},
{
name: "Object Encoding check for int",
commands: []string{"SET foo 1", "OBJECT ENCODING foo"},
expected: []interface{}{"OK", "int"},
assertType: []string{"equal", "equal"},
delay: []time.Duration{0, 0},
cleanup: []string{"DEL foo"},
},
{
name: "Object Encoding check for embstr",
commands: []string{"SET foo bar", "OBJECT ENCODING foo"},
expected: []interface{}{"OK", "embstr"},
assertType: []string{"equal", "equal"},
delay: []time.Duration{0, 0},
cleanup: []string{"DEL foo"},
},
{
name: "Object Encoding check for deque",
commands: []string{"LPUSH listKey 'value1'", "LPUSH listKey 'value2'", "OBJECT ENCODING listKey"},
expected: []interface{}{int64(1), int64(2), "deque"},
assertType: []string{"assert", "assert", "equal"},
delay: []time.Duration{0, 0, 0},
cleanup: []string{"DEL listKey"},
},
{
name: "Object Encoding check for bf",
commands: []string{"BF.ADD bloomkey value1", "BF.ADD bloomkey value2", "OBJECT ENCODING bloomkey"},
expected: []interface{}{int64(1), int64(1), "bf"},
assertType: []string{"assert", "assert", "equal"},
delay: []time.Duration{0, 0, 0},
cleanup: []string{"DEL bloomkey"},
},
{
name: "Object Encoding check for json",
commands: []string{`JSON.SET k10 $ ` + simpleJSON, "OBJECT ENCODING k10"},
expected: []interface{}{"OK", "json"},
assertType: []string{"equal", "equal"},
delay: []time.Duration{0, 0},
cleanup: []string{"DEL k10"},
},
{
name: "Object Encoding check for bytearray",
commands: []string{"SETBIT kbitset 0 1", "SETBIT kbitset 1 0", "SETBIT kbitset 2 1", "OBJECT ENCODING kbitset"},
expected: []interface{}{int64(0), int64(0), int64(0), "bytearray"},
assertType: []string{"assert", "assert", "assert", "equal"},
delay: []time.Duration{0, 0, 0, 0},
cleanup: []string{"DEL kbitset"},
},
{
name: "Object Encoding check for hashmap",
commands: []string{"HSET hashKey hKey hValue", "OBJECT ENCODING hashKey"},
expected: []interface{}{int64(1), "hashmap"},
assertType: []string{"assert", "equal"},
delay: []time.Duration{0, 0},
cleanup: []string{"DEL hashKey"},
},
{
name: "Object Encoding check for btree",
commands: []string{"ZADD btreekey 1 'member1' 2 'member2'", "OBJECT ENCODING btreekey"},
expected: []interface{}{int64(2), "btree"},
assertType: []string{"equal", "equal"},
delay: []time.Duration{0, 0},
cleanup: []string{"DEL btreekey"},
},
{
name: "Object Encoding check for setstr",
commands: []string{"SADD skey one two three", "OBJECT ENCODING skey"},
expected: []interface{}{int64(3), "setstr"},
assertType: []string{"assert", "equal"},
delay: []time.Duration{0, 0},
cleanup: []string{"DEL skey"},
},
}

for _, tc := range testCases {
Expand Down
7 changes: 2 additions & 5 deletions internal/eval/bloom.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,13 +298,10 @@ func GetBloomFilter(key string, store *dstore.Store) (*Bloom, error) {
if obj == nil {
return nil, nil
}
if err := object.AssertType(obj.TypeEncoding, object.ObjTypeBitSet); err != nil {
if err := object.AssertType(obj.Type, object.ObjTypeBF); err != nil {
return nil, diceerrors.ErrWrongTypeOperation
}

if err := object.AssertEncoding(obj.TypeEncoding, object.ObjEncodingBF); err != nil {
return nil, diceerrors.ErrWrongTypeOperation
}
return obj.Value.(*Bloom), nil
}

Expand All @@ -319,7 +316,7 @@ func CreateBloomFilter(key string, store *dstore.Store, opts *BloomOpts) (*Bloom
if opts == nil {
opts = defaultBloomOpts()
}
obj := store.NewObj(newBloomFilter(opts), -1, object.ObjTypeBitSet, object.ObjEncodingBF)
obj := store.NewObj(newBloomFilter(opts), -1, object.ObjTypeBF)
store.Put(key, obj)
return obj.Value.(*Bloom), nil
}
33 changes: 13 additions & 20 deletions internal/eval/bytearray.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ func NewByteArrayFromObj(obj *object.Obj) (*ByteArray, error) {
}

func getValueAsByteSlice(obj *object.Obj) ([]byte, error) {
oType, oEnc := object.ExtractTypeEncoding(obj)
oType := object.ExtractType(obj)
switch oType {
case object.ObjTypeInt:
return []byte(strconv.FormatInt(obj.Value.(int64), 10)), nil
case object.ObjTypeString:
return getStringValueAsByteSlice(obj, oEnc)
return getStringValueAsByteSlice(obj)
// TODO: Have this case as SETBIT stores values encoded as byte arrays. Need to investigate this further.
case object.ObjTypeByteArray:
return getByteArrayValueAsByteSlice(obj)
Expand All @@ -50,24 +50,24 @@ func getValueAsByteSlice(obj *object.Obj) ([]byte, error) {
}
}

func getStringValueAsByteSlice(obj *object.Obj, oEnc uint8) ([]byte, error) {
switch oEnc {
case object.ObjEncodingInt:
func getStringValueAsByteSlice(obj *object.Obj) ([]byte, error) {
switch obj.Type {
case object.ObjTypeInt:
intVal, ok := obj.Value.(int64)
if !ok {
return nil, errors.New("expected integer value but got another type")
}

return []byte(strconv.FormatInt(intVal, 10)), nil
case object.ObjEncodingEmbStr, object.ObjEncodingRaw:
case object.ObjTypeString:
strVal, ok := obj.Value.(string)
if !ok {
return nil, errors.New("expected string value but got another type")
}

return []byte(strVal), nil
default:
return nil, fmt.Errorf("unsupported encoding type: %d", oEnc)
return nil, fmt.Errorf("unsupported type type: %d", obj.Type)
}
}

Expand All @@ -81,12 +81,12 @@ func getByteArrayValueAsByteSlice(obj *object.Obj) ([]byte, error) {
}

// ByteSliceToObj converts a byte slice to an Obj of the specified type and encoding
func ByteSliceToObj(store *dstore.Store, oldObj *object.Obj, b []byte, objType, encoding uint8) (*object.Obj, error) {
func ByteSliceToObj(store *dstore.Store, oldObj *object.Obj, b []byte, objType uint8) (*object.Obj, error) {
switch objType {
case object.ObjTypeInt:
return ByteSliceToIntObj(store, oldObj, b)
case object.ObjTypeString:
return ByteSliceToStringObj(store, oldObj, b, encoding)
return ByteSliceToStringObj(store, oldObj, b)
case object.ObjTypeByteArray:
return ByteSliceToByteArrayObj(store, oldObj, b)
default:
Expand All @@ -100,19 +100,12 @@ func ByteSliceToIntObj(store *dstore.Store, oldObj *object.Obj, b []byte) (*obje
if err != nil {
return store.NewObj(string(b), -1, object.ObjTypeString, object.ObjEncodingEmbStr), nil

Check failure on line 101 in internal/eval/bytearray.go

View workflow job for this annotation

GitHub Actions / build

too many arguments in call to store.NewObj

Check failure on line 101 in internal/eval/bytearray.go

View workflow job for this annotation

GitHub Actions / build

undefined: object.ObjEncodingEmbStr

Check failure on line 101 in internal/eval/bytearray.go

View workflow job for this annotation

GitHub Actions / lint

too many arguments in call to store.NewObj

Check failure on line 101 in internal/eval/bytearray.go

View workflow job for this annotation

GitHub Actions / lint

undefined: object.ObjEncodingEmbStr (typecheck)

Check failure on line 101 in internal/eval/bytearray.go

View workflow job for this annotation

GitHub Actions / lint

too many arguments in call to store.NewObj

Check failure on line 101 in internal/eval/bytearray.go

View workflow job for this annotation

GitHub Actions / lint

undefined: object.ObjEncodingEmbStr (typecheck)

Check failure on line 101 in internal/eval/bytearray.go

View workflow job for this annotation

GitHub Actions / lint

too many arguments in call to store.NewObj

Check failure on line 101 in internal/eval/bytearray.go

View workflow job for this annotation

GitHub Actions / lint

undefined: object.ObjEncodingEmbStr (typecheck)

Check failure on line 101 in internal/eval/bytearray.go

View workflow job for this annotation

GitHub Actions / lint

too many arguments in call to store.NewObj

Check failure on line 101 in internal/eval/bytearray.go

View workflow job for this annotation

GitHub Actions / lint

undefined: object.ObjEncodingEmbStr (typecheck)

Check failure on line 101 in internal/eval/bytearray.go

View workflow job for this annotation

GitHub Actions / lint

too many arguments in call to store.NewObj

Check failure on line 101 in internal/eval/bytearray.go

View workflow job for this annotation

GitHub Actions / lint

undefined: object.ObjEncodingEmbStr (typecheck)
}
return store.NewObj(intVal, -1, object.ObjTypeInt, object.ObjEncodingInt), nil
return store.NewObj(intVal, -1, object.ObjTypeInt), nil
}

// ByteSliceToStringObj converts a byte slice to an Obj with a string value
func ByteSliceToStringObj(store *dstore.Store, oldObj *object.Obj, b []byte, encoding uint8) (*object.Obj, error) {
switch encoding {
case object.ObjEncodingInt:
return ByteSliceToIntObj(store, oldObj, b)
case object.ObjEncodingEmbStr, object.ObjEncodingRaw:
return store.NewObj(string(b), -1, object.ObjTypeString, object.ObjEncodingEmbStr), nil
default:
return nil, fmt.Errorf("unsupported encoding type")
}
func ByteSliceToStringObj(store *dstore.Store, oldObj *object.Obj, b []byte) (*object.Obj, error) {
return store.NewObj(string(b), -1, object.ObjTypeString), nil
}

// ByteSliceToByteArrayObj converts a byte slice to an Obj with a ByteArray value
Expand All @@ -121,7 +114,7 @@ func ByteSliceToByteArrayObj(store *dstore.Store, oldObj *object.Obj, b []byte)
data: b,
Length: int64(len(b)),
}
return store.NewObj(byteValue, -1, object.ObjTypeByteArray, object.ObjEncodingByteArray), nil
return store.NewObj(byteValue, -1, object.ObjTypeByteArray), nil
}

// SetBit sets the bit at the given position to the specified value
Expand Down
8 changes: 2 additions & 6 deletions internal/eval/countminsketch.go
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ func createCountMinSketch(key string, opts *CountMinSketchOpts, store *dstore.St
return diceerrors.NewErr("key already exists")
}

obj = store.NewObj(newCountMinSketch(opts), -1, object.ObjTypeCountMinSketch, object.ObjEncodingMatrix)
obj = store.NewObj(newCountMinSketch(opts), -1, object.ObjTypeCountMinSketch)
store.Put(key, obj)

return nil
Expand All @@ -526,11 +526,7 @@ func getCountMinSketch(key string, store *dstore.Store) (*CountMinSketch, error)
return nil, diceerrors.NewErr("key does not exist")
}

if err := object.AssertType(obj.TypeEncoding, object.ObjTypeCountMinSketch); err != nil {
return nil, err
}

if err := object.AssertEncoding(obj.TypeEncoding, object.ObjEncodingMatrix); err != nil {
if err := object.AssertTypeWithError(obj.Type, object.ObjTypeCountMinSketch); err != nil {
return nil, err
}

Expand Down
6 changes: 3 additions & 3 deletions internal/eval/dump_restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func readString(data []byte) (*object.Obj, error) {
return nil, err
}

return &object.Obj{TypeEncoding: object.ObjTypeString, Value: string(strBytes)}, nil
return &object.Obj{Type: object.ObjTypeString, Value: string(strBytes)}, nil
}

func readInt(data []byte) (*object.Obj, error) {
Expand All @@ -45,14 +45,14 @@ func readInt(data []byte) (*object.Obj, error) {
return nil, err
}

return &object.Obj{TypeEncoding: object.ObjTypeInt, Value: intVal}, nil
return &object.Obj{Type: object.ObjTypeInt, Value: intVal}, nil
}

func rdbSerialize(obj *object.Obj) ([]byte, error) {
var buf bytes.Buffer
buf.WriteByte(0x09)

switch object.GetType(obj.TypeEncoding) {
switch obj.Type {
case object.ObjTypeString:
str, ok := obj.Value.(string)
if !ok {
Expand Down
Loading

0 comments on commit 41867aa

Please sign in to comment.