Skip to content

Commit

Permalink
convert to array-based points map (#349)
Browse files Browse the repository at this point in the history
  • Loading branch information
friendlymatthew authored Jun 20, 2024
1 parent cbb0221 commit b9a7069
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 25 deletions.
19 changes: 6 additions & 13 deletions pkg/hnsw/hnsw.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type Hnsw struct {

entryPointId Id

points map[Id]*Point
points []*Point
friends map[Id]*Friends

levelMultiplier float64
Expand All @@ -37,8 +37,8 @@ func NewHnsw(d int, efConstruction int, M int, entryPoint Point) *Hnsw {
friends := make(map[Id]*Friends)
friends[defaultEntryPointId] = NewFriends(0)

points := make(map[Id]*Point)
points[defaultEntryPointId] = &entryPoint
points := make([]*Point, 0)
points = append(points, &entryPoint)

return &Hnsw{
entryPointId: defaultEntryPointId,
Expand Down Expand Up @@ -102,10 +102,7 @@ func (h *Hnsw) searchLevel(q *Point, entryItem *Item, numNearestToQToReturn, lev
return nil, fmt.Errorf("error during searching level %d: %w", level, err)
}

ccFriendPoint, ok := h.points[ccFriendId]
if !ok {
return nil, ErrNodeNotFound
}
ccFriendPoint := h.points[ccFriendId]

// if distance(ccFriend, q) < distance(f, q)
ccFriendDistToQ := EuclidDistance(*ccFriendPoint, *q)
Expand Down Expand Up @@ -194,7 +191,7 @@ func (h *Hnsw) InsertVector(q Point) error {

qFriends := NewFriends(qTopLevel)
h.friends[qId] = qFriends
h.points[qId] = &q
h.points = append(h.points, &q)

entryItem := h.findCloserEntryPoint(&q, qFriends)

Expand Down Expand Up @@ -254,11 +251,7 @@ func (h *Hnsw) isValidPoint(point Point) bool {
}

func (h *Hnsw) KnnSearch(q Point, numNeighborsToReturn int) (*DistHeap, error) {
entryPoint, ok := h.points[h.entryPointId]

if !ok {
return nil, fmt.Errorf("no point found for entry point %v", h.entryPointId)
}
entryPoint := h.points[h.entryPointId]

entryPointFriends, ok := h.friends[h.entryPointId]
if !ok {
Expand Down
18 changes: 6 additions & 12 deletions pkg/hnsw/hnsw_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func SetupClusterHnsw(cluster []Point, efc, maxConnections int) (*Hnsw, error) {

for idx, point := range cluster {
pointId := Id(idx + 1)
g.points[pointId] = &point
g.points = append(g.points, &point)
g.friends[pointId] = NewFriends(0)

distEntryToClusterPoint := EuclidDistance(entryPoint, point)
Expand Down Expand Up @@ -90,7 +90,7 @@ func TestHnsw_SearchLevel(t *testing.T) {
entryPoint := Point{0, 0}
g := NewHnsw(2, 4, 4, entryPoint)
mPoint := Point{2, 2}
g.points[Id(1)] = &mPoint
g.points = append(g.points, &mPoint)

g.friends[g.entryPointId].InsertFriendsAtLevel(0, 1, EuclidDistance(mPoint, entryPoint))
g.friends[Id(1)] = NewFriends(0)
Expand Down Expand Up @@ -124,10 +124,7 @@ func TestHnsw_SearchLevel(t *testing.T) {
t.Fatal(err)
}

entryPoint, ok := g.points[g.entryPointId]
if !ok {
t.Fatal(ErrNodeNotFound)
}
entryPoint := g.points[g.entryPointId]

qPoint := clusterA[3]
expectedId := Id(4)
Expand Down Expand Up @@ -169,10 +166,7 @@ func TestHnsw_SearchLevel(t *testing.T) {
t.Fatal(err)
}

entryPoint, ok := g.points[g.entryPointId]
if !ok {
t.Fatal(ErrNodeNotFound)
}
entryPoint := g.points[g.entryPointId]

qPoint := Point{0.3, 0.81}
expectedId := Id(3) // point3 is (0.3, 0.8)
Expand Down Expand Up @@ -285,7 +279,7 @@ func TestHnsw_FindCloserEntryPoint(t *testing.T) {
closerPointId := Id(1)
closerPoint := Point{2, 2}

h.points[closerPointId] = &closerPoint
h.points = append(h.points, &closerPoint)
h.friends[closerPointId] = NewFriends(4)

distToEntry := EuclidDistance(Point{0, 0}, closerPoint)
Expand All @@ -312,7 +306,7 @@ func TestHnsw_FindCloserEntryPoint(t *testing.T) {
closerPointId := Id(1)
closerPoint := Point{2, 2}

h.points[closerPointId] = &closerPoint
h.points = append(h.points, &closerPoint)
h.friends[closerPointId] = NewFriends(4)

distToEntry := EuclidDistance(Point{0, 0}, closerPoint)
Expand Down

0 comments on commit b9a7069

Please sign in to comment.