Git Product home page Git Product logo

kiwi's Introduction

Kiwi Logo

A minimalistic in-memory key value store.

Go CI Docs CI Docs CD PkgGoDev

Overview

You can think of Kiwi as thread safe global variables. This kind of library comes in helpful when you need to manage state across your application which can be mutated with multiple threads. Kiwi protects your keys with mutex locks so you don't have to.

Head over to kiwi.sdslabs.co for more details and documentation.

Installation

Kiwi requires Go >= 1.14

Kiwi can be integrated with your application just like any other go library.

go get -u github.com/sdslabs/kiwi

Now you can import kiwi any where in your code.

import "github.com/sdslabs/kiwi"

Basic usage

Create a store, add key and play with it. It's that easy!

store := stdkiwi.NewStore()

if err := store.AddKey("my_string", "str"); err != nil {
  // handle error
}

myString := store.Str("my_string")

if err := myString.Update("Hello, World!"); err != nil {
  // handle error
}

str, err := myString.Get()
if err != nil {
  // handle error
}

fmt.Println(str) // Hello, World!

Check out the tutorial to learn how to use Kiwi.

Benchmarks

Following are the benchmarks comparing Kiwi with BuntDB on a MacBook Pro (8th gen Intel i5 2.4GHz processor, 8GB RAM).

❯ go test -bench=. -test.benchmem ./benchmark
goos: darwin
goarch: amd64
pkg: github.com/sdslabs/kiwi/benchmark
BenchmarkBuntDB_Update-8        11777931                96.6 ns/op            48 B/op          1 allocs/op
BenchmarkBuntDB_View-8          23310963                47.1 ns/op            48 B/op          1 allocs/op
BenchmarkKiwi_Update-8          10356004               115 ns/op              48 B/op          3 allocs/op
BenchmarkKiwi_Get-8             21910110                53.2 ns/op             0 B/op          0 allocs/op
PASS
ok      github.com/sdslabs/kiwi/benchmark       6.216s

Following are the key differences due to which Kiwi is a little slow:

  1. BuntDB supports transactions, i.e., it locks the database once to apply all the operations (and this is what is tested).
  2. Kiwi supports dynamic data-types, which means, allocation on heap at runtime (interface{}) whereas BuntDB is statically typed.

The above two differences are what makes Kiwi unique and suitable to use on many occasions. Due to the aforementioned reasons, Kiwi can support typed values and not everything is just another "string".

There are places where we could improve more. Some performance issues also lie in the implementation of values. For example, when updating a string, not returning the updated string avoids an extra allocation.

Contributing

We are always open for contributions. If you find any feature missing, or just want to report a bug, feel free to open an issue and/or submit a pull request regarding the same.

For more information on contribution, check out our docs.

Contact

If you have a query regarding the product or just want to say hello then feel free to visit chat.sdslabs.co or drop a mail at [email protected]


Made by SDSLabs

kiwi's People

Contributors

carmo-evan avatar cypherean avatar murex971 avatar vrngupta53 avatar vrongmeal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kiwi's Issues

Add zhash value type

It would be great to have a "zhash" in standard set of values. This would be similar to zset (or scored set) with the difference that a zhash will have a value along with the score.

A zset can be thought of as:

Key Score
key_one 10
key_two 20
key_three 30

whereas a zhash will be:

Key Score Value
key_one 10 val_one
key_two 20 val_two
key_three 30 val_three

For documentation on how to add a new value type, see: https://kiwi.sdslabs.co/docs/add-new-value-type.html

Add Time to Live for values

This requires a little thought on how it should be implemented but the basic idea is after d duration a key should have empty value.

This might require the following method in the Value interface:

  // IsEmpty tells if the value is empty or not.
  IsEmpty() error

The store can then implement a method, called, IsClean:

// IsEmpty tells if the value associated with the key is empty or not.
func (s *Store) IsEmpty(key string) (bool, error)

// SetTTL sets the time to live for value.
//
// Calls `UpdateKey` after "d" duration, which by default sets the empty value.
func (s *Store) SetTTL(key string, d time.Duration) error

A new SchemaTTL can be added to define schema with TTL. Changes are made this way such that this version remains compatible with the previous version as well.

type SchemaTTL map[string]ValueTTL

type ValueTTL struct {
  TTL  time.Duration
  Type ValueType
}

// Correspondingly a new method called `NewStoreWithSchemaTTL`
func NewStoreWithSchemaTTL(schema SchemaTTL) (*Store, error)

export fatal err: Unlock of unlocked RWMutex

This function fails on store.Export()

func MakeStorage(){
	store := stdkiwi.NewStore()
	for i := 0; i < 10; i++ {
		res, err := http.Get("http://whatthecommit.com/index.txt")
		if err != nil {
			log.Fatal()
			return
		}
		if err := store.AddKey(strconv.Itoa(i), "str"); err != nil {
			panic(err)
		}
		comm := store.Str(strconv.Itoa(i))
		msg, err := ioutil.ReadAll(res.Body)
		if err != nil {
			log.Fatal(err)
			return
		}
		err = comm.Update(string(msg))
		if err != nil {
			log.Fatal(err)
			return
		}
		err = res.Body.Close()
		if err != nil {
			log.Fatal(err)
			return
		}
		log.Println("written", i, "to file")
	}
	js, err :=store.Export()
	if err != nil {
		log.Fatal(err)
		return
	}
	err = ioutil.WriteFile("commits.json", js, os.ModePerm)
	if err != nil {
		log.Fatal(err)
		return
	}
}
fatal error: sync: Unlock of unlocked RWMutex

goroutine 1 [running]:
runtime.throw(0x3e9b00, 0x20)
	C:/Go/src/runtime/panic.go:1116 +0x79 fp=0xc0000c9ca8 sp=0xc0000c9c78 pc=0x138a19
sync.throw(0x3e9b00, 0x20)
	C:/Go/src/runtime/panic.go:1102 +0x3c fp=0xc0000c9cc8 sp=0xc0000c9ca8 pc=0x16521c
sync.(*RWMutex).Unlock(0xc00020c080)
	C:/Go/src/sync/rwmutex.go:129 +0xc6 fp=0xc0000c9d00 sp=0xc0000c9cc8 pc=0x184006
github.com/sdslabs/kiwi.(*Store).Export(0xc0000985e0, 0x3, 0x3, 0x3dffd9, 0x6, 0xc000089280)
	C:/Users/poly/go/pkg/mod/github.com/sdslabs/[email protected]/store.go:279 +0x23b fp=0xc0000c9e70 sp=0xc0000c9d00 pc=0x1fe8db
github.com/po1yb1ank/gocommit/commitstorage.MakeStorage()
	C:/Users/poly/wsp/testt/gocommit/commitstorage/storage.go:41 +0x56a fp=0xc0000c9f78 sp=0xc0000c9e70 pc=0x3666aa
main.main()
	C:/Users/poly/wsp/testt/gocommit/commit.go:27 +0x27 fp=0xc0000c9f88 sp=0xc0000c9f78 pc=0x366847
runtime.main()
	C:/Go/src/runtime/proc.go:204 +0x209 fp=0xc0000c9fe0 sp=0xc0000c9f88 pc=0x13b1c9
runtime.goexit()
	C:/Go/src/runtime/asm_amd64.s:1374 +0x1 fp=0xc0000c9fe8 sp=0xc0000c9fe0 pc=0x16a3a1

goroutine 5 [IO wait]:
internal/poll.runtime_pollWait(0x20ce113a708, 0x72, 0x439260)
	C:/Go/src/runtime/netpoll.go:222 +0x65
internal/poll.(*pollDesc).wait(0xc0000cf0b8, 0x72, 0x573300, 0x0, 0x0)
	C:/Go/src/internal/poll/fd_poll_runtime.go:87 +0x4c
internal/poll.execIO(0xc0000cef18, 0x3f82a0, 0xc00003ba01, 0x1be18d, 0x602fa544)
	C:/Go/src/internal/poll/fd_windows.go:175 +0x105
internal/poll.(*FD).Read(0xc0000cef00, 0xc000044000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	C:/Go/src/internal/poll/fd_windows.go:441 +0x2ff
net.(*netFD).Read(0xc0000cef00, 0xc000044000, 0x1000, 0x1000, 0x13b665, 0xc00003bb58, 0x1627e0)
	C:/Go/src/net/fd_posix.go:55 +0x56
net.(*conn).Read(0xc000006010, 0xc000044000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	C:/Go/src/net/net.go:182 +0x95
net/http.(*persistConn).Read(0xc0000de6c0, 0xc000044000, 0x1000, 0x1000, 0xc000180000, 0xc00003bc58, 0x105ab5)
	C:/Go/src/net/http/transport.go:1887 +0x7c
bufio.(*Reader).fill(0xc00003e060)
	C:/Go/src/bufio/bufio.go:101 +0x10a
bufio.(*Reader).Peek(0xc00003e060, 0x1, 0x0, 0x0, 0x1, 0x0, 0xc000123920)
	C:/Go/src/bufio/bufio.go:139 +0x56
net/http.(*persistConn).readLoop(0xc0000de6c0)
	C:/Go/src/net/http/transport.go:2040 +0x1ba
created by net/http.(*Transport).dialConn
	C:/Go/src/net/http/transport.go:1708 +0xcd7

goroutine 6 [select]:
net/http.(*persistConn).writeLoop(0xc0000de6c0)
	C:/Go/src/net/http/transport.go:2340 +0x134
created by net/http.(*Transport).dialConn
	C:/Go/src/net/http/transport.go:1709 +0xcfc

  • go 1.15
  • github.com/sdslabs/kiwi v1.1.0

Wrappers for other languages

Is your feature request related to a problem? Please describe.
This doesn't have support for other languages.

Describe the solution you'd like
wrappers to languages like C++, python.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.