-
Notifications
You must be signed in to change notification settings - Fork 674
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. | ||
// See the file LICENSE for licensing terms. | ||
|
||
package heap | ||
|
||
// NewSet returns a heap without duplicates ordered by its values | ||
func NewSet[T comparable](less func(a, b T) bool) Set[T] { | ||
return Set[T]{ | ||
set: Map[T, struct{}]{ | ||
queue: &indexedQueue[T, struct{}]{ | ||
entries: make([]entry[T, struct{}], 0), | ||
Check failure on line 11 in utils/heap/set.go GitHub Actions / test_e2e
Check failure on line 11 in utils/heap/set.go GitHub Actions / test_upgrade
Check failure on line 11 in utils/heap/set.go GitHub Actions / test_e2e_persistent
Check failure on line 11 in utils/heap/set.go GitHub Actions / build_unit_test (macos-12)
Check failure on line 11 in utils/heap/set.go GitHub Actions / build_unit_test (ubuntu-20.04)
|
||
index: make(map[T]int), | ||
less: func(a, b entry[T, struct{}]) bool { | ||
Check failure on line 13 in utils/heap/set.go GitHub Actions / test_e2e
Check failure on line 13 in utils/heap/set.go GitHub Actions / test_upgrade
Check failure on line 13 in utils/heap/set.go GitHub Actions / test_e2e_persistent
Check failure on line 13 in utils/heap/set.go GitHub Actions / build_unit_test (macos-12)
Check failure on line 13 in utils/heap/set.go GitHub Actions / build_unit_test (ubuntu-20.04)
|
||
return less(a.k, b.k) | ||
}, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
type Set[T comparable] struct { | ||
set Map[T, struct{}] | ||
} | ||
|
||
// Push returns if a value was overwritten | ||
func (s Set[T]) Push(t T) bool { | ||
_, ok := s.set.Push(t, struct{}{}) | ||
return ok | ||
} | ||
|
||
func (s Set[T]) Pop() (T, bool) { | ||
pop, _, ok := s.set.Pop() | ||
return pop, ok | ||
} | ||
|
||
func (s Set[T]) Peek() (T, bool) { | ||
peek, _, ok := s.set.Peek() | ||
return peek, ok | ||
} | ||
|
||
func (s Set[T]) Len() int { | ||
return s.set.Len() | ||
} | ||
|
||
func (s Set[T]) Remove(i int) T { | ||
remove, _ := s.set.Remove(i) | ||
return remove | ||
} | ||
|
||
func (s Set[T]) Fix(i int) { | ||
s.set.Fix(i) | ||
} | ||
|
||
func (s Set[T]) Index() map[T]int { | ||
return s.set.queue.index | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. | ||
// See the file LICENSE for licensing terms. | ||
|
||
package heap | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestSet(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
setup func(h Set[int]) | ||
expected []int | ||
}{ | ||
{ | ||
name: "only push", | ||
setup: func(h Set[int]) { | ||
h.Push(1) | ||
h.Push(2) | ||
h.Push(3) | ||
}, | ||
expected: []int{1, 2, 3}, | ||
}, | ||
{ | ||
name: "out of order pushes", | ||
setup: func(h Set[int]) { | ||
h.Push(1) | ||
h.Push(5) | ||
h.Push(2) | ||
h.Push(4) | ||
h.Push(3) | ||
}, | ||
expected: []int{1, 2, 3, 4, 5}, | ||
}, | ||
{ | ||
name: "push and pop", | ||
setup: func(h Set[int]) { | ||
h.Push(1) | ||
h.Push(5) | ||
h.Push(2) | ||
h.Push(4) | ||
h.Push(3) | ||
h.Pop() | ||
h.Pop() | ||
h.Pop() | ||
}, | ||
expected: []int{4, 5}, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
require := require.New(t) | ||
|
||
h := NewSet[int](func(a, b int) bool { | ||
return a < b | ||
}) | ||
|
||
tt.setup(h) | ||
|
||
require.Equal(len(tt.expected), h.Len()) | ||
for _, expected := range tt.expected { | ||
got, ok := h.Pop() | ||
require.True(ok) | ||
require.Equal(expected, got) | ||
} | ||
}) | ||
} | ||
} |