From 9e87554ae1b53e7c199f925bce92b911766e96e5 Mon Sep 17 00:00:00 2001 From: thanhpp Date: Fri, 8 Mar 2024 13:37:13 +0700 Subject: [PATCH] =?UTF-8?q?feat(prod):=20=E2=9C=A8=20pkg:=20hashset?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: thanhpp --- pkg/hashset/hashset.go | 35 +++++++++++++++++++++ pkg/hashset/hashset_sync.go | 62 +++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 pkg/hashset/hashset.go create mode 100644 pkg/hashset/hashset_sync.go diff --git a/pkg/hashset/hashset.go b/pkg/hashset/hashset.go new file mode 100644 index 0000000..e52a05e --- /dev/null +++ b/pkg/hashset/hashset.go @@ -0,0 +1,35 @@ +package hashset + +import "golang.org/x/exp/maps" + +type HashSet[K comparable] struct { + m map[K]struct{} +} + +func New[K comparable]() *HashSet[K] { + return &HashSet[K]{ + m: map[K]struct{}{}, + } +} + +func (h *HashSet[K]) Contains(k K) bool { + _, ok := h.m[k] + + return ok +} + +func (h *HashSet[K]) Add(k K) { + h.m[k] = struct{}{} +} + +func (h *HashSet[K]) Remove(k K) { + delete(h.m, k) +} + +func (h *HashSet[K]) Size() int { + return len(h.m) +} + +func (h *HashSet[K]) Clear() { + maps.Clear(h.m) +} diff --git a/pkg/hashset/hashset_sync.go b/pkg/hashset/hashset_sync.go new file mode 100644 index 0000000..374deae --- /dev/null +++ b/pkg/hashset/hashset_sync.go @@ -0,0 +1,62 @@ +package hashset + +import "sync" + +type SyncHashSet[K comparable] struct { + rw sync.RWMutex + s *HashSet[K] +} + +func NewSync[K comparable]() *SyncHashSet[K] { + return &SyncHashSet[K]{ + rw: sync.RWMutex{}, + s: New[K](), + } +} + +func (sh *SyncHashSet[K]) Contains(k K) bool { + sh.rw.RLock() + defer sh.rw.RUnlock() + + return sh.s.Contains(k) +} + +func (sh *SyncHashSet[K]) ContainsOrAdd(k K) (isContains bool) { + sh.rw.Lock() + defer sh.rw.Unlock() + if sh.s.Contains(k) { + return true + } + + sh.s.Add(k) + + return false +} + +func (sh *SyncHashSet[K]) Add(k K) { + sh.rw.Lock() + defer sh.rw.Unlock() + + sh.s.Add(k) +} + +func (sh *SyncHashSet[K]) Remove(k K) { + sh.rw.Lock() + defer sh.rw.Unlock() + + sh.s.Remove(k) +} + +func (sh *SyncHashSet[K]) Size() int { + sh.rw.RLock() + defer sh.rw.RUnlock() + + return sh.s.Size() +} + +func (sh *SyncHashSet[K]) Clear() { + sh.rw.Lock() + defer sh.rw.Unlock() + + sh.s.Clear() +}