diff --git a/g/container/gqueue/gqueue.go b/g/container/gqueue/gqueue.go new file mode 100644 index 000000000..0f04b22a6 --- /dev/null +++ b/g/container/gqueue/gqueue.go @@ -0,0 +1,85 @@ +// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +// 动态大小的安全队列(dynamic channel). +package gqueue + +import ( + "math" + "sync" + "container/list" +) + +type Queue struct { + mu sync.RWMutex + list *list.List + events chan struct{} +} + +func NewQueue() *Queue { + return &Queue { + list : list.New(), + events : make(chan struct{}, math.MaxInt64), + } +} + +// 将数据压入队列, 队尾 +func (q *Queue) PushBack(v interface{}) { + q.mu.Lock() + q.list.PushBack(v) + q.mu.Unlock() + q.events <- struct{}{} +} + +// 将数据压入队列, 队头 +func (q *Queue) PushFront(v interface{}) { + q.mu.Lock() + q.list.PushFront(v) + q.mu.Unlock() + q.events <- struct{}{} +} + +// 从队头先进先出地从队列取出一项数据,当没有数据可获取时,阻塞等待 +// 第二个返回值表示队列是否关闭 +func (q *Queue) PopFront() (interface{}, bool) { + select { + case <- q.events: + q.mu.Lock() + if elem := q.list.Front(); elem != nil { + item := q.list.Remove(elem) + q.mu.Unlock() + return item, true + } + q.mu.Unlock() + } + return nil, false +} + +// 从队尾先进先出地从队列取出一项数据,当没有数据可获取时,阻塞等待 +// 第二个返回值表示队列是否关闭 +func (q *Queue) PopBack() (interface{}, bool) { + select { + case <- q.events: + q.mu.Lock() + if elem := q.list.Front(); elem != nil { + item := q.list.Remove(elem) + q.mu.Unlock() + return item, true + } + q.mu.Unlock() + } + return nil, false +} + +// 关闭队列(通知所有通过Pop阻塞的协程退出) +func (q *Queue) Close() { + q.events <- struct{}{} +} + +// 获取当前队列大小 +func (q *Queue) Size() int { + return len(q.events) +} \ No newline at end of file diff --git a/g/container/gqueue/int_queue.go b/g/container/gqueue/int_queue.go deleted file mode 100644 index e6fca5e3b..000000000 --- a/g/container/gqueue/int_queue.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved. -// -// This Source Code Form is subject to the terms of the MIT License. -// If a copy of the MIT was not distributed with this file, -// You can obtain one at https://gitee.com/johng/gf. - -package gqueue - -import ( - "math" - "sync" - "container/list" -) - -type IntQueue struct { - mu sync.RWMutex - list *list.List - events chan struct{} -} - -func NewIntQueue() *IntQueue { - return &IntQueue{ - list : list.New(), - events : make(chan struct{}, math.MaxInt64), - } -} - -// 将数据压入队列 -func (q *IntQueue) Push(v int) { - q.mu.Lock() - q.list.PushBack(v) - q.mu.Unlock() - q.events <- struct{}{} -} - -// 先进先出地从队列取出一项数据,当没有数据可获取时,阻塞等待 -func (q *IntQueue) Pop() int { - select { - case <- q.events: - q.mu.Lock() - if elem := q.list.Front(); elem != nil { - item := q.list.Remove(elem).(int) - q.mu.Unlock() - return item - } - q.mu.Unlock() - } - return 0 -} - -// 关闭队列(通知所有通过Pop阻塞的协程退出) -func (q *IntQueue) Close() { - q.events <- struct{}{} -} - -// 获取当前队列大小 -func (q *IntQueue) Size() int { - return len(q.events) -} \ No newline at end of file diff --git a/g/container/gqueue/interface_queue.go b/g/container/gqueue/interface_queue.go deleted file mode 100644 index a357ea9cc..000000000 --- a/g/container/gqueue/interface_queue.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved. -// -// This Source Code Form is subject to the terms of the MIT License. -// If a copy of the MIT was not distributed with this file, -// You can obtain one at https://gitee.com/johng/gf. - -// 动态大小的安全队列(dynamic channel). -package gqueue - -import ( - "math" - "sync" - "container/list" -) - -type InterfaceQueue struct { - mu sync.RWMutex - list *list.List - events chan struct{} -} - -func NewInterfaceQueue() *InterfaceQueue { - return &InterfaceQueue { - list : list.New(), - events : make(chan struct{}, math.MaxInt64), - } -} - -// 将数据压入队列 -func (q *InterfaceQueue) Push(v interface{}) { - q.mu.Lock() - q.list.PushBack(v) - q.mu.Unlock() - q.events <- struct{}{} -} - -// 先进先出地从队列取出一项数据,当没有数据可获取时,阻塞等待 -func (q *InterfaceQueue) Pop() interface{} { - select { - case <- q.events: - q.mu.Lock() - if elem := q.list.Front(); elem != nil { - item := q.list.Remove(elem) - q.mu.Unlock() - return item - } - q.mu.Unlock() - } - return nil -} - -// 关闭队列(通知所有通过Pop阻塞的协程退出) -func (q *InterfaceQueue) Close() { - q.events <- struct{}{} -} - -// 获取当前队列大小 -func (q *InterfaceQueue) Size() int { - return len(q.events) -} \ No newline at end of file diff --git a/g/container/gqueue/string_queue.go b/g/container/gqueue/string_queue.go deleted file mode 100644 index 03bc61211..000000000 --- a/g/container/gqueue/string_queue.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved. -// -// This Source Code Form is subject to the terms of the MIT License. -// If a copy of the MIT was not distributed with this file, -// You can obtain one at https://gitee.com/johng/gf. - -package gqueue - -import ( - "math" - "sync" - "container/list" -) - -type StringQueue struct { - mu sync.RWMutex - list *list.List - events chan struct{} -} - -func NewStringQueue() *StringQueue { - return &StringQueue{ - list : list.New(), - events : make(chan struct{}, math.MaxInt64), - } -} - -// 将数据压入队列 -func (q *StringQueue) Push(v string) { - q.mu.Lock() - q.list.PushBack(v) - q.mu.Unlock() - q.events <- struct{}{} -} - -// 先进先出地从队列取出一项数据,当没有数据可获取时,阻塞等待 -func (q *StringQueue) Pop() string { - select { - case <- q.events: - q.mu.Lock() - if elem := q.list.Front(); elem != nil { - item := q.list.Remove(elem).(string) - q.mu.Unlock() - return item - } - q.mu.Unlock() - } - return "" -} - -// 关闭队列(通知所有通过Pop阻塞的协程退出) -func (q *StringQueue) Close() { - q.events <- struct{}{} -} - -// 获取当前队列大小 -func (q *StringQueue) Size() int { - return len(q.events) -} \ No newline at end of file diff --git a/g/container/gqueue/uint_queue.go b/g/container/gqueue/uint_queue.go deleted file mode 100644 index 4b3d31968..000000000 --- a/g/container/gqueue/uint_queue.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved. -// -// This Source Code Form is subject to the terms of the MIT License. -// If a copy of the MIT was not distributed with this file, -// You can obtain one at https://gitee.com/johng/gf. - -package gqueue - -import ( - "math" - "sync" - "container/list" -) - -type UintQueue struct { - mu sync.RWMutex - list *list.List - events chan struct{} -} - -func NewUintQueue() *UintQueue { - return &UintQueue{ - list : list.New(), - events : make(chan struct{}, math.MaxInt64), - } -} - -// 将数据压入队列 -func (q *UintQueue) Push(v uint) { - q.mu.Lock() - q.list.PushBack(v) - q.mu.Unlock() - q.events <- struct{}{} -} - -// 先进先出地从队列取出一项数据,当没有数据可获取时,阻塞等待 -func (q *UintQueue) Pop() uint { - select { - case <- q.events: - q.mu.Lock() - if elem := q.list.Front(); elem != nil { - item := q.list.Remove(elem).(uint) - q.mu.Unlock() - return item - } - q.mu.Unlock() - } - return 0 -} - -// 关闭队列(通知所有通过Pop阻塞的协程退出) -func (q *UintQueue) Close() { - q.events <- struct{}{} -} - -// 获取当前队列大小 -func (q *UintQueue) Size() int { - return len(q.events) -} \ No newline at end of file