Skip to content

Commit

Permalink
Merge pull request #108 from Workiva/rt_get
Browse files Browse the repository at this point in the history
Add get methods.
  • Loading branch information
dustinhiatt-wf committed Aug 4, 2015
2 parents a430e78 + e57e14c commit fa486f9
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 0 deletions.
9 changes: 9 additions & 0 deletions mock/rangetree.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,12 @@ func (m *RangeTree) InsertAtDimension(dimension uint64, index,
func (m *RangeTree) Apply(interval rangetree.Interval, fn func(rangetree.Entry) bool) {
m.Called(interval, fn)
}

func (m *RangeTree) Get(entries ...rangetree.Entry) rangetree.Entries {
ifc := m.Called(entries).Get(0)
if ifc == nil {
return nil
}

return ifc.(rangetree.Entries)
}
29 changes: 29 additions & 0 deletions rangetree/immutable.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,35 @@ func (irt *immutableRangeTree) Query(interval Interval) Entries {
return entries
}

func (irt *immutableRangeTree) get(entry Entry) Entry {
on := irt.top
for i := uint64(1); i <= irt.dimensions; i++ {
n, _ := on.get(entry.ValueAtDimension(i))
if n == nil {
return nil
}
if i == irt.dimensions {
return n.entry
}
on = n.orderedNodes
}

return nil
}

// Get returns any entries that exist at the addresses provided by the
// given entries. Entries are returned in the order in which they are
// received. If an entry cannot be found, a nil is returned in its
// place.
func (irt *immutableRangeTree) Get(entries ...Entry) Entries {
result := make(Entries, 0, len(entries))
for _, entry := range entries {
result = append(result, irt.get(entry))
}

return result
}

// Len returns the number of items in this tree.
func (irt *immutableRangeTree) Len() uint64 {
return irt.number
Expand Down
10 changes: 10 additions & 0 deletions rangetree/immutable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,16 @@ func TestImmutableInsertInvalidNumber(t *testing.T) {
assert.Equal(t, tree, tree1)
}

func TestImmutableGet(t *testing.T) {
tree, entries := constructMultiDimensionalImmutableTree(2)

result := tree.Get(entries...)
assert.Equal(t, entries, result)

result = tree.Get(constructMockEntry(10000, 5000, 5000))
assert.Equal(t, Entries{nil}, result)
}

func BenchmarkImmutableInsertFirstDimension(b *testing.B) {
numItems := int64(100000)

Expand Down
5 changes: 5 additions & 0 deletions rangetree/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ type RangeTree interface {
// cancel iteration. Altering the entry in such a way that its location
// changes will result in undefined behavior.
Apply(interval Interval, fn func(Entry) bool)
// Get returns any entries that exist at the addresses provided by the
// given entries. Entries are returned in the order in which they are
// received. If an entry cannot be found, a nil is returned in its
// place.
Get(entries ...Entry) Entries
// InsertAtDimension will increment items at and above the given index
// by the number provided. Provide a negative number to to decrement.
// Returned are two lists. The first list is a list of entries that
Expand Down
29 changes: 29 additions & 0 deletions rangetree/orderedtree.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,35 @@ func (ot *orderedTree) delete(entry Entry) *node {
return node
}

func (ot *orderedTree) get(entry Entry) Entry {
on := ot.top
for i := uint64(1); i <= ot.dimensions; i++ {
n, _ := on.get(entry.ValueAtDimension(i))
if n == nil {
return nil
}
if i == ot.dimensions {
return n.entry
}
on = n.orderedNodes
}

return nil
}

// Get returns any entries that exist at the addresses provided by the
// given entries. Entries are returned in the order in which they are
// received. If an entry cannot be found, a nil is returned in its
// place.
func (ot *orderedTree) Get(entries ...Entry) Entries {
result := make(Entries, 0, len(entries))
for _, entry := range entries {
result = append(result, ot.get(entry))
}

return result
}

// Delete will remove the provided entries from the tree.
// Any entries that were deleted will be returned in the order in
// which they were deleted. If an entry does not exist to be deleted,
Expand Down
32 changes: 32 additions & 0 deletions rangetree/orderedtree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,16 @@ func TestOverwrites(t *testing.T) {
assert.Equal(t, Entries{entry}, overwritten)
}

func TestGet(t *testing.T) {
tree, entries := constructMultiDimensionalOrderedTree(2)

result := tree.Get(entries...)
assert.Equal(t, entries, result)

result = tree.Get(constructMockEntry(10000, 5000, 5000))
assert.Equal(t, Entries{nil}, result)
}

func TestTreeApply(t *testing.T) {
tree, entries := constructMultiDimensionalOrderedTree(2)

Expand Down Expand Up @@ -610,3 +620,25 @@ func BenchmarkDeleteSecondDimension(b *testing.B) {
tree.InsertAtDimension(2, 0, -1)
}
}

func BenchmarkGetMultiDimensions(b *testing.B) {
numItemsX := 10000
numItemsY := 100

tree := newOrderedTree(2)
entries := make(Entries, 0, numItemsY*numItemsX)

for i := 0; i < numItemsX; i++ {
for j := 0; j < numItemsY; j++ {
e := constructMockEntry(uint64(j*numItemsY+i), int64(i), int64(j))
entries = append(entries, e)
}
}

tree.Add(entries...)
b.ResetTimer()

for i := 0; i < b.N; i++ {
tree.Get(entries[i%len(entries)])
}
}

0 comments on commit fa486f9

Please sign in to comment.