Skip to content

Commit

Permalink
Seperate name spaces for parameters and sections, eases implementations.
Browse files Browse the repository at this point in the history
  • Loading branch information
pwood committed Jun 14, 2024
1 parent f587e84 commit 05e0f3a
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 35 deletions.
79 changes: 48 additions & 31 deletions impl/memory/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,63 +7,80 @@ import (
)

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

type memory struct {
m *sync.RWMutex
kv map[string]interface{}
m *sync.RWMutex
kv map[string]interface{}
sections map[string]persistence.Section
}

func (m *memory) Exists(key string) bool {
func (m *memory) Section(key ...string) persistence.Section {
m.m.RLock()
defer m.m.RUnlock()
s, ok := m.sections[key[0]]
m.m.RUnlock()

_, found := m.kv[key]
if !ok {
s = New()
m.m.Lock()
m.sections[key[0]] = s
m.m.Unlock()
}

return found
if len(key) > 1 {
return s.Section(key[1:]...)
} else {
return s
}
}

func (m *memory) Keys() []string {
func (m *memory) SectionKeys() []string {
m.m.RLock()
defer m.m.RUnlock()

var keys = make([]string, 0, len(m.kv))
var keys = make([]string, 0, len(m.sections))

for k := range m.kv {
for k := range m.sections {
keys = append(keys, k)
}

return keys
}

func (m *memory) Section(key ...string) persistence.Section {
m.m.RLock()
v, ok := m.kv[key[0]]
m.m.RUnlock()
func (m *memory) DeleteSection(key string) bool {
m.m.Lock()
defer m.m.Unlock()

var s persistence.Section
_, found := m.sections[key]

if ok {
if cs, cok := v.(persistence.Section); cok {
s = cs
} else {
ok = false
}
if found {
delete(m.sections, key)
}

if !ok {
s = New()
m.m.Lock()
m.kv[key[0]] = s
m.m.Unlock()
}
return found
}

if len(key) > 1 {
return s.Section(key[1:]...)
} else {
return s
func (m *memory) Exists(key string) bool {
m.m.RLock()
defer m.m.RUnlock()

_, found := m.kv[key]

return found
}

func (m *memory) Keys() []string {
m.m.RLock()
defer m.m.RUnlock()

var keys = make([]string, 0, len(m.kv))

for k := range m.kv {
keys = append(keys, k)
}

return keys
}

func genericRetrieve[T any](m *memory, key string, defValue ...T) (T, bool) {
Expand Down
50 changes: 48 additions & 2 deletions impl/memory/memory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,11 @@ func TestMemory_Section(t *testing.T) {
cs := s.Section("tier1", "tier2")
_ = cs.Set("key", "value")

assert.Contains(t, s.Keys(), "tier1")
assert.Contains(t, s.SectionKeys(), "tier1")

t1 := s.Section("tier1")

assert.Contains(t, t1.Keys(), "tier2")
assert.Contains(t, t1.SectionKeys(), "tier2")

t2 := t1.Section("tier2")

Expand All @@ -233,6 +233,30 @@ func TestMemory_Section(t *testing.T) {
})
}

func TestMemory_SectionKeys(t *testing.T) {
t.Run("seconds can be listed", func(t *testing.T) {
s := New()

s.Section("one")
s.Section("two")

assert.Contains(t, s.SectionKeys(), "one")
assert.Contains(t, s.SectionKeys(), "two")
})
}

func TestMemory_DeleteSection(t *testing.T) {
t.Run("seconds can be deleted", func(t *testing.T) {
s := New()

s.Section("one")
assert.Contains(t, s.SectionKeys(), "one")

s.DeleteSection("one")
assert.NotContains(t, s.SectionKeys(), "one")
})
}

func TestMemory_Exists(t *testing.T) {
t.Run("returns if a key exists", func(t *testing.T) {
s := New()
Expand All @@ -242,3 +266,25 @@ func TestMemory_Exists(t *testing.T) {
assert.False(t, s.Exists("otherKey"))
})
}

func TestMemory_SectionKeyNotClash(t *testing.T) {
t.Run("ensure that keys and sections dont shared the same name space", func(t *testing.T) {
s := New()

s.Section("key")
s.Section("key2")
s.Set("key", 42)
s.Set("key3", 42)

actualKeyInt, _ := s.Int("key")
assert.Equal(t, int64(42), actualKeyInt)

assert.Contains(t, s.Keys(), "key")
assert.NotContains(t, s.Keys(), "key2")
assert.Contains(t, s.Keys(), "key3")

assert.Contains(t, s.SectionKeys(), "key")
assert.Contains(t, s.SectionKeys(), "key2")
assert.NotContains(t, s.SectionKeys(), "key3")
})
}
6 changes: 4 additions & 2 deletions interface.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package persistence

type Section interface {
Section(key ...string) Section
SectionKeys() []string
DeleteSection(key string) bool

Keys() []string
Exists(key string) bool

Section(key ...string) Section

Int(key string, defValue ...int64) (int64, bool)
UInt(key string, defValue ...uint64) (uint64, bool)
String(key string, defValue ...string) (string, bool)
Expand Down

0 comments on commit 05e0f3a

Please sign in to comment.