@@ -59,15 +59,12 @@ func Inclusion(index, size uint64) (Nodes, error) {
5959// - start to be a multiple of the smallest power of two greater than or equal to
6060// (end - start)
6161func SubtreeInclusion (index , start , end uint64 ) (Nodes , error ) {
62- if start >= end {
63- return Nodes {}, fmt .Errorf ("start %d greater than or equal to end %d " , start , end )
62+ if err := IsSubtreeValid ( start , end ); err != nil {
63+ return Nodes {}, fmt .Errorf ("subtree invalid: %v " , err )
6464 }
6565 if index < start || index >= end {
6666 return Nodes {}, fmt .Errorf ("index %d out of bounds for subtree [%d, %d)" , index , start , end )
6767 }
68- if err := isSubtreeValid (start , end ); err != nil {
69- return Nodes {}, fmt .Errorf ("subtree invalid: %v" , err )
70- }
7168
7269 // Shift the subtree to the left, such that it starts at 0.
7370 p := nodes (index - start , 0 , end - start ).skipFirst ()
@@ -223,26 +220,33 @@ func reverse(ids []compact.NodeID) {
223220 }
224221}
225222
226- // isSubtreeValid returns whether a subtree covers a valid range.
223+ // IsSubtreeValid returns whether a subtree covers a valid range.
227224// A subtree is valid if there exist a parent tree node to:
228225// - all the subtree nodes
229226// - no extra node to the left of the subtree
230227// - potentially extra nodes to the right of the subtree
231- func isSubtreeValid (start , end uint64 ) error {
232- l := end - start
228+ func IsSubtreeValid (start , end uint64 ) error {
229+ if start >= end {
230+ return fmt .Errorf ("start %d must be strictly less than end %d" , start , end )
231+ }
233232 if start == 0 {
234233 return nil
235- } else if l > uint64 (1 )<< 63 {
236- // special-case large subtree to avoid panic
234+ }
235+
236+ l := end - start
237+
238+ // special-case large subtree to avoid panic
239+ if l > uint64 (1 )<< 63 {
237240 return fmt .Errorf ("start %d must be 0 when subtree length %d > 1<<63. " , start , l )
238241 }
239- if bc := bitCeil (l ); start % bc != 0 {
242+ if bc := bitCeil (l ); start & ( bc - 1 ) != 0 {
240243 return fmt .Errorf ("start %d not a multiple of bit_ceil(end - start) = %d" , start , bc )
241244 }
245+
242246 return nil
243247}
244248
245- // bitCeil returns the smallest power of 2 larger than n.
249+ // bitCeil returns the smallest power of 2 larger or equal than n.
246250// MUST NOT be used with n larger than uint64(1)<<63.
247251func bitCeil (n uint64 ) uint64 {
248252 if n <= 1 {
0 commit comments