From 72a458520fccafe4df8c02c811cb6f64a310616e Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 13 Jul 2022 21:22:14 -0600 Subject: Move the remaining former-generic.go parts out of lib/util/ --- cmd/btrfs-rec/inspect_lsfiles.go | 6 +-- cmd/btrfs-rec/inspect_lstrees.go | 7 +-- lib/btrfs/btrfsvol/chunk.go | 9 ++-- lib/btrfs/btrfsvol/devext.go | 6 +-- lib/btrfs/io3_btree.go | 3 +- lib/btrfs/io4_fs.go | 6 ++- lib/btrfsprogs/btrfsinspect/mount.go | 18 ++++---- lib/btrfsprogs/btrfsinspect/print_tree.go | 3 +- lib/btrfsprogs/btrfsinspect/recoverchunks.go | 5 +- lib/btrfsprogs/btrfsutil/scan.go | 3 +- lib/containers/rbtree.go | 4 +- lib/containers/syncmap.go | 40 ++++++++++++++++ lib/maps/maputil.go | 25 ++++++++++ lib/slices/sliceutil.go | 69 ++++++++++++++++++++++++++++ lib/util/maputil.go | 23 ---------- lib/util/sliceutil.go | 69 ---------------------------- lib/util/syncmap.go | 40 ---------------- 17 files changed, 174 insertions(+), 162 deletions(-) create mode 100644 lib/containers/syncmap.go create mode 100644 lib/maps/maputil.go create mode 100644 lib/slices/sliceutil.go delete mode 100644 lib/util/maputil.go delete mode 100644 lib/util/sliceutil.go delete mode 100644 lib/util/syncmap.go diff --git a/cmd/btrfs-rec/inspect_lsfiles.go b/cmd/btrfs-rec/inspect_lsfiles.go index 56f76b1..5abfbaf 100644 --- a/cmd/btrfs-rec/inspect_lsfiles.go +++ b/cmd/btrfs-rec/inspect_lsfiles.go @@ -16,7 +16,7 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/btrfs" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsitem" "git.lukeshu.com/btrfs-progs-ng/lib/containers" - "git.lukeshu.com/btrfs-progs-ng/lib/util" + "git.lukeshu.com/btrfs-progs-ng/lib/maps" ) func init() { @@ -129,7 +129,7 @@ func printDir(fs *btrfs.FS, fsTree btrfs.ObjID, prefix0, prefix1, dirName string } fmt.Printf("]\terror: %v\n", err) } - for i, index := range util.SortedMapKeys(membersByIndex) { + for i, index := range maps.SortedKeys(membersByIndex) { entry := membersByIndex[index] namehash := btrfsitem.NameHash(entry.Name) if other, ok := membersByNameHash[namehash]; ok { @@ -148,7 +148,7 @@ func printDir(fs *btrfs.FS, fsTree btrfs.ObjID, prefix0, prefix1, dirName string } printDirEntry(fs, fsTree, prefix1+p0, prefix1+p1, entry) } - for _, namehash := range util.SortedMapKeys(membersByNameHash) { + for _, namehash := range maps.SortedKeys(membersByNameHash) { entry := membersByNameHash[namehash] errs = append(errs, fmt.Errorf("read dir: no DIR_INDEX for DIR_ITEM crc32c(%q)=%#x", entry.Name, namehash)) diff --git a/cmd/btrfs-rec/inspect_lstrees.go b/cmd/btrfs-rec/inspect_lstrees.go index 590ec23..003e7ae 100644 --- a/cmd/btrfs-rec/inspect_lstrees.go +++ b/cmd/btrfs-rec/inspect_lstrees.go @@ -16,7 +16,8 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/btrfs" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsitem" "git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsutil" - "git.lukeshu.com/btrfs-progs-ng/lib/util" + "git.lukeshu.com/btrfs-progs-ng/lib/maps" + "git.lukeshu.com/btrfs-progs-ng/lib/slices" ) func init() { @@ -55,11 +56,11 @@ func init() { for _, cnt := range treeItemCnt { totalItems += cnt } - numWidth := len(strconv.Itoa(util.Max(treeErrCnt, totalItems))) + numWidth := len(strconv.Itoa(slices.Max(treeErrCnt, totalItems))) table := tabwriter.NewWriter(os.Stdout, 0, 8, 2, ' ', 0) fmt.Fprintf(table, " errors\t% *s\n", numWidth, strconv.Itoa(treeErrCnt)) - for _, typ := range util.SortedMapKeys(treeItemCnt) { + for _, typ := range maps.SortedKeys(treeItemCnt) { fmt.Fprintf(table, " %v items\t% *s\n", typ, numWidth, strconv.Itoa(treeItemCnt[typ])) } fmt.Fprintf(table, " total items\t% *s\n", numWidth, strconv.Itoa(totalItems)) diff --git a/lib/btrfs/btrfsvol/chunk.go b/lib/btrfs/btrfsvol/chunk.go index 2d26964..9c77a49 100644 --- a/lib/btrfs/btrfsvol/chunk.go +++ b/lib/btrfs/btrfsvol/chunk.go @@ -8,7 +8,8 @@ import ( "fmt" "sort" - "git.lukeshu.com/btrfs-progs-ng/lib/util" + "git.lukeshu.com/btrfs-progs-ng/lib/maps" + "git.lukeshu.com/btrfs-progs-ng/lib/slices" ) // logical => []physical @@ -51,8 +52,8 @@ func (a chunkMapping) union(rest ...chunkMapping) (chunkMapping, error) { beg := chunks[0].LAddr end := chunks[0].LAddr.Add(chunks[0].Size) for _, chunk := range chunks { - beg = util.Min(beg, chunk.LAddr) - end = util.Max(end, chunk.LAddr.Add(chunk.Size)) + beg = slices.Min(beg, chunk.LAddr) + end = slices.Max(end, chunk.LAddr.Add(chunk.Size)) } ret := chunkMapping{ LAddr: beg, @@ -78,7 +79,7 @@ func (a chunkMapping) union(rest ...chunkMapping) (chunkMapping, error) { }] = struct{}{} } } - ret.PAddrs = util.MapKeys(paddrs) + ret.PAddrs = maps.Keys(paddrs) sort.Slice(ret.PAddrs, func(i, j int) bool { return ret.PAddrs[i].Cmp(ret.PAddrs[j]) < 0 }) diff --git a/lib/btrfs/btrfsvol/devext.go b/lib/btrfs/btrfsvol/devext.go index 1f6cabe..83ece99 100644 --- a/lib/btrfs/btrfsvol/devext.go +++ b/lib/btrfs/btrfsvol/devext.go @@ -7,7 +7,7 @@ package btrfsvol import ( "fmt" - "git.lukeshu.com/btrfs-progs-ng/lib/util" + "git.lukeshu.com/btrfs-progs-ng/lib/slices" ) // physical => logical @@ -48,8 +48,8 @@ func (a devextMapping) union(rest ...devextMapping) (devextMapping, error) { beg := exts[0].PAddr end := beg.Add(exts[0].Size) for _, ext := range exts { - beg = util.Min(beg, ext.PAddr) - end = util.Max(end, ext.PAddr.Add(ext.Size)) + beg = slices.Min(beg, ext.PAddr) + end = slices.Max(end, ext.PAddr.Add(ext.Size)) } ret := devextMapping{ PAddr: beg, diff --git a/lib/btrfs/io3_btree.go b/lib/btrfs/io3_btree.go index e7c6cc2..f476dae 100644 --- a/lib/btrfs/io3_btree.go +++ b/lib/btrfs/io3_btree.go @@ -15,6 +15,7 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsitem" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol" + "git.lukeshu.com/btrfs-progs-ng/lib/slices" "git.lukeshu.com/btrfs-progs-ng/lib/util" ) @@ -653,7 +654,7 @@ func (fs *FS) TreeSearchAll(treeID ObjID, fn func(Key) int) ([]Item, error) { } ret = append(ret, prevItem) } - util.ReverseSlice(ret) + slices.Reverse(ret) for nextPath, nextNode := middlePath, middleNode; true; { nextPath, nextNode, err = fs.next(nextPath, nextNode) if err != nil { diff --git a/lib/btrfs/io4_fs.go b/lib/btrfs/io4_fs.go index eaa83f7..cae2771 100644 --- a/lib/btrfs/io4_fs.go +++ b/lib/btrfs/io4_fs.go @@ -17,6 +17,8 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsitem" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol" "git.lukeshu.com/btrfs-progs-ng/lib/containers" + "git.lukeshu.com/btrfs-progs-ng/lib/maps" + "git.lukeshu.com/btrfs-progs-ng/lib/slices" "git.lukeshu.com/btrfs-progs-ng/lib/util" ) @@ -246,7 +248,7 @@ func (ret *Dir) populate() { ret.ChildrenByName[string(entry.Name)] = entry } } - for _, name := range util.SortedMapKeys(ret.ChildrenByName) { + for _, name := range maps.SortedKeys(ret.ChildrenByName) { if _, exists := entriesWithIndexes[name]; !exists { ret.Errs = append(ret.Errs, fmt.Errorf("missing by-index direntry for %q", name)) ret.ChildrenByIndex[nextIndex] = ret.ChildrenByName[name] @@ -377,7 +379,7 @@ func (file *File) maybeShortReadAt(dat []byte, off int64) (int, error) { continue } offsetWithinExt := off - extent.OffsetWithinFile - readSize := util.Min(int64(len(dat)), extLen-offsetWithinExt) + readSize := slices.Min(int64(len(dat)), extLen-offsetWithinExt) switch extent.Type { case btrfsitem.FILE_EXTENT_INLINE: return copy(dat, extent.BodyInline[offsetWithinExt:offsetWithinExt+readSize]), nil diff --git a/lib/btrfsprogs/btrfsinspect/mount.go b/lib/btrfsprogs/btrfsinspect/mount.go index c171ed3..c882c65 100644 --- a/lib/btrfsprogs/btrfsinspect/mount.go +++ b/lib/btrfsprogs/btrfsinspect/mount.go @@ -24,8 +24,10 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/btrfs" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsitem" "git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsutil" + "git.lukeshu.com/btrfs-progs-ng/lib/containers" "git.lukeshu.com/btrfs-progs-ng/lib/linux" - "git.lukeshu.com/btrfs-progs-ng/lib/util" + "git.lukeshu.com/btrfs-progs-ng/lib/maps" + "git.lukeshu.com/btrfs-progs-ng/lib/slices" ) func MountRO(ctx context.Context, fs *btrfs.FS, mountpoint string) error { @@ -34,7 +36,7 @@ func MountRO(ctx context.Context, fs *btrfs.FS, mountpoint string) error { return errors.New("no devices") } - deviceName := pvs[util.SortedMapKeys(pvs)[0]].Name() + deviceName := pvs[maps.SortedKeys(pvs)[0]].Name() if abs, err := filepath.Abs(deviceName); err == nil { deviceName = abs } @@ -106,8 +108,8 @@ type subvolume struct { fuseutil.NotImplementedFileSystem lastHandle uint64 - dirHandles util.SyncMap[fuseops.HandleID, *dirState] - fileHandles util.SyncMap[fuseops.HandleID, *fileState] + dirHandles containers.SyncMap[fuseops.HandleID, *dirState] + fileHandles containers.SyncMap[fuseops.HandleID, *fileState] subvolMu sync.Mutex subvols map[string]struct{} @@ -155,7 +157,7 @@ func (sv *subvolume) LoadDir(inode btrfs.ObjID) (val *btrfs.Dir, err error) { val, err = sv.Subvolume.LoadDir(inode) if val != nil { haveSubvolumes := false - for _, index := range util.SortedMapKeys(val.ChildrenByIndex) { + for _, index := range maps.SortedKeys(val.ChildrenByIndex) { entry := val.ChildrenByIndex[index] if entry.Location.ItemType == btrfsitem.ROOT_ITEM_KEY { haveSubvolumes = true @@ -168,7 +170,7 @@ func (sv *subvolume) LoadDir(inode btrfs.ObjID) (val *btrfs.Dir, err error) { return } sv.subvolMu.Lock() - for _, index := range util.SortedMapKeys(val.ChildrenByIndex) { + for _, index := range maps.SortedKeys(val.ChildrenByIndex) { entry := val.ChildrenByIndex[index] if entry.Location.ItemType != btrfsitem.ROOT_ITEM_KEY { continue @@ -317,7 +319,7 @@ func (sv *subvolume) ReadDir(_ context.Context, op *fuseops.ReadDirOp) error { return syscall.EBADF } origOffset := op.Offset - for _, index := range util.SortedMapKeys(state.Dir.ChildrenByIndex) { + for _, index := range maps.SortedKeys(state.Dir.ChildrenByIndex) { if index < uint64(origOffset) { continue } @@ -373,7 +375,7 @@ func (sv *subvolume) ReadFile(_ context.Context, op *fuseops.ReadFileOp) error { var dat []byte if op.Dst != nil { - size := util.Min(int64(len(op.Dst)), op.Size) + size := slices.Min(int64(len(op.Dst)), op.Size) dat = op.Dst[:size] } else { dat = make([]byte, op.Size) diff --git a/lib/btrfsprogs/btrfsinspect/print_tree.go b/lib/btrfsprogs/btrfsinspect/print_tree.go index 5d3b4ef..8aef98a 100644 --- a/lib/btrfsprogs/btrfsinspect/print_tree.go +++ b/lib/btrfsprogs/btrfsinspect/print_tree.go @@ -17,6 +17,7 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsitem" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfssum" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol" + "git.lukeshu.com/btrfs-progs-ng/lib/slices" "git.lukeshu.com/btrfs-progs-ng/lib/util" ) @@ -206,7 +207,7 @@ func printTree(ctx context.Context, out io.Writer, fs *btrfs.FS, treeID btrfs.Ob itemSize := btrfsvol.AddrDelta(len(body.Sums)) * sectorSize fmt.Fprintf(out, "\t\trange start %d end %d length %d", start, start.Add(itemSize), itemSize) - sumsPerLine := util.Max(1, len(btrfssum.CSum{})/body.ChecksumSize/2) + sumsPerLine := slices.Max(1, len(btrfssum.CSum{})/body.ChecksumSize/2) pos := start for i, sum := range body.Sums { diff --git a/lib/btrfsprogs/btrfsinspect/recoverchunks.go b/lib/btrfsprogs/btrfsinspect/recoverchunks.go index 9f97b45..4f01d0a 100644 --- a/lib/btrfsprogs/btrfsinspect/recoverchunks.go +++ b/lib/btrfsprogs/btrfsinspect/recoverchunks.go @@ -14,6 +14,7 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsitem" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol" "git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsutil" + "git.lukeshu.com/btrfs-progs-ng/lib/maps" "git.lukeshu.com/btrfs-progs-ng/lib/util" ) @@ -79,7 +80,7 @@ func (found ScanOneDevResult) AddToLV(ctx context.Context, fs *btrfs.FS, dev *bt // nodes will be subsumed by other things.) // // Sort them so that progress numbers are predictable. - for _, laddr := range util.SortedMapKeys(found.FoundNodes) { + for _, laddr := range maps.SortedKeys(found.FoundNodes) { for _, paddr := range found.FoundNodes[laddr] { if err := fs.LV.AddMapping(btrfsvol.Mapping{ LAddr: laddr, @@ -118,7 +119,7 @@ func (found ScanOneDevResult) AddToLV(ctx context.Context, fs *btrfs.FS, dev *bt Flags: bg.BG.Flags, }] = struct{}{} } - bgsOrdered := util.MapKeys(bgsSet) + bgsOrdered := maps.Keys(bgsSet) sort.Slice(bgsOrdered, func(i, j int) bool { return bgsOrdered[i].LAddr < bgsOrdered[j].LAddr }) diff --git a/lib/btrfsprogs/btrfsutil/scan.go b/lib/btrfsprogs/btrfsutil/scan.go index 02d4124..7189e99 100644 --- a/lib/btrfsprogs/btrfsutil/scan.go +++ b/lib/btrfsprogs/btrfsutil/scan.go @@ -11,6 +11,7 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/btrfs" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol" + "git.lukeshu.com/btrfs-progs-ng/lib/slices" "git.lukeshu.com/btrfs-progs-ng/lib/util" ) @@ -33,7 +34,7 @@ func ScanForNodes(ctx context.Context, dev *btrfs.Device, sb btrfs.Superblock, f if ctx.Err() != nil { return ctx.Err() } - if util.InSlice(pos, btrfs.SuperblockAddrs) { + if slices.Contains(pos, btrfs.SuperblockAddrs) { //fmt.Printf("sector@%v is a superblock\n", pos) continue } diff --git a/lib/containers/rbtree.go b/lib/containers/rbtree.go index 64a679e..0eef553 100644 --- a/lib/containers/rbtree.go +++ b/lib/containers/rbtree.go @@ -8,7 +8,7 @@ import ( "fmt" "reflect" - "git.lukeshu.com/btrfs-progs-ng/lib/util" + "git.lukeshu.com/btrfs-progs-ng/lib/slices" ) type Color bool @@ -192,7 +192,7 @@ func (t *RBTree[K, V]) SearchRange(fn func(V) int) []V { for node := t.Prev(middle); node != nil && fn(node.Value) == 0; node = t.Prev(node) { ret = append(ret, node.Value) } - util.ReverseSlice(ret) + slices.Reverse(ret) for node := t.Next(middle); node != nil && fn(node.Value) == 0; node = t.Next(node) { ret = append(ret, node.Value) } diff --git a/lib/containers/syncmap.go b/lib/containers/syncmap.go new file mode 100644 index 0000000..6c26b85 --- /dev/null +++ b/lib/containers/syncmap.go @@ -0,0 +1,40 @@ +// Copyright (C) 2022 Luke Shumaker +// +// SPDX-License-Identifier: GPL-2.0-or-later + +package containers + +import ( + "sync" +) + +type SyncMap[K comparable, V any] struct { + inner sync.Map +} + +func (m *SyncMap[K, V]) Delete(key K) { m.inner.Delete(key) } +func (m *SyncMap[K, V]) Load(key K) (value V, ok bool) { + _value, ok := m.inner.Load(key) + if ok { + value = _value.(V) + } + return value, ok +} +func (m *SyncMap[K, V]) LoadAndDelete(key K) (value V, loaded bool) { + _value, ok := m.inner.LoadAndDelete(key) + if ok { + value = _value.(V) + } + return value, ok +} +func (m *SyncMap[K, V]) LoadOrStore(key K, value V) (actual V, loaded bool) { + _actual, loaded := m.inner.LoadOrStore(key, value) + actual = _actual.(V) + return actual, loaded +} +func (m *SyncMap[K, V]) Range(f func(key K, value V) bool) { + m.inner.Range(func(key, value any) bool { + return f(key.(K), value.(V)) + }) +} +func (m *SyncMap[K, V]) Store(key K, value V) { m.inner.Store(key, value) } diff --git a/lib/maps/maputil.go b/lib/maps/maputil.go new file mode 100644 index 0000000..aeebe12 --- /dev/null +++ b/lib/maps/maputil.go @@ -0,0 +1,25 @@ +// Copyright (C) 2022 Luke Shumaker +// +// SPDX-License-Identifier: GPL-2.0-or-later + +package maps + +import ( + "golang.org/x/exp/constraints" + + "git.lukeshu.com/btrfs-progs-ng/lib/slices" +) + +func Keys[K comparable, V any](m map[K]V) []K { + ret := make([]K, 0, len(m)) + for k := range m { + ret = append(ret, k) + } + return ret +} + +func SortedKeys[K constraints.Ordered, V any](m map[K]V) []K { + ret := Keys(m) + slices.Sort(ret) + return ret +} diff --git a/lib/slices/sliceutil.go b/lib/slices/sliceutil.go new file mode 100644 index 0000000..392514f --- /dev/null +++ b/lib/slices/sliceutil.go @@ -0,0 +1,69 @@ +// Copyright (C) 2022 Luke Shumaker +// +// SPDX-License-Identifier: GPL-2.0-or-later + +package slices + +import ( + "sort" + + "golang.org/x/exp/constraints" +) + +func Contains[T comparable](needle T, haystack []T) bool { + for _, straw := range haystack { + if needle == straw { + return true + } + } + return false +} + +func RemoveAll[T comparable](haystack []T, needle T) []T { + for i, straw := range haystack { + if needle == straw { + return append( + haystack[:i], + RemoveAll(haystack[i+1:], needle)...) + } + } + return haystack +} + +func RemoveAllFunc[T any](haystack []T, f func(T) bool) []T { + for i, straw := range haystack { + if f(straw) { + return append( + haystack[:i], + RemoveAllFunc(haystack[i+1:], f)...) + } + } + return haystack +} + +func Reverse[T any](slice []T) { + for i := 0; i < len(slice)/2; i++ { + j := (len(slice) - 1) - i + slice[i], slice[j] = slice[j], slice[i] + } +} + +func Max[T constraints.Ordered](a, b T) T { + if a > b { + return a + } + return b +} + +func Min[T constraints.Ordered](a, b T) T { + if a < b { + return a + } + return b +} + +func Sort[T constraints.Ordered](slice []T) { + sort.Slice(slice, func(i, j int) bool { + return slice[i] < slice[j] + }) +} diff --git a/lib/util/maputil.go b/lib/util/maputil.go deleted file mode 100644 index d7f1727..0000000 --- a/lib/util/maputil.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2022 Luke Shumaker -// -// SPDX-License-Identifier: GPL-2.0-or-later - -package util - -import ( - "golang.org/x/exp/constraints" -) - -func MapKeys[K comparable, V any](m map[K]V) []K { - ret := make([]K, 0, len(m)) - for k := range m { - ret = append(ret, k) - } - return ret -} - -func SortedMapKeys[K constraints.Ordered, V any](m map[K]V) []K { - ret := MapKeys(m) - SortSlice(ret) - return ret -} diff --git a/lib/util/sliceutil.go b/lib/util/sliceutil.go deleted file mode 100644 index 6e0ce76..0000000 --- a/lib/util/sliceutil.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (C) 2022 Luke Shumaker -// -// SPDX-License-Identifier: GPL-2.0-or-later - -package util - -import ( - "sort" - - "golang.org/x/exp/constraints" -) - -func InSlice[T comparable](needle T, haystack []T) bool { - for _, straw := range haystack { - if needle == straw { - return true - } - } - return false -} - -func RemoveAllFromSlice[T comparable](haystack []T, needle T) []T { - for i, straw := range haystack { - if needle == straw { - return append( - haystack[:i], - RemoveAllFromSlice(haystack[i+1:], needle)...) - } - } - return haystack -} - -func RemoveAllFromSliceFunc[T any](haystack []T, f func(T) bool) []T { - for i, straw := range haystack { - if f(straw) { - return append( - haystack[:i], - RemoveAllFromSliceFunc(haystack[i+1:], f)...) - } - } - return haystack -} - -func ReverseSlice[T any](slice []T) { - for i := 0; i < len(slice)/2; i++ { - j := (len(slice) - 1) - i - slice[i], slice[j] = slice[j], slice[i] - } -} - -func Max[T constraints.Ordered](a, b T) T { - if a > b { - return a - } - return b -} - -func Min[T constraints.Ordered](a, b T) T { - if a < b { - return a - } - return b -} - -func SortSlice[T constraints.Ordered](slice []T) { - sort.Slice(slice, func(i, j int) bool { - return slice[i] < slice[j] - }) -} diff --git a/lib/util/syncmap.go b/lib/util/syncmap.go deleted file mode 100644 index a281f2d..0000000 --- a/lib/util/syncmap.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2022 Luke Shumaker -// -// SPDX-License-Identifier: GPL-2.0-or-later - -package util - -import ( - "sync" -) - -type SyncMap[K comparable, V any] struct { - inner sync.Map -} - -func (m *SyncMap[K, V]) Delete(key K) { m.inner.Delete(key) } -func (m *SyncMap[K, V]) Load(key K) (value V, ok bool) { - _value, ok := m.inner.Load(key) - if ok { - value = _value.(V) - } - return value, ok -} -func (m *SyncMap[K, V]) LoadAndDelete(key K) (value V, loaded bool) { - _value, ok := m.inner.LoadAndDelete(key) - if ok { - value = _value.(V) - } - return value, ok -} -func (m *SyncMap[K, V]) LoadOrStore(key K, value V) (actual V, loaded bool) { - _actual, loaded := m.inner.LoadOrStore(key, value) - actual = _actual.(V) - return actual, loaded -} -func (m *SyncMap[K, V]) Range(f func(key K, value V) bool) { - m.inner.Range(func(key, value any) bool { - return f(key.(K), value.(V)) - }) -} -func (m *SyncMap[K, V]) Store(key K, value V) { m.inner.Store(key, value) } -- cgit v1.2.3-54-g00ecf