Skip to content
Permalink
Browse files

map store

  • Loading branch information
mrjoshuak committed Nov 9, 2019
1 parent 4e9b97e commit 0c47c40eb059efda915b6fc0c8e38792a34201f5
Showing with 139 additions and 0 deletions.
  1. +63 −0 store/map.go
  2. +76 −0 store/map_test.go
@@ -0,0 +1,63 @@
package store

import (
"io"
"os"

"github.com/Avalanche-io/c4"
)

var _ Store = &MAP{}

// A MAP store is an implementation of the Store interface that stores all data
// in ram.
type MAP map[c4.ID]string

func NewMap(m map[c4.ID]string) MAP {
return MAP(m)
}

// Open opens a file named the given c4.ID in read-only mode from ram. If
// the file does not exist an error of type `*os.PathError` is returned.
func (s MAP) Open(id c4.ID) (io.ReadCloser, error) {
return os.Open(s[id])
}

// Create creates an io.WriteCloser interface to a ram buffer, if the data for
// `id` already exists in the MAP store then an error of type `*os.PathError` is
// returned.
func (s MAP) Create(id c4.ID) (io.WriteCloser, error) {
return os.Create(s[id])
}

// Remove removes the c4 id and it's assoceated data from memory, an error is
// returned if the id does not exist.
func (s MAP) Remove(id c4.ID) error {
return os.Remove(s[id])
}

func (m MAP) Delete(id c4.ID) {
delete(m, id)
}

func (m MAP) Load(id c4.ID) (path string) {
return m[id]
}

func (m MAP) LoadOrStore(id c4.ID, path string) (actual string, loaded bool) {
var ok bool
actual, ok = m[id]
if !ok {
m[id] = path
return path, false
}
return actual, true
}

func (m MAP) Range(f func(id c4.ID, path string) bool) {
for id, path := range m {
if !f(id, path) {
return
}
}
}
@@ -0,0 +1,76 @@
package store

import (
"bytes"
"fmt"
"os"
"path/filepath"
"testing"

"github.com/Avalanche-io/c4"
)

func TestMapStore(t *testing.T) {
tmp, done, err := MkTmp("TestMapStore")
if err != nil {
t.Fatal(err)
}
defer done()
m := make(map[c4.ID]string)
ms := NewMap(m)
var ids []c4.ID
for i := 100; i > 0; i-- {
data := fmt.Sprintf("%04d", i)
filename := filepath.Join(tmp, data)
f, err := os.Create(filename)
if err != nil {
t.Fatal(err)
}
_, err = f.WriteString(data)
f.Close()
if err != nil {
t.Fatal(err)
}
id := c4.Identify(bytes.NewReader([]byte(data)))
ids = append(ids, id)
ms.LoadOrStore(id, filename)
}

ms.Range(func(id c4.ID, path string) bool {
if m[id] != path {
t.Error("wrong map content")
}
return true
})

if len(m) != len(ids) {
t.Errorf("counts don't match %d %d", len(m), len(ids))
}

// Test all filenames against all ids
for i, id := range ids {
f, err := ms.Open(id)
if err != nil {
t.Fatal(err)
}
testid := c4.Identify(f)
f.Close()
if testid != id {
t.Fatalf("wrong id content %d", i)
}

}
}

func MkTmp(name string) (string, func(), error) {
path := os.TempDir()
path = filepath.Join(path, name)
err := os.MkdirAll(path, 0755)
if err != nil {
return "", func() {}, err
}

return path, func() {
os.RemoveAll(path)
}, nil
}

0 comments on commit 0c47c40

Please sign in to comment.
You can’t perform that action at this time.