Commit bf6fdcf1 authored by hannahhoward's avatar hannahhoward

refactor(selector): minor structural optimizations

update the structure for ExploreIndex & ExploreRange to be slightly more clear and optimized
parent c590adc1
...@@ -9,13 +9,13 @@ import ( ...@@ -9,13 +9,13 @@ import (
// ExploreIndex traverses a specific index in a list, and applies a next // ExploreIndex traverses a specific index in a list, and applies a next
// selector to the reached node. // selector to the reached node.
type ExploreIndex struct { type ExploreIndex struct {
next Selector // selector for element we're interested in next Selector // selector for element we're interested in
interest []PathSegment // index of element we're interested in interest [1]PathSegment // index of element we're interested in
} }
// Interests for ExploreIndex is just the index specified by the selector node // Interests for ExploreIndex is just the index specified by the selector node
func (s ExploreIndex) Interests() []PathSegment { func (s ExploreIndex) Interests() []PathSegment {
return s.interest return s.interest[:]
} }
// Explore returns the node's selector if // Explore returns the node's selector if
...@@ -59,5 +59,5 @@ func ParseExploreIndex(n ipld.Node) (Selector, error) { ...@@ -59,5 +59,5 @@ func ParseExploreIndex(n ipld.Node) (Selector, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return ExploreIndex{selector, []PathSegment{PathSegmentInt{I: indexValue}}}, nil return ExploreIndex{selector, [1]PathSegment{PathSegmentInt{I: indexValue}}}, nil
} }
...@@ -60,13 +60,13 @@ func TestParseExploreIndex(t *testing.T) { ...@@ -60,13 +60,13 @@ func TestParseExploreIndex(t *testing.T) {
}) })
s, err := ParseExploreIndex(sn) s, err := ParseExploreIndex(sn)
Wish(t, err, ShouldEqual, nil) Wish(t, err, ShouldEqual, nil)
Wish(t, s, ShouldEqual, ExploreIndex{Matcher{}, []PathSegment{PathSegmentInt{I: 2}}}) Wish(t, s, ShouldEqual, ExploreIndex{Matcher{}, [1]PathSegment{PathSegmentInt{I: 2}}})
}) })
} }
func TestExploreIndexExplore(t *testing.T) { func TestExploreIndexExplore(t *testing.T) {
fnb := fluent.WrapNodeBuilder(ipldfree.NodeBuilder()) // just for the other fixture building fnb := fluent.WrapNodeBuilder(ipldfree.NodeBuilder()) // just for the other fixture building
s := ExploreIndex{Matcher{}, []PathSegment{PathSegmentInt{I: 3}}} s := ExploreIndex{Matcher{}, [1]PathSegment{PathSegmentInt{I: 3}}}
t.Run("exploring should return nil unless node is a list", func(t *testing.T) { t.Run("exploring should return nil unless node is a list", func(t *testing.T) {
n := fnb.CreateMap(func(mb fluent.MapBuilder, knb fluent.NodeBuilder, vnb fluent.NodeBuilder) {}) n := fnb.CreateMap(func(mb fluent.MapBuilder, knb fluent.NodeBuilder, vnb fluent.NodeBuilder) {})
returnedSelector := s.Explore(n, PathSegmentInt{I: 3}) returnedSelector := s.Explore(n, PathSegmentInt{I: 3})
......
...@@ -9,9 +9,10 @@ import ( ...@@ -9,9 +9,10 @@ import (
// ExploreRange traverses a list, and for each element in the range specified, // ExploreRange traverses a list, and for each element in the range specified,
// will apply a next selector to those reached nodes. // will apply a next selector to those reached nodes.
type ExploreRange struct { type ExploreRange struct {
next Selector // selector for element we're interested in next Selector // selector for element we're interested in
hasSelector map[int]struct{} // a quick check whether to return the selector start int
interest []PathSegment // index of element we're interested in end int
interest []PathSegment // index of element we're interested in
} }
// Interests for ExploreRange are all path segments within the iteration range // Interests for ExploreRange are all path segments within the iteration range
...@@ -29,7 +30,7 @@ func (s ExploreRange) Explore(n ipld.Node, p PathSegment) Selector { ...@@ -29,7 +30,7 @@ func (s ExploreRange) Explore(n ipld.Node, p PathSegment) Selector {
if err != nil { if err != nil {
return nil return nil
} }
if _, ok := s.hasSelector[index]; !ok { if index < s.start || index >= s.end {
return nil return nil
} }
return s.next return s.next
...@@ -75,12 +76,12 @@ func ParseExploreRange(n ipld.Node) (Selector, error) { ...@@ -75,12 +76,12 @@ func ParseExploreRange(n ipld.Node) (Selector, error) {
} }
x := ExploreRange{ x := ExploreRange{
selector, selector,
make(map[int]struct{}, endValue-startValue), startValue,
endValue,
make([]PathSegment, 0, endValue-startValue), make([]PathSegment, 0, endValue-startValue),
} }
for i := startValue; i < endValue; i++ { for i := startValue; i < endValue; i++ {
x.interest = append(x.interest, PathSegmentInt{I: i}) x.interest = append(x.interest, PathSegmentInt{I: i})
x.hasSelector[i] = struct{}{}
} }
return x, nil return x, nil
} }
...@@ -98,13 +98,13 @@ func TestParseExploreRange(t *testing.T) { ...@@ -98,13 +98,13 @@ func TestParseExploreRange(t *testing.T) {
}) })
s, err := ParseExploreRange(sn) s, err := ParseExploreRange(sn)
Wish(t, err, ShouldEqual, nil) Wish(t, err, ShouldEqual, nil)
Wish(t, s, ShouldEqual, ExploreRange{Matcher{}, map[int]struct{}{2: struct{}{}}, []PathSegment{PathSegmentInt{I: 2}}}) Wish(t, s, ShouldEqual, ExploreRange{Matcher{}, 2, 3, []PathSegment{PathSegmentInt{I: 2}}})
}) })
} }
func TestExploreRangeExplore(t *testing.T) { func TestExploreRangeExplore(t *testing.T) {
fnb := fluent.WrapNodeBuilder(ipldfree.NodeBuilder()) // just for the other fixture building fnb := fluent.WrapNodeBuilder(ipldfree.NodeBuilder()) // just for the other fixture building
s := ExploreRange{Matcher{}, map[int]struct{}{3: struct{}{}}, []PathSegment{PathSegmentInt{I: 3}}} s := ExploreRange{Matcher{}, 3, 4, []PathSegment{PathSegmentInt{I: 3}}}
t.Run("exploring should return nil unless node is a list", func(t *testing.T) { t.Run("exploring should return nil unless node is a list", func(t *testing.T) {
n := fnb.CreateMap(func(mb fluent.MapBuilder, knb fluent.NodeBuilder, vnb fluent.NodeBuilder) {}) n := fnb.CreateMap(func(mb fluent.MapBuilder, knb fluent.NodeBuilder, vnb fluent.NodeBuilder) {})
returnedSelector := s.Explore(n, PathSegmentInt{I: 3}) returnedSelector := s.Explore(n, PathSegmentInt{I: 3})
......
...@@ -44,7 +44,7 @@ func TestParseExploreUnion(t *testing.T) { ...@@ -44,7 +44,7 @@ func TestParseExploreUnion(t *testing.T) {
}) })
s, err := ParseExploreUnion(sn) s, err := ParseExploreUnion(sn)
Wish(t, err, ShouldEqual, nil) Wish(t, err, ShouldEqual, nil)
Wish(t, s, ShouldEqual, ExploreUnion{[]Selector{Matcher{}, ExploreIndex{Matcher{}, []PathSegment{PathSegmentInt{I: 2}}}}}) Wish(t, s, ShouldEqual, ExploreUnion{[]Selector{Matcher{}, ExploreIndex{Matcher{}, [1]PathSegment{PathSegmentInt{I: 2}}}}})
}) })
} }
...@@ -54,13 +54,13 @@ func TestExploreUnionExplore(t *testing.T) { ...@@ -54,13 +54,13 @@ func TestExploreUnionExplore(t *testing.T) {
lb.AppendAll([]ipld.Node{fnb.CreateInt(0), fnb.CreateInt(1), fnb.CreateInt(2), fnb.CreateInt(3)}) lb.AppendAll([]ipld.Node{fnb.CreateInt(0), fnb.CreateInt(1), fnb.CreateInt(2), fnb.CreateInt(3)})
}) })
t.Run("exploring should return nil if all member selectors return nil when explored", func(t *testing.T) { t.Run("exploring should return nil if all member selectors return nil when explored", func(t *testing.T) {
s := ExploreUnion{[]Selector{Matcher{}, ExploreIndex{Matcher{}, []PathSegment{PathSegmentInt{I: 2}}}}} s := ExploreUnion{[]Selector{Matcher{}, ExploreIndex{Matcher{}, [1]PathSegment{PathSegmentInt{I: 2}}}}}
returnedSelector := s.Explore(n, PathSegmentInt{I: 3}) returnedSelector := s.Explore(n, PathSegmentInt{I: 3})
Wish(t, returnedSelector, ShouldEqual, nil) Wish(t, returnedSelector, ShouldEqual, nil)
}) })
t.Run("if exactly one member selector returns a non-nil selector when explored, exploring should return that value", func(t *testing.T) { t.Run("if exactly one member selector returns a non-nil selector when explored, exploring should return that value", func(t *testing.T) {
s := ExploreUnion{[]Selector{Matcher{}, ExploreIndex{Matcher{}, []PathSegment{PathSegmentInt{I: 2}}}}} s := ExploreUnion{[]Selector{Matcher{}, ExploreIndex{Matcher{}, [1]PathSegment{PathSegmentInt{I: 2}}}}}
returnedSelector := s.Explore(n, PathSegmentInt{I: 2}) returnedSelector := s.Explore(n, PathSegmentInt{I: 2})
Wish(t, returnedSelector, ShouldEqual, Matcher{}) Wish(t, returnedSelector, ShouldEqual, Matcher{})
...@@ -68,8 +68,8 @@ func TestExploreUnionExplore(t *testing.T) { ...@@ -68,8 +68,8 @@ func TestExploreUnionExplore(t *testing.T) {
t.Run("exploring should return a new union selector if more than one member selector returns a non nil selector when explored", func(t *testing.T) { t.Run("exploring should return a new union selector if more than one member selector returns a non nil selector when explored", func(t *testing.T) {
s := ExploreUnion{[]Selector{ s := ExploreUnion{[]Selector{
Matcher{}, Matcher{},
ExploreIndex{Matcher{}, []PathSegment{PathSegmentInt{I: 2}}}, ExploreIndex{Matcher{}, [1]PathSegment{PathSegmentInt{I: 2}}},
ExploreRange{Matcher{}, map[int]struct{}{2: struct{}{}}, []PathSegment{PathSegmentInt{I: 2}}}, ExploreRange{Matcher{}, 2, 3, []PathSegment{PathSegmentInt{I: 2}}},
ExploreFields{map[string]Selector{"applesauce": Matcher{}}, []PathSegment{PathSegmentString{S: "applesauce"}}}, ExploreFields{map[string]Selector{"applesauce": Matcher{}}, []PathSegment{PathSegmentString{S: "applesauce"}}},
}} }}
...@@ -83,7 +83,7 @@ func TestExploreUnionInterests(t *testing.T) { ...@@ -83,7 +83,7 @@ func TestExploreUnionInterests(t *testing.T) {
s := ExploreUnion{[]Selector{ s := ExploreUnion{[]Selector{
ExploreAll{Matcher{}}, ExploreAll{Matcher{}},
Matcher{}, Matcher{},
ExploreIndex{Matcher{}, []PathSegment{PathSegmentInt{I: 2}}}, ExploreIndex{Matcher{}, [1]PathSegment{PathSegmentInt{I: 2}}},
}} }}
Wish(t, s.Interests(), ShouldEqual, []PathSegment(nil)) Wish(t, s.Interests(), ShouldEqual, []PathSegment(nil))
}) })
...@@ -91,7 +91,7 @@ func TestExploreUnionInterests(t *testing.T) { ...@@ -91,7 +91,7 @@ func TestExploreUnionInterests(t *testing.T) {
s := ExploreUnion{[]Selector{ s := ExploreUnion{[]Selector{
ExploreFields{map[string]Selector{"applesauce": Matcher{}}, []PathSegment{PathSegmentString{S: "applesauce"}}}, ExploreFields{map[string]Selector{"applesauce": Matcher{}}, []PathSegment{PathSegmentString{S: "applesauce"}}},
Matcher{}, Matcher{},
ExploreIndex{Matcher{}, []PathSegment{PathSegmentInt{I: 2}}}, ExploreIndex{Matcher{}, [1]PathSegment{PathSegmentInt{I: 2}}},
}} }}
Wish(t, s.Interests(), ShouldEqual, []PathSegment{PathSegmentString{S: "applesauce"}, PathSegmentInt{I: 2}}) Wish(t, s.Interests(), ShouldEqual, []PathSegment{PathSegmentString{S: "applesauce"}, PathSegmentInt{I: 2}})
}) })
...@@ -104,7 +104,7 @@ func TestExploreUnionDecide(t *testing.T) { ...@@ -104,7 +104,7 @@ func TestExploreUnionDecide(t *testing.T) {
s := ExploreUnion{[]Selector{ s := ExploreUnion{[]Selector{
ExploreAll{Matcher{}}, ExploreAll{Matcher{}},
Matcher{}, Matcher{},
ExploreIndex{Matcher{}, []PathSegment{PathSegmentInt{I: 2}}}, ExploreIndex{Matcher{}, [1]PathSegment{PathSegmentInt{I: 2}}},
}} }}
Wish(t, s.Decide(n), ShouldEqual, true) Wish(t, s.Decide(n), ShouldEqual, true)
}) })
...@@ -112,7 +112,7 @@ func TestExploreUnionDecide(t *testing.T) { ...@@ -112,7 +112,7 @@ func TestExploreUnionDecide(t *testing.T) {
s := ExploreUnion{[]Selector{ s := ExploreUnion{[]Selector{
ExploreFields{map[string]Selector{"applesauce": Matcher{}}, []PathSegment{PathSegmentString{S: "applesauce"}}}, ExploreFields{map[string]Selector{"applesauce": Matcher{}}, []PathSegment{PathSegmentString{S: "applesauce"}}},
ExploreAll{Matcher{}}, ExploreAll{Matcher{}},
ExploreIndex{Matcher{}, []PathSegment{PathSegmentInt{I: 2}}}, ExploreIndex{Matcher{}, [1]PathSegment{PathSegmentInt{I: 2}}},
}} }}
Wish(t, s.Decide(n), ShouldEqual, false) Wish(t, s.Decide(n), ShouldEqual, false)
}) })
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment