Skip to content

Commit

Permalink
Merge branch 'master' into 4923-gopacket-dhcp-vol.7
Browse files Browse the repository at this point in the history
  • Loading branch information
EugeneOne1 committed Feb 19, 2024
2 parents 38b3165 + bd99e3e commit 0f90eb3
Show file tree
Hide file tree
Showing 11 changed files with 786 additions and 88 deletions.
16 changes: 15 additions & 1 deletion bamboo-specs/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
'name': 'AdGuard Home - Build and run tests'
'variables':
'dockerGo': 'adguard/golang-ubuntu:8.0'
'channel': 'development'

'stages':
- 'Tests':
Expand Down Expand Up @@ -73,7 +74,7 @@
make\
ARCH="amd64"\
OS="windows darwin linux"\
CHANNEL="development"\
CHANNEL=${bamboo.channel}\
SIGN=0\
PARALLELISM=1\
VERBOSE=2\
Expand Down Expand Up @@ -115,3 +116,16 @@
'labels': []
'other':
'concurrent-build-plugin': 'system-default'

'branch-overrides':
# rc-vX.Y.Z branches are the release candidate branches. They are created
# from the release branch and are used to build the release candidate
# images.
- '^rc-v[0-9]+\.[0-9]+\.[0-9]+':
# Build betas on release branches manually.
'triggers': []
# Set the default release channel on the release branch to beta, as we
# may need to build a few of these.
'variables':
'dockerGo': 'adguard/golang-ubuntu:8.0'
'channel': 'candidate'
86 changes: 86 additions & 0 deletions internal/aghalg/sortedmap.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package aghalg

import (
"slices"
)

// SortedMap is a map that keeps elements in order with internal sorting
// function. Must be initialised by the [NewSortedMap].
type SortedMap[K comparable, V any] struct {
vals map[K]V
cmp func(a, b K) (res int)
keys []K
}

// NewSortedMap initializes the new instance of sorted map. cmp is a sort
// function to keep elements in order.
//
// TODO(s.chzhen): Use cmp.Compare in Go 1.21.
func NewSortedMap[K comparable, V any](cmp func(a, b K) (res int)) SortedMap[K, V] {
return SortedMap[K, V]{
vals: map[K]V{},
cmp: cmp,
}
}

// Set adds val with key to the sorted map. It panics if the m is nil.
func (m *SortedMap[K, V]) Set(key K, val V) {
m.vals[key] = val

i, has := slices.BinarySearchFunc(m.keys, key, m.cmp)
if has {
m.keys[i] = key
} else {
m.keys = slices.Insert(m.keys, i, key)
}
}

// Get returns val by key from the sorted map.
func (m *SortedMap[K, V]) Get(key K) (val V, ok bool) {
if m == nil {
return
}

val, ok = m.vals[key]

return val, ok
}

// Del removes the value by key from the sorted map.
func (m *SortedMap[K, V]) Del(key K) {
if m == nil {
return
}

if _, has := m.vals[key]; !has {
return
}

delete(m.vals, key)
i, _ := slices.BinarySearchFunc(m.keys, key, m.cmp)
m.keys = slices.Delete(m.keys, i, i+1)
}

// Clear removes all elements from the sorted map.
func (m *SortedMap[K, V]) Clear() {
if m == nil {
return
}

m.keys = nil
clear(m.vals)
}

// Range calls cb for each element of the map, sorted by m.cmp. If cb returns
// false it stops.
func (m *SortedMap[K, V]) Range(cb func(K, V) (cont bool)) {
if m == nil {
return
}

for _, k := range m.keys {
if !cb(k, m.vals[k]) {
return
}
}
}
95 changes: 95 additions & 0 deletions internal/aghalg/sortedmap_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package aghalg

import (
"strings"
"testing"

"github.com/stretchr/testify/assert"
)

func TestNewSortedMap(t *testing.T) {
var m SortedMap[string, int]

letters := []string{}
for i := 0; i < 10; i++ {
r := string('a' + rune(i))
letters = append(letters, r)
}

t.Run("create_and_fill", func(t *testing.T) {
m = NewSortedMap[string, int](strings.Compare)

nums := []int{}
for i, r := range letters {
m.Set(r, i)
nums = append(nums, i)
}

gotLetters := []string{}
gotNums := []int{}
m.Range(func(k string, v int) bool {
gotLetters = append(gotLetters, k)
gotNums = append(gotNums, v)

return true
})

assert.Equal(t, letters, gotLetters)
assert.Equal(t, nums, gotNums)

n, ok := m.Get(letters[0])
assert.True(t, ok)
assert.Equal(t, nums[0], n)
})

t.Run("clear", func(t *testing.T) {
lastLetter := letters[len(letters)-1]
m.Del(lastLetter)

_, ok := m.Get(lastLetter)
assert.False(t, ok)

m.Clear()

gotLetters := []string{}
m.Range(func(k string, _ int) bool {
gotLetters = append(gotLetters, k)

return true
})

assert.Len(t, gotLetters, 0)
})
}

func TestNewSortedMap_nil(t *testing.T) {
const (
key = "key"
val = "val"
)

var m SortedMap[string, string]

assert.Panics(t, func() {
m.Set(key, val)
})

assert.NotPanics(t, func() {
_, ok := m.Get(key)
assert.False(t, ok)
})

assert.NotPanics(t, func() {
m.Range(func(_, _ string) (cont bool) {
return true
})
})

assert.NotPanics(t, func() {
m.Del(key)
})

assert.NotPanics(t, func() {
m.Clear()
})
}
10 changes: 10 additions & 0 deletions internal/home/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ func NewUID() (uid UID, err error) {
return UID(uuidv7), err
}

// MustNewUID is a wrapper around [NewUID] that panics if there is an error.
func MustNewUID() (uid UID) {
uid, err := NewUID()
if err != nil {
panic(fmt.Errorf("unexpected uuidv7 error: %w", err))
}

return uid
}

// type check
var _ encoding.TextMarshaler = UID{}

Expand Down
Loading

0 comments on commit 0f90eb3

Please sign in to comment.