-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c18cf4b
commit abcd168
Showing
20 changed files
with
363 additions
and
291 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package gocollection | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
) | ||
|
||
func testListBasicOps(t *testing.T, list List) { | ||
/// Setup & When & Then | ||
getValue1, getFound1 := list.Get(0) | ||
|
||
if getValue1 != nil || getFound1 { | ||
t.Errorf("Should not have any element") | ||
} | ||
|
||
newElements := []Element{1, 2, 3, 4} | ||
list.AddAll(newElements...) | ||
|
||
for ix := range newElements { | ||
e := newElements[ix] | ||
value, found := list.Get(ix) | ||
|
||
if value != e || !found { | ||
t.Errorf("Should have found element") | ||
} | ||
} | ||
|
||
fmt.Printf("Final list: %v\n", list) | ||
} | ||
|
||
func testListAllOps(t *testing.T, listFn func() List) { | ||
testCollectionBasicOps(t, listFn()) | ||
testListBasicOps(t, listFn()) | ||
} | ||
|
||
func TestSliceListAllOps(t *testing.T) { | ||
t.Parallel() | ||
|
||
testListAllOps(t, func() List { | ||
return NewSliceList() | ||
}) | ||
} | ||
|
||
func TestLockConcurrentListAllOps(t *testing.T) { | ||
t.Parallel() | ||
|
||
testListAllOps(t, func() List { | ||
sl := NewSliceList() | ||
return NewLockConcurrentList(sl) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package gocollection | ||
|
||
import ( | ||
"strconv" | ||
"testing" | ||
) | ||
|
||
func testCollectionBasicOps(t *testing.T, c Collection) { | ||
/// Setup & When & Then | ||
add1 := c.Add(1) | ||
add2 := c.Add(2) | ||
add3 := c.Add(3) | ||
add4 := c.Add(4) | ||
|
||
if add1 != 1 || add2 != 1 || add3 != 1 || add4 != 1 { | ||
t.Errorf("Added wrong element count") | ||
} | ||
|
||
if c.Length() != 4 { | ||
t.Errorf("Should have 4 elements") | ||
} | ||
|
||
deletedFound1 := c.Remove(2) | ||
|
||
if c.Length() != 3 || !deletedFound1 { | ||
t.Errorf("Should have 3 elements") | ||
} | ||
|
||
slice := make([]Element, 1000) | ||
|
||
for ix := range slice { | ||
slice[ix] = strconv.Itoa(ix) | ||
} | ||
|
||
addAll1 := c.AddAll(slice...) | ||
|
||
if addAll1 != 1000 { | ||
t.Errorf("Added wrong element count") | ||
} | ||
|
||
if c.Length() != 1003 { | ||
t.Errorf("Should have 1003 elements") | ||
} | ||
|
||
deletedFound2 := c.Remove("Not existent") | ||
|
||
if deletedFound2 { | ||
t.Errorf("Should not have found element") | ||
} | ||
|
||
c.Clear() | ||
|
||
if c.Length() != 0 { | ||
t.Errorf("Should not have any element") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package gocollection | ||
|
||
// Element represents a Collection element. | ||
type Element interface{} | ||
|
||
// Collection represents a collection of elements which may be ordered (list) or | ||
// unordered (set). | ||
type Collection interface { | ||
Add(element Element) int | ||
AddAll(elements ...Element) int | ||
Contains(element Element) bool | ||
Clear() | ||
Length() int | ||
Remove(element Element) bool | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package gocollection | ||
|
||
// ConcurrentCollection represents a thread-safe Collection. | ||
type ConcurrentCollection interface { | ||
Collection | ||
AddAsync(element Element, callback func(int)) | ||
AddAllAsync(callback func(int), elements ...Element) | ||
ClearAsync(callback func()) | ||
ContainsAsync(element Element, callback func(bool)) | ||
LengthAsync(callback func(int)) | ||
RemoveAsync(element Element, callback func(bool)) | ||
} | ||
|
||
type concurrentCollection struct { | ||
Collection | ||
} | ||
|
||
func (cc *concurrentCollection) AddAsync(element Element, callback func(int)) { | ||
go func() { | ||
added := cc.Add(element) | ||
callback(added) | ||
}() | ||
} | ||
|
||
func (cc *concurrentCollection) AddAllAsync(callback func(int), elements ...Element) { | ||
go func() { | ||
added := cc.AddAll(elements...) | ||
callback(added) | ||
}() | ||
} | ||
|
||
func (cc *concurrentCollection) ClearAsync(callback func()) { | ||
go func() { | ||
cc.Clear() | ||
callback() | ||
}() | ||
} | ||
|
||
func (cc *concurrentCollection) ContainsAsync(element Element, callback func(bool)) { | ||
go func() { | ||
contains := cc.Contains(element) | ||
callback(contains) | ||
}() | ||
} | ||
|
||
func (cc *concurrentCollection) LengthAsync(callback func(int)) { | ||
go func() { | ||
length := cc.Length() | ||
callback(length) | ||
}() | ||
} | ||
|
||
func (cc *concurrentCollection) RemoveAsync(element Element, callback func(bool)) { | ||
go func() { | ||
found := cc.Remove(element) | ||
callback(found) | ||
}() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package gocollection | ||
|
||
import ( | ||
"fmt" | ||
) | ||
|
||
// ConcurrentList represents a thread-safe List. | ||
type ConcurrentList interface { | ||
ConcurrentCollection | ||
listExtra | ||
GetAsync(index int, callback func(Element, bool)) | ||
} | ||
|
||
type concurrentList struct { | ||
ConcurrentCollection | ||
listExtra | ||
} | ||
|
||
func (cl *concurrentList) String() string { | ||
return fmt.Sprint(cl.listExtra) | ||
} | ||
|
||
func (cl *concurrentList) GetAsync(index int, callback func(Element, bool)) { | ||
go func() { | ||
e, found := cl.listExtra.Get(index) | ||
callback(e, found) | ||
}() | ||
} | ||
|
||
func newConcurrentList(list List) ConcurrentList { | ||
collection := &concurrentCollection{Collection: list} | ||
return &concurrentList{ConcurrentCollection: collection, listExtra: list} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package gocollection | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
func testListConcurrentOps(tb testing.TB, cl ConcurrentCollection) { | ||
params := &ConcurrentCollectionOpsParams{ | ||
concurrentCollection: cl, | ||
log: false, | ||
keyCount: 500, | ||
} | ||
|
||
setupConcurrentCollectionOps(params) | ||
} | ||
|
||
func benchmarkListConcurrentOps(b *testing.B, clFn func() ConcurrentCollection) { | ||
for i := 0; i < b.N; i++ { | ||
testListConcurrentOps(b, clFn()) | ||
} | ||
} | ||
|
||
func BenchmarkLockListConcurrentOps(b *testing.B) { | ||
benchmarkListConcurrentOps(b, func() ConcurrentCollection { | ||
sl := NewSliceList() | ||
return NewLockConcurrentList(sl) | ||
}) | ||
} | ||
|
||
func TestLockListConcurrentOps(t *testing.T) { | ||
t.Parallel() | ||
sl := NewSliceList() | ||
cl := NewLockConcurrentList(sl) | ||
testListConcurrentOps(t, cl) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package gocollection | ||
|
||
// This represents the minimal interface with additional List methods. | ||
type listExtra interface { | ||
Get(index int) (Element, bool) | ||
} | ||
|
||
// List represents an indexed Collection of elements. | ||
type List interface { | ||
Collection | ||
listExtra | ||
} |
Oops, something went wrong.