Skip to content

Instantly share code, notes, and snippets.

@polosaty
Last active October 21, 2022 19:42
Show Gist options
  • Save polosaty/60dd10cf9b4ae0a2e4eb91253c9c78c4 to your computer and use it in GitHub Desktop.
Save polosaty/60dd10cf9b4ae0a2e4eb91253c9c78c4 to your computer and use it in GitHub Desktop.
package main
import (
"errors"
"hash"
"hash/fnv"
"log"
)
type Store struct {
count int
table []*Node
h64 hash.Hash64
}
type Node struct {
Key string
Value int
Next *Node
}
func NewStore() *Store {
return &Store{
table: make([]*Node, 1),
h64: fnv.New64a(),
}
}
func (s *Store) hash(key string) uint64 {
defer s.h64.Reset()
if _, err := s.h64.Write([]byte(key)); err != nil {
log.Println("hash of key: ", key, " raised error: ", err)
}
return s.h64.Sum64() % uint64(len(s.table))
}
func NewNode(key string, value int, next *Node) *Node {
return &Node{
key, value, next,
}
}
func (s *Store) put(key string, value int) {
j := s.hash(key)
for node := s.table[j]; node != nil; node = node.Next {
if key == node.Key {
node.Value = value
return
}
}
if s.count >= len(s.table) {
s.rehash()
j = s.hash(key)
}
s.table[j] = NewNode(key, value, s.table[j])
s.count++
}
func (s *Store) rehash() {
oldTable := s.table
s.table = make([]*Node, len(oldTable)*2)
s.count = 0
for _, tab := range oldTable {
for node := tab; node != nil; node = node.Next {
s.put(node.Key, node.Value)
}
}
}
var NotFoundErr = errors.New("node not found")
func (s *Store) get(key string) (int, error) {
j := s.hash(key)
for node := s.table[j]; node != nil; node = node.Next {
if key == node.Key {
return node.Value, nil
}
}
return 0, NotFoundErr
}
func check(key string, value int, s *Store) {
v, err := s.get(key)
if err != nil {
log.Println("search key:", key, "err:", err)
return
}
if v == value {
log.Println(key, " is ok")
} else {
log.Println(key, " is broken")
}
}
func main() {
s := NewStore()
s.put("cat", 10)
s.put("dog", 20)
s.put("fox", 30)
s.put("art", 40)
s.put("car", 50)
s.put("cat", 60)
check("cat", 60, s)
check("dog", 20, s)
check("fox", 30, s)
check("art", 40, s)
check("car", 50, s)
check("crow", 0, s) // search key: crow err: node not found
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment