Repository: DiceDB/dice
File: internal/eval/eval.go (Go)

Code before:
// If the approximated cardinality estimated by the HyperLogLog changed after executing the command,
// returns 1, otherwise 0 is returned.
func evalPFADD(args []string, store *dstore.Store) []byte {
	if len(args) < 1 {
		return diceerrors.NewErrArity("PFADD")
	}

	key := args[0]
	obj := store.Get(key)

	// If key doesn't exist prior initial cardinality changes hence return 1
	if obj == nil {
		hll := hyperloglog.New()
		for _, arg := range args[1:] {
			hll.Insert([]byte(arg))
		}

		obj = store.NewObj(hll, -1, object.ObjTypeString, object.ObjEncodingRaw)

		store.Put(key, obj)
		return clientio.Encode(1, false)
	}

	existingHll, ok := obj.Value.(*hyperloglog.Sketch)
	if !ok {
		return diceerrors.NewErrWithMessage("*WRONGTYPE*")
	}
	initialCardinality := existingHll.Estimate()
	for _, arg := range args[1:] {
		existingHll.Insert([]byte(arg))
	}

	if newCardinality := existingHll.Estimate(); initialCardinality != newCardinality {
		return clientio.Encode(1, false)
	}

	return clientio.Encode(0, false)
}

func evalPFCOUNT(args []string, store *dstore.Store) []byte {
	if len(args) < 1 {
		return diceerrors.NewErrArity("PFCOUNT")
	}

	var unionHll = hyperloglog.New()

	for _, arg := range args {
		obj := store.Get(arg)
		if obj != nil {
			currKeyHll, ok := obj.Value.(*hyperloglog.Sketch)
			if !ok {

Review comment (bug):
We shall change the error as below to maintain parity with Redis.
`WrongTypeHllErr    = "-WRONGTYPE Key is not a valid HyperLogLog string value."`

```
if !ok {
  return diceerrors.NewErrWithMessage(diceerrors.WrongTypeErr)
}
```

Output from Redis:
```
127.0.0.1:6379> pfadd hll a b c
(integer) 1
127.0.0.1:6379> setrange hll 0 "0123"
(integer) 27
127.0.0.1:6379> pfcount hll
(error) WRONGTYPE Key is not a valid HyperLogLog string value.
```

Code after:
// If the approximated cardinality estimated by the HyperLogLog changed after executing the command,
// returns 1, otherwise 0 is returned.
func evalPFADD(args []string, store *dstore.Store) []byte {
	if len(args) < 1 {
		return diceerrors.NewErrArity("PFADD")
	}

	key := args[0]
	obj := store.Get(key)

	// If key doesn't exist prior initial cardinality changes hence return 1
	if obj == nil {
		hll := hyperloglog.New()
		for _, arg := range args[1:] {
			hll.Insert([]byte(arg))
		}

		obj = store.NewObj(hll, -1, object.ObjTypeString, object.ObjEncodingRaw)

		store.Put(key, obj)
		return clientio.Encode(1, false)
	}

	existingHll, ok := obj.Value.(*hyperloglog.Sketch)
	if !ok {
		return diceerrors.NewErrWithMessage(diceerrors.WrongTypeHllErr)
	}
	initialCardinality := existingHll.Estimate()
	for _, arg := range args[1:] {
		existingHll.Insert([]byte(arg))
	}

	if newCardinality := existingHll.Estimate(); initialCardinality != newCardinality {
		return clientio.Encode(1, false)
	}

	return clientio.Encode(0, false)
}

func evalPFCOUNT(args []string, store *dstore.Store) []byte {
	if len(args) < 1 {
		return diceerrors.NewErrArity("PFCOUNT")
	}

	var unionHll = hyperloglog.New()

	for _, arg := range args {
		obj := store.Get(arg)
		if obj != nil {
			currKeyHll, ok := obj.Value.(*hyperloglog.Sketch)
			if !ok {