Skip to content

Commit

Permalink
feat(队列): 增加默认队列
Browse files Browse the repository at this point in the history
  • Loading branch information
storezhang committed Nov 28, 2024
1 parent 4f86781 commit 3020e4e
Show file tree
Hide file tree
Showing 14 changed files with 126 additions and 43 deletions.
1 change: 1 addition & 0 deletions collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ import (
"github.com/goexl/collection/internal/kernel"
)

// Collection 集合
type Collection = kernel.Collection
8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
module github.com/goexl/collection

go 1.23

require github.com/stretchr/testify v1.10.0

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
4 changes: 3 additions & 1 deletion internal/kernel/collection.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package kernel

// Collection 集合
type Collection interface {
// Size 大小
Size() int

// Empty 是否为空
Empty() bool
}
3 changes: 1 addition & 2 deletions internal/kernel/queue.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package kernel

// Queue 队列
type Queue[T any] interface {
Collection

// Enqueue 入队
Enqueue(T, ...T)

// Dequeue 出队
Dequeue() []T
Dequeue() T
}
1 change: 1 addition & 0 deletions queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ import (
"github.com/goexl/collection/internal/kernel"
)

// Queue 队列
type Queue[T any] = kernel.Queue[T]
22 changes: 18 additions & 4 deletions queue/internal/builder/queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package builder

import (
"github.com/goexl/collection/internal/kernel"
"github.com/goexl/collection/queue/internal/core"
"github.com/goexl/collection/queue/internal/param"
)

type Queue[T any] struct {
params *param.Queue
queue kernel.Queue[T]
}

func NewQueue[T any]() *Queue[T] {
Expand All @@ -15,13 +17,25 @@ func NewQueue[T any]() *Queue[T] {
}
}

func (b *Queue[T]) Capacity(capacity int) (blocking *Queue[T]) {
b.params.Capacity = capacity
blocking = b
func (q *Queue[T]) Blocking() (queue *Queue[T]) {
q.queue = core.NewBlocking[T](q.params)
queue = q

return
}

func (b *Queue[T]) Build() *kernel.Queue[T] {
func (q *Queue[T]) Capacity(capacity int) (queue *Queue[T]) {
q.params.Capacity = capacity
queue = q

return
}

func (q *Queue[T]) Build() (queue kernel.Queue[T]) {
if nil == q.queue {
q.queue = core.NewDefault[T](q.params)
}
queue = q.queue

return
}
31 changes: 21 additions & 10 deletions queue/internal/blocking.go → queue/internal/core/blocking.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package internal
package core

import (
"container/list"
"sync"

"github.com/goexl/collection/internal/kernel"
Expand All @@ -10,7 +11,7 @@ import (
var _ kernel.Queue[int] = (*Blocking[int])(nil)

type Blocking[T any] struct {
data []T
items *list.List
mutex *sync.Mutex
cond *sync.Cond

Expand All @@ -19,7 +20,7 @@ type Blocking[T any] struct {

func NewBlocking[T any](params *param.Queue) (blocking *Blocking[T]) {
blocking = new(Blocking[T])
blocking.data = make([]T, 0, params.Capacity)
blocking.items = list.New()
blocking.mutex = new(sync.Mutex)
blocking.cond = sync.NewCond(blocking.mutex)

Expand All @@ -33,27 +34,37 @@ func (b *Blocking[T]) Enqueue(required T, optionals ...T) {
defer b.mutex.Unlock()

items := append([]T{required}, optionals...)
for len(b.data)+len(items) > b.params.Capacity {
for b.items.Len()+len(items) > b.params.Capacity {
b.cond.Wait()
}
b.data = append(b.data, items...)
for _, item := range items {
b.items.PushBack(item)
}
b.cond.Broadcast()
}

func (b *Blocking[T]) Dequeue() (items []T) {
func (b *Blocking[T]) Dequeue() (item T) {
b.mutex.Lock()
defer b.mutex.Unlock()

for len(b.data) == 0 {
for 0 == b.items.Len() {
b.cond.Wait()
}
items = b.data[:]
b.data = make([]T, 0, b.params.Capacity)

if 0 != b.items.Len() {
element := b.items.Front()
b.items.Remove(element)
item = element.Value.(T)
}
b.cond.Broadcast()

return
}

func (b *Blocking[T]) Size() int {
return len(b.data)
return b.items.Len()
}

func (b *Blocking[T]) Empty() bool {
return 0 == b.items.Len()
}
53 changes: 53 additions & 0 deletions queue/internal/core/default.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package core

import (
"container/list"

"github.com/goexl/collection/internal/kernel"
"github.com/goexl/collection/queue/internal/param"
)

var _ kernel.Queue[int] = (*Default[int])(nil)

type Default[T any] struct {
items *list.List
params *param.Queue
}

func NewDefault[T any](params *param.Queue) *Default[T] {
return &Default[T]{
items: list.New(),
params: params,
}
}

func (q *Default[T]) Enqueue(required T, optionals ...T) {
q.enqueue(required)
for _, optional := range optionals {
q.enqueue(optional)
}
}

func (q *Default[T]) Dequeue() (item T) {
if 0 != q.items.Len() {
element := q.items.Front()
q.items.Remove(element)
item = element.Value.(T)
}

return
}

func (q *Default[T]) Empty() bool {
return 0 == q.items.Len()
}

func (q *Default[T]) Size() int {
return q.items.Len()
}

func (q *Default[T]) enqueue(item T) {
for q.params.Capacity > q.items.Len() {
q.items.PushBack(item)
}
}
File renamed without changes.
File renamed without changes.
6 changes: 5 additions & 1 deletion queue/internal/param/queue.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package param

import (
"math"
)

type Queue struct {
Capacity int
}

func NewQueue() *Queue {
return &Queue{
Capacity: 16,
Capacity: math.MaxInt,
}
}
4 changes: 2 additions & 2 deletions queue/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ import (
"github.com/goexl/collection/queue/internal/builder"
)

func New(T any) *builder.Queue[T] {

func New[T any]() *builder.Queue[T] {
return builder.NewQueue[T]()
}
13 changes: 13 additions & 0 deletions queue/new_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package queue_test

import (
"testing"

"github.com/goexl/collection/queue"
"github.com/stretchr/testify/require"
)

func TestNew(t *testing.T) {
_queue := queue.New[int]().Build()
require.NotNil(t, _queue, "默认队列创建出错")
}
23 changes: 0 additions & 23 deletions queue/priority.go

This file was deleted.

0 comments on commit 3020e4e

Please sign in to comment.