Skip to content

Commit

Permalink
removed PointMinHeap and PointMaxHeap
Browse files Browse the repository at this point in the history
  • Loading branch information
yuzhichang committed Sep 26, 2017
1 parent 7c1b9d5 commit 18c7585
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 140 deletions.
80 changes: 12 additions & 68 deletions point.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/binary"
"sort"

datastructures "github.com/deepfabric/go-datastructures"
"github.com/keegancsmith/nth"
)

Expand All @@ -12,12 +13,6 @@ type Point struct {
UserData uint64
}

// PointMinHeap is a min-heap of points.
type PointMinHeap []Point

// PointMaxHeap is a max-heap of points.
type PointMaxHeap []Point

type PointArray interface {
sort.Interface
GetPoint(idx int) Point
Expand All @@ -41,6 +36,17 @@ type PointArrayExt struct {
pointSize int
}

// Compare is part of datastructures.Comparable interface
func (p Point) Compare(other datastructures.Comparable) int {
rhs := other.(Point)
for dim := 0; dim < len(p.Vals); dim++ {
if p.Vals[dim] != rhs.Vals[dim] {
return int(p.Vals[dim] - rhs.Vals[dim])
}
}
return int(p.UserData - rhs.UserData)
}

func (p *Point) Inside(lowPoint, highPoint Point) (isInside bool) {
for dim := 0; dim < len(p.Vals); dim++ {
if p.Vals[dim] < lowPoint.Vals[dim] || p.Vals[dim] > highPoint.Vals[dim] {
Expand Down Expand Up @@ -111,68 +117,6 @@ func (p *Point) Decode(b []byte, numDims int, bytesPerDim int) {
return
}

// Len is part of sort.Interface.
func (s PointMinHeap) Len() int {
return len(s)
}

// Swap is part of sort.Interface.
func (s PointMinHeap) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}

// Less is part of sort.Interface.
func (s PointMinHeap) Less(i, j int) bool {
return s[i].LessThan(s[j])
}

// Push is part of heap.Interface.
func (s *PointMinHeap) Push(x interface{}) {
// Push and Pop use pointer receivers because they modify the slice's length,
// not just its contents.
*s = append(*s, x.(Point))
}

// Pop is part of heap.Interface.
func (s *PointMinHeap) Pop() interface{} {
old := *s
n := len(old)
x := old[n-1]
*s = old[0 : n-1]
return x
}

// Len is part of sort.Interface.
func (s PointMaxHeap) Len() int {
return len(s)
}

// Swap is part of sort.Interface.
func (s PointMaxHeap) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}

// Less is part of sort.Interface.
func (s PointMaxHeap) Less(i, j int) bool {
return s[j].LessThan(s[i])
}

// Push is part of heap.Interface.
func (s *PointMaxHeap) Push(x interface{}) {
// Push and Pop use pointer receivers because they modify the slice's length,
// not just its contents.
*s = append(*s, x.(Point))
}

// Pop is part of heap.Interface.
func (s *PointMaxHeap) Pop() interface{} {
old := *s
n := len(old)
x := old[n-1]
*s = old[0 : n-1]
return x
}

// Len is part of sort.Interface.
func (s *PointArrayMem) Len() int {
return len(s.points)
Expand Down
72 changes: 0 additions & 72 deletions point_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,9 @@ package bkdtree

import (
"bytes"
"container/heap"
"fmt"
"math/rand"
"os"
"testing"

"sort"

"github.com/juju/testing/checkers"
)

type CaseInside struct {
Expand Down Expand Up @@ -101,72 +95,6 @@ func NewRandPoints(numDims int, maxVal uint64, size int) (points []Point) {
return
}

func TestPointHeap(t *testing.T) {
numDims := 3
maxVal := uint64(100)
size := 10000
points := NewRandPoints(numDims, maxVal, size)
/*There are several ways to build a heap from array:
s := PointMinHeap(points)
h := &s
heap.Init(h)
h := &PointMinHeap{}
*h = points
heap.Init(h)
s := &points
h := (*PointMinHeap)(s)
heap.Init(h)
h := &PointMinHeap{}
for i := 0; i < len(points); i++ {
heap.Push(h, points[i])
}
*/
h := &PointMinHeap{}
*h = points
heap.Init(h)
var prevPoint *Point
var smallestN1 []Point
var smallestN2 []Point
N := 1000
for h.Len() > 0 {
p := heap.Pop(h).(Point)
if prevPoint != nil && p.LessThan(*prevPoint) {
t.Fatalf("incorrect order of %v %v", *prevPoint, p)
}
prevPoint = &p
if len(smallestN1) < N {
smallestN1 = append(smallestN1, p)
}
}

/*Inspired by https://stackoverflow.com/questions/5845810/constant-size-priority-queue-insert-first-or-delete-first
h2 is a max-heap which stores the N smallest points found so far. The top (largest) is at index zero.
*/
h2 := &PointMaxHeap{}
heap.Init(h2)
for i := 0; i < len(points); i++ {
if len(*h2) < N {
h2.Push(points[i])
} else if points[i].LessThan((*h2)[0]) {
(*h2)[0] = points[i]
heap.Fix(h2, 0)
}
}
s := PointMinHeap(*h2)
sort.Sort(&s)
smallestN2 = s
isEqual, err := checkers.DeepEqual(smallestN1, smallestN2)
if !isEqual {
fmt.Printf("smallestN1: %+v\n", smallestN1)
fmt.Printf("smallestN2: %+v\n", smallestN2)
t.Fatalf("smallestN1 and smallestN2 %+v", err)
}
}

func TestPointArrayExt_ToMem(t *testing.T) {
numDims := 3
maxVal := uint64(100)
Expand Down

0 comments on commit 18c7585

Please sign in to comment.