Skip to content

Commit 21cc2c0

Browse files
Config for start options cache (#36)
* feat: new struct Options to allow the user make own config in cache gokey/cache.go test: little chances to adapter new behavior gokey/cache_test.go refactor: change that functions hash to generate a callbacks gokey/hash.go test: little change in test TestGenerateMD5HashFromKey gokey/hash_test.go feat: new function to verified if user put the capacity of cache size gokey/helpers.go * refactor: change the catch err in write method gokey/hash.go refactor: delete variable err in hashFunc gokey/cache.go test: new test are add gokey/hash_test.go * refactor: delate the error return in hashFunc gokey/cache.go test : new test are add gokey/hash_test.go * fix: new comment add gokey/cache.go * fix: sanitize Options to prevent argument is empty or nil gokey/cache.go * feat: new type and constant for Ahash modified: gokey/cache.go fix: fix var name modified: gokey/cache_test.go * docs : new comment add gokey/cache.go * docs: add to Options struct gokey/cache.go
1 parent fa1ffe6 commit 21cc2c0

File tree

5 files changed

+102
-39
lines changed

5 files changed

+102
-39
lines changed

gokey/cache.go

+35-20
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,20 @@ import (
66
"time"
77
)
88

9+
type THash string
10+
11+
// constans to select type of hash algorithm, Example:Options{Ahash:MD5}
12+
var (
13+
MD5 = THash("md5")
14+
SHA256 = THash("sha256")
15+
SHA1 = THash("sha1")
16+
)
17+
918
type Cache struct {
1019
sync.RWMutex
1120
pairsSet map[string]tuple //contains expiration time and value of a key
1221

13-
hashFn func([]byte) (string, error)
22+
hashFn func([]byte) string
1423
}
1524

1625
type tuple struct {
@@ -19,6 +28,14 @@ type tuple struct {
1928
value []byte
2029
}
2130

31+
// Options allow at user set properties of cache like
32+
// maxsize or hash algorithm
33+
type Options struct {
34+
MaxSize int
35+
AHast THash
36+
TTL float64 // in Newcache or their methods?
37+
}
38+
2239
var (
2340
_ Operations = (*Cache)(nil)
2441

@@ -27,11 +44,20 @@ var (
2744
ErrExpiredKey = errors.New("key has expired")
2845
)
2946

30-
func newCache() *Cache {
47+
func newCache(o ...*Options) *Cache {
48+
var options *Options
49+
50+
if len(o) < 1 || o[0] == nil {
51+
options = &Options{}
52+
} else {
53+
options = o[0]
54+
}
55+
56+
hashFn := selectHash(options.AHast)
3157
return &Cache{
3258
RWMutex: sync.RWMutex{},
33-
pairsSet: make(map[string]tuple, getLimitPairsSet()),
34-
hashFn: generateMD5,
59+
pairsSet: make(map[string]tuple, sizeLimit(options.MaxSize)),
60+
hashFn: hashFn,
3561
}
3662
}
3763

@@ -44,10 +70,7 @@ func (c *Cache) Get(key string) ([]byte, error) {
4470
c.RLock()
4571
defer c.RUnlock()
4672

47-
keyHashed, err := c.hashFn([]byte(key))
48-
if err != nil {
49-
return nil, err
50-
}
73+
keyHashed := c.hashFn([]byte(key))
5174

5275
pair, exists := c.pairsSet[keyHashed]
5376

@@ -83,10 +106,7 @@ func (c *Cache) Upsert(key string, value []byte, ttl time.Duration) (bool, error
83106
c.Lock()
84107
defer c.Unlock()
85108

86-
keyHashed, err := c.hashFn([]byte(key))
87-
if err != nil {
88-
return false, err
89-
}
109+
keyHashed := c.hashFn([]byte(key))
90110

91111
if c.pairsSet == nil {
92112
c.pairsSet = make(map[string]tuple, getLimitPairsSet())
@@ -111,10 +131,8 @@ func (c *Cache) Delete(key string) (bool, error) {
111131
c.Lock()
112132
defer c.Unlock()
113133

114-
keyHashed, err := c.hashFn([]byte(key))
115-
if err != nil {
116-
return false, err
117-
}
134+
keyHashed := c.hashFn([]byte(key))
135+
118136
_, exists := c.pairsSet[keyHashed]
119137

120138
if exists {
@@ -134,10 +152,7 @@ func (c *Cache) Exists(key string) (bool, error) {
134152
c.RLock()
135153
defer c.RUnlock()
136154

137-
keyHashed, err := c.hashFn([]byte(key))
138-
if err != nil {
139-
return false, err
140-
}
155+
keyHashed := c.hashFn([]byte(key))
141156

142157
pair, exists := c.pairsSet[keyHashed]
143158

gokey/cache_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
"time"
99
)
1010

11-
var operations = newCache()
11+
var operations = newCache(&Options{AHast: MD5})
1212

1313
// go test -run TestCacheUpsert -v
1414
func TestCacheUpsert(t *testing.T) {

gokey/hash.go

+20-15
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,33 @@ package gokey
22

33
import (
44
"crypto/md5"
5-
"crypto/sha512"
5+
"crypto/sha1"
6+
"crypto/sha256"
67
"encoding/hex"
8+
"hash"
79
)
810

911
// generateMD5 is a hash generator function according to input(key)
1012
// using md5 algorithm.
11-
func generateMD5(key []byte) (string, error) {
12-
algorithm := md5.New()
13-
_, err := algorithm.Write(key)
14-
if err != nil {
15-
return "", err
13+
14+
func selectHash(hash THash) func([]byte) string {
15+
switch hash {
16+
case "sha256":
17+
return generateFromHash(sha256.New())
18+
case "sha1":
19+
return generateFromHash(sha1.New())
20+
default:
21+
return generateFromHash(md5.New())
1622
}
17-
return hex.EncodeToString(algorithm.Sum(nil)), nil
1823
}
1924

20-
// generateSHA512
21-
func generateSHA512(input string) (string, error) {
22-
hasher := sha512.New()
23-
_, err := hasher.Write([]byte(input))
24-
if err != nil {
25-
return "", err
25+
func generateFromHash(algorithm hash.Hash) func([]byte) string {
26+
27+
return func(key []byte) string {
28+
algorithm.Reset()
29+
// write never return error
30+
algorithm.Write(key)
31+
32+
return hex.EncodeToString(algorithm.Sum(nil))
2633
}
27-
hash := hasher.Sum(nil)
28-
return hex.EncodeToString(hash), nil
2934
}

gokey/hash_test.go

+39-3
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,59 @@ package gokey
22

33
import "testing"
44

5-
type hashMD5Test struct {
5+
type hashTest struct {
66
input []byte
77
output string
88
}
99

1010
func TestGenerateMD5HashFromKey(t *testing.T) {
11-
tests := []hashMD5Test{
11+
tests := []hashTest{
1212
{[]byte("foo"), "acbd18db4cc2f85cedef654fccc4a4d8"},
1313
{[]byte("bar"), "37b51d194a7513e45b56f6524f2d51f2"},
1414
{[]byte("gopher"), "ca654591d4ac97414391907f882b3c05"},
1515
{[]byte("Irregardless"), "7dac0723ab11aec37ae53d26df848282"},
1616
{[]byte("earthquake"), "e9ad9c2394f7dc7b6a69fb43e52a7382"},
1717
{[]byte("endeavor"), "c5f5aaefa43684051f6fa380eef4b59e"},
1818
}
19+
generateMD5 := selectHash(MD5)
20+
for _, v := range tests {
21+
if out := generateMD5(v.input); out != v.output {
22+
t.Errorf("Find %s, expected %s", string(v.output), out)
23+
}
24+
}
1925

26+
}
27+
28+
func TestGenerateSha1HashFromKey(t *testing.T) {
29+
tests := []hashTest{
30+
{[]byte("foo"), "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"},
31+
{[]byte("bar"), "62cdb7020ff920e5aa642c3d4066950dd1f01f4d"},
32+
{[]byte("gopher"), "4188736a00fbfb506aca06281acf338290455c21"},
33+
{[]byte("Irregardless"), "bd633cd299f2b91082944cd661e21923f106bff2"},
34+
{[]byte("earthquake"), "e8dea393aacba5f48ec3fdfd16114a89a2b59c63"},
35+
{[]byte("endeavor"), "2c84ef5af854a4eefb5832ffc01d8c0edd261645"},
36+
}
37+
generateSha1 := selectHash(SHA1)
38+
for _, v := range tests {
39+
if out := generateSha1(v.input); out != v.output {
40+
t.Errorf("Find %s, expected %s", string(v.output), out)
41+
}
42+
}
43+
44+
}
45+
46+
func TestGenerateSha256HashFromKey(t *testing.T) {
47+
tests := []hashTest{
48+
{[]byte("foo"), "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"},
49+
{[]byte("bar"), "fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9"},
50+
{[]byte("gopher"), "9cc1ee455a3363ffc504f40006f70d0c8276648a5d3eb3f9524e94d1b7a83aef"},
51+
{[]byte("Irregardless"), "5bf4000a8a603e715286ad206e46a40e930c9e20998bf3ea36ddf687e6acced2"},
52+
{[]byte("earthquake"), "fa7835fc1c74a9e014c750a4f452b56f215702a9802d386a0560e5099da94fbb"},
53+
{[]byte("endeavor"), "1cd38b20bf937895efffc247bd9b85abbacfc5bfe21bfc12a44efa47a1da2343"},
54+
}
55+
generateSha256 := selectHash(SHA256)
2056
for _, v := range tests {
21-
if out, err := generateMD5(v.input); err != nil || out != v.output {
57+
if out := generateSha256(v.input); out != v.output {
2258
t.Errorf("Find %s, expected %s", string(v.output), out)
2359
}
2460
}

gokey/helpers.go

+7
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,10 @@ package gokey
33
func isEmpty(key string) bool {
44
return key == ""
55
}
6+
7+
func sizeLimit(slimit int) int {
8+
if slimit < 1 {
9+
return getLimitPairsSet()
10+
}
11+
return slimit
12+
}

0 commit comments

Comments
 (0)