Skip to content

Commit

Permalink
Merge pull request #4 from nutbunnies/master
Browse files Browse the repository at this point in the history
added locking to mutation methods Store, DeleteOne and DeleteAll
  • Loading branch information
ian-kent authored Nov 15, 2016
2 parents 2f131a5 + a8cd874 commit 4266627
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 0 deletions.
8 changes: 8 additions & 0 deletions memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package storage

import (
"strings"
"sync"

"github.com/mailhog/data"
)
Expand All @@ -10,6 +11,7 @@ import (
type InMemory struct {
MessageIDIndex map[string]int
Messages []*data.Message
mu sync.Mutex
}

// CreateInMemory creates a new in memory storage backend
Expand All @@ -22,6 +24,8 @@ func CreateInMemory() *InMemory {

// Store stores a message and returns its storage ID
func (memory *InMemory) Store(m *data.Message) (string, error) {
memory.mu.Lock()
defer memory.mu.Unlock()
memory.Messages = append(memory.Messages, m)
memory.MessageIDIndex[string(m.ID)] = len(memory.Messages) - 1
return string(m.ID), nil
Expand Down Expand Up @@ -156,6 +160,8 @@ func (memory *InMemory) List(start int, limit int) (*data.Messages, error) {

// DeleteOne deletes an individual message by storage ID
func (memory *InMemory) DeleteOne(id string) error {
memory.mu.Lock()
defer memory.mu.Unlock()
index := memory.MessageIDIndex[id]
delete(memory.MessageIDIndex, id)
for k, v := range memory.MessageIDIndex {
Expand All @@ -169,6 +175,8 @@ func (memory *InMemory) DeleteOne(id string) error {

// DeleteAll deletes all in memory messages
func (memory *InMemory) DeleteAll() error {
memory.mu.Lock()
defer memory.mu.Unlock()
memory.Messages = make([]*data.Message, 0)
memory.MessageIDIndex = make(map[string]int)
return nil
Expand Down
75 changes: 75 additions & 0 deletions memory_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package storage

import (
"sync"
"testing"
"time"

"github.com/mailhog/data"
)

func TestStore(t *testing.T) {
storage := CreateInMemory()

if storage.Count() != 0 {
t.Errorf("storage.Count() expected: %d, got: %d", 0, storage.Count())
}

var wg sync.WaitGroup
wg.Add(25)
for i := 0; i < 25; i++ {
go func(i int) {
msg := &data.Message{
ID: data.MessageID(i),
Created: time.Now(),
}
storage.Store(msg)
wg.Done()
}(i)
}
wg.Wait()

if storage.Count() != 25 {
t.Errorf("storage.Count() expected: %d, got: %d", 25, storage.Count())
}
}

func TestDeleteAll(t *testing.T) {
storage := CreateInMemory()

if storage.Count() != 0 {
t.Errorf("storage.Count() expected: %d, got: %d", 0, storage.Count())
}

for i := 0; i < 25; i++ {
storage.Store(&data.Message{ID: data.MessageID(i), Created: time.Now()})
}

if storage.Count() != 25 {
t.Errorf("storage.Count() expected: %d, got: %d", 25, storage.Count())
}

storage.DeleteAll()

if storage.Count() != 0 {
t.Errorf("storage.Count() expected: %d, got: %d", 0, storage.Count())
}
}

func TestDeleteOne(t *testing.T) {
storage := CreateInMemory()

if storage.Count() != 0 {
t.Errorf("storage.Count() expected: %d, got: %d", 0, storage.Count())
}

for i := 0; i < 25; i++ {
storage.Store(&data.Message{ID: data.MessageID(i), Created: time.Now()})
}

storage.DeleteOne("1")

if storage.Count() != 24 {
t.Errorf("storage.Count() expected: %d, got: %d", 0, storage.Count())
}
}

0 comments on commit 4266627

Please sign in to comment.