removed iter/context. extra pointers

This commit is contained in:
Josh Baker 2016-06-25 12:51:38 -07:00
parent 442f9f0d8e
commit b71853025b
6 changed files with 88 additions and 128 deletions

View File

@ -152,13 +152,13 @@ func (tr *RTree) search1(min, max []float64, iter Iterator) bool {
} }
} }
ended := false ended := false
tr.tr1.Search(amin, amax, func(dataID, context interface{}) bool { tr.tr1.Search(amin, amax, func(dataID interface{}) bool {
if !iter(dataID.(Item)) { if !iter(dataID.(Item)) {
ended = true ended = true
return false return false
} }
return true return true
}, nil) })
return !ended return !ended
} }
func (tr *RTree) search2(min, max []float64, iter Iterator) bool { func (tr *RTree) search2(min, max []float64, iter Iterator) bool {
@ -173,13 +173,13 @@ func (tr *RTree) search2(min, max []float64, iter Iterator) bool {
} }
} }
ended := false ended := false
tr.tr2.Search(amin, amax, func(dataID, context interface{}) bool { tr.tr2.Search(amin, amax, func(dataID interface{}) bool {
if !iter(dataID.(Item)) { if !iter(dataID.(Item)) {
ended = true ended = true
return false return false
} }
return true return true
}, nil) })
return !ended return !ended
} }
func (tr *RTree) search3(min, max []float64, iter Iterator) bool { func (tr *RTree) search3(min, max []float64, iter Iterator) bool {
@ -194,13 +194,13 @@ func (tr *RTree) search3(min, max []float64, iter Iterator) bool {
} }
} }
ended := false ended := false
tr.tr3.Search(amin, amax, func(dataID, context interface{}) bool { tr.tr3.Search(amin, amax, func(dataID interface{}) bool {
if !iter(dataID.(Item)) { if !iter(dataID.(Item)) {
ended = true ended = true
return false return false
} }
return true return true
}, nil) })
return !ended return !ended
} }
func (tr *RTree) search4(min, max []float64, iter Iterator) bool { func (tr *RTree) search4(min, max []float64, iter Iterator) bool {
@ -215,12 +215,12 @@ func (tr *RTree) search4(min, max []float64, iter Iterator) bool {
} }
} }
ended := false ended := false
tr.tr4.Search(amin, amax, func(dataID, context interface{}) bool { tr.tr4.Search(amin, amax, func(dataID interface{}) bool {
if !iter(dataID.(Item)) { if !iter(dataID.(Item)) {
ended = true ended = true
return false return false
} }
return true return true
}, nil) })
return !ended return !ended
} }

View File

@ -55,7 +55,7 @@ const (
USE_SPHERICAL_VOLUME = true // Better split classification, may be slower on some systems USE_SPHERICAL_VOLUME = true // Better split classification, may be slower on some systems
) )
type ResultCallback func(dataID, context interface{}) bool type ResultCallback func(dataID interface{}) bool
var unitSphereVolume float64 var unitSphereVolume float64
@ -185,7 +185,7 @@ func (tr *RTree) Remove(min, max [NUMDIMS]float64, dataId interface{}) {
/// \param a_resultCallback Callback function to return result. Callback should return 'true' to continue searching /// \param a_resultCallback Callback function to return result. Callback should return 'true' to continue searching
/// \param a_context User context to pass as parameter to a_resultCallback /// \param a_context User context to pass as parameter to a_resultCallback
/// \return Returns the number of entries found /// \return Returns the number of entries found
func (tr *RTree) Search(min, max [NUMDIMS]float64, resultCallback ResultCallback, context interface{}) int { func (tr *RTree) Search(min, max [NUMDIMS]float64, resultCallback ResultCallback) int {
if _DEBUG { if _DEBUG {
for index := 0; index < NUMDIMS; index++ { for index := 0; index < NUMDIMS; index++ {
ASSERT(min[index] <= max[index]) ASSERT(min[index] <= max[index])
@ -196,10 +196,7 @@ func (tr *RTree) Search(min, max [NUMDIMS]float64, resultCallback ResultCallback
rect.min[axis] = min[axis] rect.min[axis] = min[axis]
rect.max[axis] = max[axis] rect.max[axis] = max[axis]
} }
// NOTE: May want to return search result another way, perhaps returning the number of found elements here. foundCount, _ := Search(tr.root, rect, 0, resultCallback)
foundCount := 0
Search(tr.root, &rect, &foundCount, resultCallback, context)
return foundCount return foundCount
} }
@ -728,7 +725,7 @@ func RemoveRectRec(rect *Rect, id interface{}, node *Node, listNode **ListNode)
if node.IsInternalNode() { // not a leaf node if node.IsInternalNode() { // not a leaf node
for index := 0; index < node.count; index++ { for index := 0; index < node.count; index++ {
if Overlap(rect, &(node.branch[index].rect)) { if Overlap(*rect, node.branch[index].rect) {
if !RemoveRectRec(rect, id, node.branch[index].child, listNode) { if !RemoveRectRec(rect, id, node.branch[index].child, listNode) {
if node.branch[index].child.count >= MINNODES { if node.branch[index].child.count >= MINNODES {
// child removed, just resize parent rect // child removed, just resize parent rect
@ -755,9 +752,7 @@ func RemoveRectRec(rect *Rect, id interface{}, node *Node, listNode **ListNode)
} }
// Decide whether two rectangles overlap. // Decide whether two rectangles overlap.
func Overlap(rectA, rectB *Rect) bool { func Overlap(rectA, rectB Rect) bool {
ASSERT(rectA != nil && rectB != nil)
for index := 0; index < NUMDIMS; index++ { for index := 0; index < NUMDIMS; index++ {
if rectA.min[index] > rectB.max[index] || if rectA.min[index] > rectB.max[index] ||
rectB.min[index] > rectA.max[index] { rectB.min[index] > rectA.max[index] {
@ -777,37 +772,34 @@ func ReInsert(node *Node, listNode **ListNode) {
} }
// Search in an index tree or subtree for all data retangles that overlap the argument rectangle. // Search in an index tree or subtree for all data retangles that overlap the argument rectangle.
func Search(node *Node, rect *Rect, foundCount *int, resultCallback ResultCallback, context interface{}) bool { func Search(node *Node, rect Rect, foundCount int, resultCallback ResultCallback) (int, bool) {
ASSERT(node != nil) ASSERT(node != nil)
ASSERT(node.level >= 0) ASSERT(node.level >= 0)
ASSERT(rect != nil)
if node.IsInternalNode() { if node.IsInternalNode() {
// This is an internal node in the tree // This is an internal node in the tree
for index := 0; index < node.count; index++ { for index := 0; index < node.count; index++ {
if Overlap(rect, &node.branch[index].rect) { if Overlap(rect, node.branch[index].rect) {
if !Search(node.branch[index].child, rect, foundCount, resultCallback, context) { var ok bool
foundCount, ok = Search(node.branch[index].child, rect, foundCount, resultCallback)
if !ok {
// The callback indicated to stop searching // The callback indicated to stop searching
return false return foundCount, false
} }
} }
} }
} else { } else {
// This is a leaf node // This is a leaf node
for index := 0; index < node.count; index++ { for index := 0; index < node.count; index++ {
if Overlap(rect, &node.branch[index].rect) { if Overlap(rect, node.branch[index].rect) {
id := node.branch[index].data id := node.branch[index].data
foundCount++
// NOTE: There are different ways to return results. Here's where to modify if !resultCallback(id) {
return foundCount, false // Don't continue searching
*foundCount++
if !resultCallback(id, context) {
return false // Don't continue searching
} }
} }
} }
} }
return foundCount, true // Continue searching
return true // Continue searching
} }

40
vendor/d1/rtree.go vendored
View File

@ -55,7 +55,7 @@ const (
USE_SPHERICAL_VOLUME = true // Better split classification, may be slower on some systems USE_SPHERICAL_VOLUME = true // Better split classification, may be slower on some systems
) )
type ResultCallback func(dataID, context interface{}) bool type ResultCallback func(dataID interface{}) bool
var unitSphereVolume float64 var unitSphereVolume float64
@ -185,7 +185,7 @@ func (tr *RTree) Remove(min, max [NUMDIMS]float64, dataId interface{}) {
/// \param a_resultCallback Callback function to return result. Callback should return 'true' to continue searching /// \param a_resultCallback Callback function to return result. Callback should return 'true' to continue searching
/// \param a_context User context to pass as parameter to a_resultCallback /// \param a_context User context to pass as parameter to a_resultCallback
/// \return Returns the number of entries found /// \return Returns the number of entries found
func (tr *RTree) Search(min, max [NUMDIMS]float64, resultCallback ResultCallback, context interface{}) int { func (tr *RTree) Search(min, max [NUMDIMS]float64, resultCallback ResultCallback) int {
if _DEBUG { if _DEBUG {
for index := 0; index < NUMDIMS; index++ { for index := 0; index < NUMDIMS; index++ {
ASSERT(min[index] <= max[index]) ASSERT(min[index] <= max[index])
@ -196,10 +196,7 @@ func (tr *RTree) Search(min, max [NUMDIMS]float64, resultCallback ResultCallback
rect.min[axis] = min[axis] rect.min[axis] = min[axis]
rect.max[axis] = max[axis] rect.max[axis] = max[axis]
} }
// NOTE: May want to return search result another way, perhaps returning the number of found elements here. foundCount, _ := Search(tr.root, rect, 0, resultCallback)
foundCount := 0
Search(tr.root, &rect, &foundCount, resultCallback, context)
return foundCount return foundCount
} }
@ -728,7 +725,7 @@ func RemoveRectRec(rect *Rect, id interface{}, node *Node, listNode **ListNode)
if node.IsInternalNode() { // not a leaf node if node.IsInternalNode() { // not a leaf node
for index := 0; index < node.count; index++ { for index := 0; index < node.count; index++ {
if Overlap(rect, &(node.branch[index].rect)) { if Overlap(*rect, node.branch[index].rect) {
if !RemoveRectRec(rect, id, node.branch[index].child, listNode) { if !RemoveRectRec(rect, id, node.branch[index].child, listNode) {
if node.branch[index].child.count >= MINNODES { if node.branch[index].child.count >= MINNODES {
// child removed, just resize parent rect // child removed, just resize parent rect
@ -755,9 +752,7 @@ func RemoveRectRec(rect *Rect, id interface{}, node *Node, listNode **ListNode)
} }
// Decide whether two rectangles overlap. // Decide whether two rectangles overlap.
func Overlap(rectA, rectB *Rect) bool { func Overlap(rectA, rectB Rect) bool {
ASSERT(rectA != nil && rectB != nil)
for index := 0; index < NUMDIMS; index++ { for index := 0; index < NUMDIMS; index++ {
if rectA.min[index] > rectB.max[index] || if rectA.min[index] > rectB.max[index] ||
rectB.min[index] > rectA.max[index] { rectB.min[index] > rectA.max[index] {
@ -777,37 +772,34 @@ func ReInsert(node *Node, listNode **ListNode) {
} }
// Search in an index tree or subtree for all data retangles that overlap the argument rectangle. // Search in an index tree or subtree for all data retangles that overlap the argument rectangle.
func Search(node *Node, rect *Rect, foundCount *int, resultCallback ResultCallback, context interface{}) bool { func Search(node *Node, rect Rect, foundCount int, resultCallback ResultCallback) (int, bool) {
ASSERT(node != nil) ASSERT(node != nil)
ASSERT(node.level >= 0) ASSERT(node.level >= 0)
ASSERT(rect != nil)
if node.IsInternalNode() { if node.IsInternalNode() {
// This is an internal node in the tree // This is an internal node in the tree
for index := 0; index < node.count; index++ { for index := 0; index < node.count; index++ {
if Overlap(rect, &node.branch[index].rect) { if Overlap(rect, node.branch[index].rect) {
if !Search(node.branch[index].child, rect, foundCount, resultCallback, context) { var ok bool
foundCount, ok = Search(node.branch[index].child, rect, foundCount, resultCallback)
if !ok {
// The callback indicated to stop searching // The callback indicated to stop searching
return false return foundCount, false
} }
} }
} }
} else { } else {
// This is a leaf node // This is a leaf node
for index := 0; index < node.count; index++ { for index := 0; index < node.count; index++ {
if Overlap(rect, &node.branch[index].rect) { if Overlap(rect, node.branch[index].rect) {
id := node.branch[index].data id := node.branch[index].data
foundCount++
// NOTE: There are different ways to return results. Here's where to modify if !resultCallback(id) {
return foundCount, false // Don't continue searching
*foundCount++
if !resultCallback(id, context) {
return false // Don't continue searching
} }
} }
} }
} }
return foundCount, true // Continue searching
return true // Continue searching
} }

40
vendor/d2/rtree.go vendored
View File

@ -55,7 +55,7 @@ const (
USE_SPHERICAL_VOLUME = true // Better split classification, may be slower on some systems USE_SPHERICAL_VOLUME = true // Better split classification, may be slower on some systems
) )
type ResultCallback func(dataID, context interface{}) bool type ResultCallback func(dataID interface{}) bool
var unitSphereVolume float64 var unitSphereVolume float64
@ -185,7 +185,7 @@ func (tr *RTree) Remove(min, max [NUMDIMS]float64, dataId interface{}) {
/// \param a_resultCallback Callback function to return result. Callback should return 'true' to continue searching /// \param a_resultCallback Callback function to return result. Callback should return 'true' to continue searching
/// \param a_context User context to pass as parameter to a_resultCallback /// \param a_context User context to pass as parameter to a_resultCallback
/// \return Returns the number of entries found /// \return Returns the number of entries found
func (tr *RTree) Search(min, max [NUMDIMS]float64, resultCallback ResultCallback, context interface{}) int { func (tr *RTree) Search(min, max [NUMDIMS]float64, resultCallback ResultCallback) int {
if _DEBUG { if _DEBUG {
for index := 0; index < NUMDIMS; index++ { for index := 0; index < NUMDIMS; index++ {
ASSERT(min[index] <= max[index]) ASSERT(min[index] <= max[index])
@ -196,10 +196,7 @@ func (tr *RTree) Search(min, max [NUMDIMS]float64, resultCallback ResultCallback
rect.min[axis] = min[axis] rect.min[axis] = min[axis]
rect.max[axis] = max[axis] rect.max[axis] = max[axis]
} }
// NOTE: May want to return search result another way, perhaps returning the number of found elements here. foundCount, _ := Search(tr.root, rect, 0, resultCallback)
foundCount := 0
Search(tr.root, &rect, &foundCount, resultCallback, context)
return foundCount return foundCount
} }
@ -728,7 +725,7 @@ func RemoveRectRec(rect *Rect, id interface{}, node *Node, listNode **ListNode)
if node.IsInternalNode() { // not a leaf node if node.IsInternalNode() { // not a leaf node
for index := 0; index < node.count; index++ { for index := 0; index < node.count; index++ {
if Overlap(rect, &(node.branch[index].rect)) { if Overlap(*rect, node.branch[index].rect) {
if !RemoveRectRec(rect, id, node.branch[index].child, listNode) { if !RemoveRectRec(rect, id, node.branch[index].child, listNode) {
if node.branch[index].child.count >= MINNODES { if node.branch[index].child.count >= MINNODES {
// child removed, just resize parent rect // child removed, just resize parent rect
@ -755,9 +752,7 @@ func RemoveRectRec(rect *Rect, id interface{}, node *Node, listNode **ListNode)
} }
// Decide whether two rectangles overlap. // Decide whether two rectangles overlap.
func Overlap(rectA, rectB *Rect) bool { func Overlap(rectA, rectB Rect) bool {
ASSERT(rectA != nil && rectB != nil)
for index := 0; index < NUMDIMS; index++ { for index := 0; index < NUMDIMS; index++ {
if rectA.min[index] > rectB.max[index] || if rectA.min[index] > rectB.max[index] ||
rectB.min[index] > rectA.max[index] { rectB.min[index] > rectA.max[index] {
@ -777,37 +772,34 @@ func ReInsert(node *Node, listNode **ListNode) {
} }
// Search in an index tree or subtree for all data retangles that overlap the argument rectangle. // Search in an index tree or subtree for all data retangles that overlap the argument rectangle.
func Search(node *Node, rect *Rect, foundCount *int, resultCallback ResultCallback, context interface{}) bool { func Search(node *Node, rect Rect, foundCount int, resultCallback ResultCallback) (int, bool) {
ASSERT(node != nil) ASSERT(node != nil)
ASSERT(node.level >= 0) ASSERT(node.level >= 0)
ASSERT(rect != nil)
if node.IsInternalNode() { if node.IsInternalNode() {
// This is an internal node in the tree // This is an internal node in the tree
for index := 0; index < node.count; index++ { for index := 0; index < node.count; index++ {
if Overlap(rect, &node.branch[index].rect) { if Overlap(rect, node.branch[index].rect) {
if !Search(node.branch[index].child, rect, foundCount, resultCallback, context) { var ok bool
foundCount, ok = Search(node.branch[index].child, rect, foundCount, resultCallback)
if !ok {
// The callback indicated to stop searching // The callback indicated to stop searching
return false return foundCount, false
} }
} }
} }
} else { } else {
// This is a leaf node // This is a leaf node
for index := 0; index < node.count; index++ { for index := 0; index < node.count; index++ {
if Overlap(rect, &node.branch[index].rect) { if Overlap(rect, node.branch[index].rect) {
id := node.branch[index].data id := node.branch[index].data
foundCount++
// NOTE: There are different ways to return results. Here's where to modify if !resultCallback(id) {
return foundCount, false // Don't continue searching
*foundCount++
if !resultCallback(id, context) {
return false // Don't continue searching
} }
} }
} }
} }
return foundCount, true // Continue searching
return true // Continue searching
} }

40
vendor/d3/rtree.go vendored
View File

@ -55,7 +55,7 @@ const (
USE_SPHERICAL_VOLUME = true // Better split classification, may be slower on some systems USE_SPHERICAL_VOLUME = true // Better split classification, may be slower on some systems
) )
type ResultCallback func(dataID, context interface{}) bool type ResultCallback func(dataID interface{}) bool
var unitSphereVolume float64 var unitSphereVolume float64
@ -185,7 +185,7 @@ func (tr *RTree) Remove(min, max [NUMDIMS]float64, dataId interface{}) {
/// \param a_resultCallback Callback function to return result. Callback should return 'true' to continue searching /// \param a_resultCallback Callback function to return result. Callback should return 'true' to continue searching
/// \param a_context User context to pass as parameter to a_resultCallback /// \param a_context User context to pass as parameter to a_resultCallback
/// \return Returns the number of entries found /// \return Returns the number of entries found
func (tr *RTree) Search(min, max [NUMDIMS]float64, resultCallback ResultCallback, context interface{}) int { func (tr *RTree) Search(min, max [NUMDIMS]float64, resultCallback ResultCallback) int {
if _DEBUG { if _DEBUG {
for index := 0; index < NUMDIMS; index++ { for index := 0; index < NUMDIMS; index++ {
ASSERT(min[index] <= max[index]) ASSERT(min[index] <= max[index])
@ -196,10 +196,7 @@ func (tr *RTree) Search(min, max [NUMDIMS]float64, resultCallback ResultCallback
rect.min[axis] = min[axis] rect.min[axis] = min[axis]
rect.max[axis] = max[axis] rect.max[axis] = max[axis]
} }
// NOTE: May want to return search result another way, perhaps returning the number of found elements here. foundCount, _ := Search(tr.root, rect, 0, resultCallback)
foundCount := 0
Search(tr.root, &rect, &foundCount, resultCallback, context)
return foundCount return foundCount
} }
@ -728,7 +725,7 @@ func RemoveRectRec(rect *Rect, id interface{}, node *Node, listNode **ListNode)
if node.IsInternalNode() { // not a leaf node if node.IsInternalNode() { // not a leaf node
for index := 0; index < node.count; index++ { for index := 0; index < node.count; index++ {
if Overlap(rect, &(node.branch[index].rect)) { if Overlap(*rect, node.branch[index].rect) {
if !RemoveRectRec(rect, id, node.branch[index].child, listNode) { if !RemoveRectRec(rect, id, node.branch[index].child, listNode) {
if node.branch[index].child.count >= MINNODES { if node.branch[index].child.count >= MINNODES {
// child removed, just resize parent rect // child removed, just resize parent rect
@ -755,9 +752,7 @@ func RemoveRectRec(rect *Rect, id interface{}, node *Node, listNode **ListNode)
} }
// Decide whether two rectangles overlap. // Decide whether two rectangles overlap.
func Overlap(rectA, rectB *Rect) bool { func Overlap(rectA, rectB Rect) bool {
ASSERT(rectA != nil && rectB != nil)
for index := 0; index < NUMDIMS; index++ { for index := 0; index < NUMDIMS; index++ {
if rectA.min[index] > rectB.max[index] || if rectA.min[index] > rectB.max[index] ||
rectB.min[index] > rectA.max[index] { rectB.min[index] > rectA.max[index] {
@ -777,37 +772,34 @@ func ReInsert(node *Node, listNode **ListNode) {
} }
// Search in an index tree or subtree for all data retangles that overlap the argument rectangle. // Search in an index tree or subtree for all data retangles that overlap the argument rectangle.
func Search(node *Node, rect *Rect, foundCount *int, resultCallback ResultCallback, context interface{}) bool { func Search(node *Node, rect Rect, foundCount int, resultCallback ResultCallback) (int, bool) {
ASSERT(node != nil) ASSERT(node != nil)
ASSERT(node.level >= 0) ASSERT(node.level >= 0)
ASSERT(rect != nil)
if node.IsInternalNode() { if node.IsInternalNode() {
// This is an internal node in the tree // This is an internal node in the tree
for index := 0; index < node.count; index++ { for index := 0; index < node.count; index++ {
if Overlap(rect, &node.branch[index].rect) { if Overlap(rect, node.branch[index].rect) {
if !Search(node.branch[index].child, rect, foundCount, resultCallback, context) { var ok bool
foundCount, ok = Search(node.branch[index].child, rect, foundCount, resultCallback)
if !ok {
// The callback indicated to stop searching // The callback indicated to stop searching
return false return foundCount, false
} }
} }
} }
} else { } else {
// This is a leaf node // This is a leaf node
for index := 0; index < node.count; index++ { for index := 0; index < node.count; index++ {
if Overlap(rect, &node.branch[index].rect) { if Overlap(rect, node.branch[index].rect) {
id := node.branch[index].data id := node.branch[index].data
foundCount++
// NOTE: There are different ways to return results. Here's where to modify if !resultCallback(id) {
return foundCount, false // Don't continue searching
*foundCount++
if !resultCallback(id, context) {
return false // Don't continue searching
} }
} }
} }
} }
return foundCount, true // Continue searching
return true // Continue searching
} }

40
vendor/d4/rtree.go vendored
View File

@ -55,7 +55,7 @@ const (
USE_SPHERICAL_VOLUME = true // Better split classification, may be slower on some systems USE_SPHERICAL_VOLUME = true // Better split classification, may be slower on some systems
) )
type ResultCallback func(dataID, context interface{}) bool type ResultCallback func(dataID interface{}) bool
var unitSphereVolume float64 var unitSphereVolume float64
@ -185,7 +185,7 @@ func (tr *RTree) Remove(min, max [NUMDIMS]float64, dataId interface{}) {
/// \param a_resultCallback Callback function to return result. Callback should return 'true' to continue searching /// \param a_resultCallback Callback function to return result. Callback should return 'true' to continue searching
/// \param a_context User context to pass as parameter to a_resultCallback /// \param a_context User context to pass as parameter to a_resultCallback
/// \return Returns the number of entries found /// \return Returns the number of entries found
func (tr *RTree) Search(min, max [NUMDIMS]float64, resultCallback ResultCallback, context interface{}) int { func (tr *RTree) Search(min, max [NUMDIMS]float64, resultCallback ResultCallback) int {
if _DEBUG { if _DEBUG {
for index := 0; index < NUMDIMS; index++ { for index := 0; index < NUMDIMS; index++ {
ASSERT(min[index] <= max[index]) ASSERT(min[index] <= max[index])
@ -196,10 +196,7 @@ func (tr *RTree) Search(min, max [NUMDIMS]float64, resultCallback ResultCallback
rect.min[axis] = min[axis] rect.min[axis] = min[axis]
rect.max[axis] = max[axis] rect.max[axis] = max[axis]
} }
// NOTE: May want to return search result another way, perhaps returning the number of found elements here. foundCount, _ := Search(tr.root, rect, 0, resultCallback)
foundCount := 0
Search(tr.root, &rect, &foundCount, resultCallback, context)
return foundCount return foundCount
} }
@ -728,7 +725,7 @@ func RemoveRectRec(rect *Rect, id interface{}, node *Node, listNode **ListNode)
if node.IsInternalNode() { // not a leaf node if node.IsInternalNode() { // not a leaf node
for index := 0; index < node.count; index++ { for index := 0; index < node.count; index++ {
if Overlap(rect, &(node.branch[index].rect)) { if Overlap(*rect, node.branch[index].rect) {
if !RemoveRectRec(rect, id, node.branch[index].child, listNode) { if !RemoveRectRec(rect, id, node.branch[index].child, listNode) {
if node.branch[index].child.count >= MINNODES { if node.branch[index].child.count >= MINNODES {
// child removed, just resize parent rect // child removed, just resize parent rect
@ -755,9 +752,7 @@ func RemoveRectRec(rect *Rect, id interface{}, node *Node, listNode **ListNode)
} }
// Decide whether two rectangles overlap. // Decide whether two rectangles overlap.
func Overlap(rectA, rectB *Rect) bool { func Overlap(rectA, rectB Rect) bool {
ASSERT(rectA != nil && rectB != nil)
for index := 0; index < NUMDIMS; index++ { for index := 0; index < NUMDIMS; index++ {
if rectA.min[index] > rectB.max[index] || if rectA.min[index] > rectB.max[index] ||
rectB.min[index] > rectA.max[index] { rectB.min[index] > rectA.max[index] {
@ -777,37 +772,34 @@ func ReInsert(node *Node, listNode **ListNode) {
} }
// Search in an index tree or subtree for all data retangles that overlap the argument rectangle. // Search in an index tree or subtree for all data retangles that overlap the argument rectangle.
func Search(node *Node, rect *Rect, foundCount *int, resultCallback ResultCallback, context interface{}) bool { func Search(node *Node, rect Rect, foundCount int, resultCallback ResultCallback) (int, bool) {
ASSERT(node != nil) ASSERT(node != nil)
ASSERT(node.level >= 0) ASSERT(node.level >= 0)
ASSERT(rect != nil)
if node.IsInternalNode() { if node.IsInternalNode() {
// This is an internal node in the tree // This is an internal node in the tree
for index := 0; index < node.count; index++ { for index := 0; index < node.count; index++ {
if Overlap(rect, &node.branch[index].rect) { if Overlap(rect, node.branch[index].rect) {
if !Search(node.branch[index].child, rect, foundCount, resultCallback, context) { var ok bool
foundCount, ok = Search(node.branch[index].child, rect, foundCount, resultCallback)
if !ok {
// The callback indicated to stop searching // The callback indicated to stop searching
return false return foundCount, false
} }
} }
} }
} else { } else {
// This is a leaf node // This is a leaf node
for index := 0; index < node.count; index++ { for index := 0; index < node.count; index++ {
if Overlap(rect, &node.branch[index].rect) { if Overlap(rect, node.branch[index].rect) {
id := node.branch[index].data id := node.branch[index].data
foundCount++
// NOTE: There are different ways to return results. Here's where to modify if !resultCallback(id) {
return foundCount, false // Don't continue searching
*foundCount++
if !resultCallback(id, context) {
return false // Don't continue searching
} }
} }
} }
} }
return foundCount, true // Continue searching
return true // Continue searching
} }