diff --git a/types/compound_list.go b/types/compound_list.go index 18694e867d..84e964e0da 100644 --- a/types/compound_list.go +++ b/types/compound_list.go @@ -3,6 +3,8 @@ package types import ( "crypto/sha1" + "runtime" + "github.com/attic-labs/noms/chunks" "github.com/attic-labs/noms/d" "github.com/attic-labs/noms/ref" @@ -78,7 +80,19 @@ func (cl compoundList) Get(idx uint64) Value { } func (cl compoundList) IterAllP(concurrency int, f listIterAllFunc) { - panic("not implemented") + start := uint64(0) + var limit chan int + if concurrency == 0 { + limit = make(chan int, runtime.NumCPU()) + } else { + limit = make(chan int, concurrency) + } + iterateMetaSequenceLeaf(cl, cl.cs, func(l Value) bool { + list := l.(listLeaf) + list.iterInternal(limit, f, start) + start += list.Len() + return false + }) } func (cl compoundList) Slice(start uint64, end uint64) List { diff --git a/types/compound_list_test.go b/types/compound_list_test.go index 34f4f88ddc..181eeec7d1 100644 --- a/types/compound_list_test.go +++ b/types/compound_list_test.go @@ -2,6 +2,7 @@ package types import ( "math/rand" + "sync" "testing" "github.com/attic-labs/noms/Godeps/_workspace/src/github.com/stretchr/testify/assert" @@ -53,6 +54,20 @@ func getTestSimpleList() testSimpleList { return values } +func getTestSimpleListUnique() testSimpleList { + length := int(getTestSimpleListLen()) + s := rand.NewSource(42) + uniques := map[int64]bool{} + for len(uniques) < length { + uniques[s.Int63()] = true + } + values := []Value{} + for k, _ := range uniques { + values = append(values, Int64(k)) + } + return values +} + func testSimpleListFromNomsList(list List) testSimpleList { simple := make(testSimpleList, list.Len()) list.IterAll(func(v Value, offset uint64) { @@ -116,6 +131,33 @@ func TestCompoundListIterAll(t *testing.T) { assert.Equal(getTestSimpleListLen(), expectIdx) } +func TestCompoundListIterAllP(t *testing.T) { + assert := assert.New(t) + + cs := chunks.NewMemoryStore() + mu := sync.Mutex{} + + simpleList := getTestSimpleListUnique() + tr := MakeCompoundType(ListKind, MakePrimitiveType(Int64Kind)) + cl := NewTypedList(cs, tr, simpleList...) + + indexes := map[Value]uint64{} + for i, v := range simpleList { + indexes[v] = uint64(i) + } + visited := map[Value]bool{} + cl.IterAllP(64, func(v Value, idx uint64) { + mu.Lock() + _, seen := visited[v] + visited[v] = true + mu.Unlock() + assert.False(seen) + assert.Equal(idx, indexes[v]) + }) + + assert.Equal(len(simpleList), len(visited)) +} + func TestCompoundListLen(t *testing.T) { assert := assert.New(t)