Skip to content

Commit 05e0f3a

Browse files
committed
Seperate name spaces for parameters and sections, eases implementations.
1 parent f587e84 commit 05e0f3a

File tree

3 files changed

+100
-35
lines changed

3 files changed

+100
-35
lines changed

Diff for: impl/memory/memory.go

+48-31
Original file line numberDiff line numberDiff line change
@@ -7,63 +7,80 @@ import (
77
)
88

99
func New() persistence.Section {
10-
return &memory{m: &sync.RWMutex{}, kv: make(map[string]interface{})}
10+
return &memory{m: &sync.RWMutex{}, kv: make(map[string]interface{}), sections: make(map[string]persistence.Section)}
1111
}
1212

1313
type memory struct {
14-
m *sync.RWMutex
15-
kv map[string]interface{}
14+
m *sync.RWMutex
15+
kv map[string]interface{}
16+
sections map[string]persistence.Section
1617
}
1718

18-
func (m *memory) Exists(key string) bool {
19+
func (m *memory) Section(key ...string) persistence.Section {
1920
m.m.RLock()
20-
defer m.m.RUnlock()
21+
s, ok := m.sections[key[0]]
22+
m.m.RUnlock()
2123

22-
_, found := m.kv[key]
24+
if !ok {
25+
s = New()
26+
m.m.Lock()
27+
m.sections[key[0]] = s
28+
m.m.Unlock()
29+
}
2330

24-
return found
31+
if len(key) > 1 {
32+
return s.Section(key[1:]...)
33+
} else {
34+
return s
35+
}
2536
}
2637

27-
func (m *memory) Keys() []string {
38+
func (m *memory) SectionKeys() []string {
2839
m.m.RLock()
2940
defer m.m.RUnlock()
3041

31-
var keys = make([]string, 0, len(m.kv))
42+
var keys = make([]string, 0, len(m.sections))
3243

33-
for k := range m.kv {
44+
for k := range m.sections {
3445
keys = append(keys, k)
3546
}
3647

3748
return keys
3849
}
3950

40-
func (m *memory) Section(key ...string) persistence.Section {
41-
m.m.RLock()
42-
v, ok := m.kv[key[0]]
43-
m.m.RUnlock()
51+
func (m *memory) DeleteSection(key string) bool {
52+
m.m.Lock()
53+
defer m.m.Unlock()
4454

45-
var s persistence.Section
55+
_, found := m.sections[key]
4656

47-
if ok {
48-
if cs, cok := v.(persistence.Section); cok {
49-
s = cs
50-
} else {
51-
ok = false
52-
}
57+
if found {
58+
delete(m.sections, key)
5359
}
5460

55-
if !ok {
56-
s = New()
57-
m.m.Lock()
58-
m.kv[key[0]] = s
59-
m.m.Unlock()
60-
}
61+
return found
62+
}
6163

62-
if len(key) > 1 {
63-
return s.Section(key[1:]...)
64-
} else {
65-
return s
64+
func (m *memory) Exists(key string) bool {
65+
m.m.RLock()
66+
defer m.m.RUnlock()
67+
68+
_, found := m.kv[key]
69+
70+
return found
71+
}
72+
73+
func (m *memory) Keys() []string {
74+
m.m.RLock()
75+
defer m.m.RUnlock()
76+
77+
var keys = make([]string, 0, len(m.kv))
78+
79+
for k := range m.kv {
80+
keys = append(keys, k)
6681
}
82+
83+
return keys
6784
}
6885

6986
func genericRetrieve[T any](m *memory, key string, defValue ...T) (T, bool) {

Diff for: impl/memory/memory_test.go

+48-2
Original file line numberDiff line numberDiff line change
@@ -220,11 +220,11 @@ func TestMemory_Section(t *testing.T) {
220220
cs := s.Section("tier1", "tier2")
221221
_ = cs.Set("key", "value")
222222

223-
assert.Contains(t, s.Keys(), "tier1")
223+
assert.Contains(t, s.SectionKeys(), "tier1")
224224

225225
t1 := s.Section("tier1")
226226

227-
assert.Contains(t, t1.Keys(), "tier2")
227+
assert.Contains(t, t1.SectionKeys(), "tier2")
228228

229229
t2 := t1.Section("tier2")
230230

@@ -233,6 +233,30 @@ func TestMemory_Section(t *testing.T) {
233233
})
234234
}
235235

236+
func TestMemory_SectionKeys(t *testing.T) {
237+
t.Run("seconds can be listed", func(t *testing.T) {
238+
s := New()
239+
240+
s.Section("one")
241+
s.Section("two")
242+
243+
assert.Contains(t, s.SectionKeys(), "one")
244+
assert.Contains(t, s.SectionKeys(), "two")
245+
})
246+
}
247+
248+
func TestMemory_DeleteSection(t *testing.T) {
249+
t.Run("seconds can be deleted", func(t *testing.T) {
250+
s := New()
251+
252+
s.Section("one")
253+
assert.Contains(t, s.SectionKeys(), "one")
254+
255+
s.DeleteSection("one")
256+
assert.NotContains(t, s.SectionKeys(), "one")
257+
})
258+
}
259+
236260
func TestMemory_Exists(t *testing.T) {
237261
t.Run("returns if a key exists", func(t *testing.T) {
238262
s := New()
@@ -242,3 +266,25 @@ func TestMemory_Exists(t *testing.T) {
242266
assert.False(t, s.Exists("otherKey"))
243267
})
244268
}
269+
270+
func TestMemory_SectionKeyNotClash(t *testing.T) {
271+
t.Run("ensure that keys and sections dont shared the same name space", func(t *testing.T) {
272+
s := New()
273+
274+
s.Section("key")
275+
s.Section("key2")
276+
s.Set("key", 42)
277+
s.Set("key3", 42)
278+
279+
actualKeyInt, _ := s.Int("key")
280+
assert.Equal(t, int64(42), actualKeyInt)
281+
282+
assert.Contains(t, s.Keys(), "key")
283+
assert.NotContains(t, s.Keys(), "key2")
284+
assert.Contains(t, s.Keys(), "key3")
285+
286+
assert.Contains(t, s.SectionKeys(), "key")
287+
assert.Contains(t, s.SectionKeys(), "key2")
288+
assert.NotContains(t, s.SectionKeys(), "key3")
289+
})
290+
}

Diff for: interface.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package persistence
22

33
type Section interface {
4+
Section(key ...string) Section
5+
SectionKeys() []string
6+
DeleteSection(key string) bool
7+
48
Keys() []string
59
Exists(key string) bool
610

7-
Section(key ...string) Section
8-
911
Int(key string, defValue ...int64) (int64, bool)
1012
UInt(key string, defValue ...uint64) (uint64, bool)
1113
String(key string, defValue ...string) (string, bool)

0 commit comments

Comments
 (0)