diff --git a/sorted_queue/coverage.out b/sorted_queue/coverage.out new file mode 100644 index 0000000..5f02b11 --- /dev/null +++ b/sorted_queue/coverage.out @@ -0,0 +1 @@ +mode: set diff --git a/sorted_queue/go.mod b/sorted_queue/go.mod new file mode 100644 index 0000000..b1b2fca --- /dev/null +++ b/sorted_queue/go.mod @@ -0,0 +1,3 @@ +module github.com/cubixle/playground/sorted_queue + +go 1.22.0 diff --git a/sorted_queue/main.go b/sorted_queue/main.go new file mode 100644 index 0000000..02c41ae --- /dev/null +++ b/sorted_queue/main.go @@ -0,0 +1,69 @@ +package queue + +import "sync" + +type Item struct { + ID string + Data string + Priority int +} + +type queue struct { + m map[string]struct{} + queue []*Item + mu *sync.Mutex +} + +func NewQueue() *queue { + return &queue{ + m: map[string]struct{}{}, + mu: &sync.Mutex{}, + queue: []*Item{}, + } +} + +// put on the queue with no duplicates +func (q *queue) Put(r *Item) bool { + q.mu.Lock() + defer q.mu.Unlock() + + _, ok := q.m[r.ID] + if ok { + return false + } + + q.m[r.ID] = struct{}{} + + q.queue = append(q.queue, r) + + if len(q.queue) > 0 { + // sort the queue + for i := len(q.queue); i > 0; i-- { + if q.queue[i].Priority > q.queue[i-1].Priority { + q.queue[i] = q.queue[i-1] + q.queue[i-1] = q.queue[i] + } + } + } + + return true +} + +func (q *queue) GetNext() *Item { + q.mu.Lock() + defer q.mu.Unlock() + + if len(q.m) == 0 { + return nil + } + + r := q.queue[0] + + // delete the id from the map + delete(q.m, r.ID) + + // delete from the front of the list + q.queue = q.queue[1:] + + return r +} diff --git a/sorted_queue/main_test.go b/sorted_queue/main_test.go new file mode 100644 index 0000000..ec0dce1 --- /dev/null +++ b/sorted_queue/main_test.go @@ -0,0 +1,32 @@ +package queue_test + +import ( + "testing" + + queue "github.com/cubixle/playground/sorted_queue" +) + +func TestQueue(t *testing.T) { + q := queue.NewQueue() + q.Put(&queue.Item{ID: "aaa", Priority: 6}) + q.Put(&queue.Item{ID: "bbb", Priority: 7}) + q.Put(&queue.Item{ID: "ccc", Priority: 2}) + q.Put(&queue.Item{ID: "ddd", Priority: 1}) + + v := q.GetNext() + if v == nil { + t.Fatal("didn't get a item") + } + if v.ID != "bbb" { + t.Fatal("id wasn't what we expected") + } + if v.ID != "aaa" { + t.Fatal("id wasn't what we expected") + } + if v.ID != "ccc" { + t.Fatal("id wasn't what we expected") + } + if v.ID != "ddd" { + t.Fatal("id wasn't what we expected") + } +}