Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement zhash value #17

Merged
merged 5 commits into from
Oct 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions stdkiwi/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,14 @@ func (s *Store) Zset(key string) *Zset {
}
}

// Zhash returns a "Zhash" with the key set as "key".
func (s *Store) Zhash(key string) *Zhash {
return &Zhash{
store: s,
key: key,
}
}

// Value can be used to access the methods for standard value types.
type Value interface {
// Guard should panic if the key does not correspond to the correct type.
Expand Down
131 changes: 131 additions & 0 deletions stdkiwi/zhash.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// Copyright (c) 2020 SDSLabs
// Use of this source code is governed by an MIT license
// details of which can be found in the LICENSE file.

package stdkiwi

import (
"github.com/sdslabs/kiwi/values/zhash"
)

// Zhash implements methods for zhash value type.
type Zhash struct {
store *Store
key string
}

// Guard guards the keys with values of str type.
func (z *Zhash) Guard() {
if err := z.GuardE(); err != nil {
panic(err)
}
}

// GuardE is same as Guard but does not panic, instead returns the error.
func (z *Zhash) GuardE() error { return z.store.guardValueE(zhash.Type, z.key) }

// Insert inserts the elements to the zhash.
func (z *Zhash) Insert(key, value string) error {
if _, err := z.store.Do(z.key, zhash.Insert, key, value); err != nil {
return err
}
return nil
}

// Set sets the value of an pre-existing key of the zhash.
func (z *Zhash) Set(key, value string) error {
if _, err := z.store.Do(z.key, zhash.Set, key, value); err != nil {
return err
}
return nil
}

// Remove removes the elements from the zhash.
func (z *Zhash) Remove(elements ...string) error {
if len(elements) == 0 {
return nil
}

ifaces := make([]interface{}, len(elements))
for i := range elements {
ifaces[i] = elements[i]
}

if _, err := z.store.Do(z.key, zhash.Remove, ifaces...); err != nil {
return err
}

return nil
}

// Increment increment the score of element of the zhash.
func (z *Zhash) Increment(element string, score int) error {
if _, err := z.store.Do(z.key, zhash.Increment, element, score); err != nil {
return err
}

return nil
}

// Get gets the value and the score of element from the zhash.
func (z *Zhash) Get(element string) (zhash.Item, error) {
v, err := z.store.Do(z.key, zhash.Get, element)
if err != nil {
return zhash.Item{}, err
}

val, ok := v.(zhash.Item)
if !ok {
return zhash.Item{}, newTypeErr(val, v)
}

return val, nil
}

// Len gets the length of the zhash.
func (z *Zhash) Len() (int, error) {
v, err := z.store.Do(z.key, zhash.Len)
if err != nil {
return 0, err
}

length, ok := v.(int)
if !ok {
return 0, newTypeErr(length, v)
}

return length, nil
}

// PeekMax gets the element with highest score from the zhash.
func (z *Zhash) PeekMax() (string, error) {
v, err := z.store.Do(z.key, zhash.PeekMax)
if err != nil {
return "", err
}

val, ok := v.(string)
if !ok {
return "", newTypeErr(val, v)
}

return val, nil
}

// PeekMin gets the element with minimum score from the zhash.
func (z *Zhash) PeekMin() (string, error) {
v, err := z.store.Do(z.key, zhash.PeekMin)
if err != nil {
return "", err
}

val, ok := v.(string)
if !ok {
return "", newTypeErr(val, v)
}

return val, nil
}

// Interface guard.
var _ Value = (*Set)(nil)
85 changes: 85 additions & 0 deletions stdkiwi/zhash_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright (c) 2020 SDSLabs
// Use of this source code is governed by an MIT license
// details of which can be found in the LICENSE file.

package stdkiwi

import (
"testing"

"github.com/sdslabs/kiwi/values/zhash"
)

func TestZHash(t *testing.T) {
store := newTestStore(t, zhash.Type)
s := store.Zhash(testKey)

// check that it does not panic
s.Guard()

// and the same should work with GuardE as well
if err := s.GuardE(); err != nil {
t.Errorf("GuardE threw an error for default testKey: %v", err)
}

if err := s.Insert("a", "b"); err != nil {
t.Errorf("could not Insert: %v", err)
}
if err := s.Insert("c", "d"); err != nil {
t.Errorf("could not Insert: %v", err)
}

if err := s.Set("a", "e"); err != nil {
t.Errorf("could not Update: %v", err)
}

length, err := s.Len()
if err != nil {
t.Errorf("could not Len: %v", err)
}

if length != 2 {
t.Errorf("expected length of zset: %d; got %d", 2, length)
}

// updating score to some non zero values.

if err = s.Increment("a", 5); err != nil {
t.Errorf("could not increment: %v", err)
}

item, err := s.Get("c")
if err != nil {
t.Errorf("could not Get: %v", err)
}

if item.Score != 0 {
t.Errorf("expected score: %d; got: %d", 0, item.Score)
}

if item.Value != "d" {
t.Errorf("expected value: d; got %v", item.Value)
}

maxstr, err := s.PeekMax()
if err != nil {
t.Errorf("could not PeekMax: %v", err)
}

if maxstr != "a" {
t.Errorf("expected element: %q; got: %q", "a", maxstr)
}

minstr, err := s.PeekMin()
if err != nil {
t.Errorf("could not PeekMin: %v", err)
}

if minstr != "c" {
t.Errorf("expected element: %q; got: %q", "f", minstr)
}

if err := s.Remove("a", "c"); err != nil {
t.Errorf("Unexpected error when removing elements: %v", err)
}
}
7 changes: 7 additions & 0 deletions values/zhash/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright (c) 2020 SDSLabs
// Use of this source code is governed by an MIT license
// details of which can be found in the LICENSE file.

// Package zhash implements a kiwi.Value which can store a hash
// with each element having a value and a score.
package zhash
Loading