Create new type and remove un-used code
Create Release & Upload Assets / Upload Assets To Gitea w/ goreleaser (push) Failing after 11s
Create Release & Upload Assets / Upload Assets To Gitea w/ goreleaser (push) Failing after 11s
This commit is contained in:
+19
@@ -0,0 +1,19 @@
|
||||
Copyright (C) 2012 Yasushi Saito, 2013 Foize B.V.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
// Created by Yaz Saito on 06/15/12.
|
||||
// Modified by Geert-Johan Riemer, Foize B.V.
|
||||
|
||||
// TODO:
|
||||
// - travis CI
|
||||
// - maybe add method (*Queue).Peek()
|
||||
|
||||
package fifo
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
const chunkSize = 64
|
||||
|
||||
// chunks are used to make a queue auto resizeable.
|
||||
type chunk struct {
|
||||
items [chunkSize]interface{} // list of queue'ed items
|
||||
first, last int // positions for the first and list item in this chunk
|
||||
next *chunk // pointer to the next chunk (if any)
|
||||
}
|
||||
|
||||
// fifo queue
|
||||
type Queue struct {
|
||||
head, tail *chunk // chunk head and tail
|
||||
count int // total amount of items in the queue
|
||||
lock sync.Mutex // synchronisation lock
|
||||
}
|
||||
|
||||
// NewQueue creates a new and empty *fifo.Queue
|
||||
func NewQueue() (q *Queue) {
|
||||
initChunk := new(chunk)
|
||||
q = &Queue{
|
||||
head: initChunk,
|
||||
tail: initChunk,
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
||||
// Return the number of items in the queue
|
||||
func (q *Queue) Len() (length int) {
|
||||
// locking to make Queue thread-safe
|
||||
q.lock.Lock()
|
||||
defer q.lock.Unlock()
|
||||
|
||||
// copy q.count and return length
|
||||
length = q.count
|
||||
return length
|
||||
}
|
||||
|
||||
// Add an item to the end of the queue
|
||||
func (q *Queue) Add(item interface{}) {
|
||||
// locking to make Queue thread-safe
|
||||
q.lock.Lock()
|
||||
defer q.lock.Unlock()
|
||||
|
||||
// check if item is valid
|
||||
if item == nil {
|
||||
panic("can not add nil item to fifo queue")
|
||||
}
|
||||
|
||||
// if the tail chunk is full, create a new one and add it to the queue.
|
||||
if q.tail.last >= chunkSize {
|
||||
q.tail.next = new(chunk)
|
||||
q.tail = q.tail.next
|
||||
}
|
||||
|
||||
// add item to the tail chunk at the last position
|
||||
q.tail.items[q.tail.last] = item
|
||||
q.tail.last++
|
||||
q.count++
|
||||
}
|
||||
|
||||
// Remove the item at the head of the queue and return it.
|
||||
// Returns nil when there are no items left in queue.
|
||||
func (q *Queue) Next() (item interface{}) {
|
||||
// locking to make Queue thread-safe
|
||||
q.lock.Lock()
|
||||
defer q.lock.Unlock()
|
||||
|
||||
// Return nil if there are no items to return
|
||||
if q.count == 0 {
|
||||
return nil
|
||||
}
|
||||
// FIXME: why would this check be required?
|
||||
if q.head.first >= q.head.last {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get item from queue
|
||||
item = q.head.items[q.head.first]
|
||||
|
||||
// increment first position and decrement queue item count
|
||||
q.head.first++
|
||||
q.count--
|
||||
|
||||
if q.head.first >= q.head.last {
|
||||
// we're at the end of this chunk and we should do some maintainance
|
||||
// if there are no follow up chunks then reset the current one so it can be used again.
|
||||
if q.count == 0 {
|
||||
q.head.first = 0
|
||||
q.head.last = 0
|
||||
q.head.next = nil
|
||||
} else {
|
||||
// set queue's head chunk to the next chunk
|
||||
// old head will fall out of scope and be GC-ed
|
||||
q.head = q.head.next
|
||||
}
|
||||
}
|
||||
|
||||
// return the retrieved item
|
||||
return item
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
## go.fifo
|
||||
|
||||
### Description
|
||||
go.fifo provides a simple FIFO thread-safe queue.
|
||||
*fifo.Queue supports pushing an item at the end with Add(), and popping an item from the front with Next().
|
||||
There is no intermediate type for the stored data. Data is directly added and retrieved as type interface{}
|
||||
The queue itself is implemented as a single-linked list of chunks containing max 64 items each.
|
||||
|
||||
### Installation
|
||||
`go get github.com/foize/go.fifo`
|
||||
|
||||
### Usage
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/foize/go.fifo"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// create a new queue
|
||||
numbers := fifo.NewQueue()
|
||||
|
||||
// add items to the queue
|
||||
numbers.Add(42)
|
||||
numbers.Add(123)
|
||||
numbers.Add(456)
|
||||
|
||||
// retrieve items from the queue
|
||||
fmt.Println(numbers.Next()) // 42
|
||||
fmt.Println(numbers.Next()) // 123
|
||||
fmt.Println(numbers.Next()) // 456
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/foize/go.fifo"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type thing struct {
|
||||
Text string
|
||||
Number int
|
||||
}
|
||||
|
||||
func main() {
|
||||
// create a new queue
|
||||
things := fifo.NewQueue()
|
||||
|
||||
// add items to the queue
|
||||
things.Add(&thing{
|
||||
Text: "one thing",
|
||||
Number: 1,
|
||||
})
|
||||
things.Add(&thing {
|
||||
Text: "another thing",
|
||||
Number: 2,
|
||||
})
|
||||
|
||||
// retrieve items from the queue
|
||||
for {
|
||||
// get a new item from the things queue
|
||||
item := things.Next();
|
||||
|
||||
// check if there was an item
|
||||
if item == nil {
|
||||
fmt.Println("queue is empty")
|
||||
return
|
||||
}
|
||||
|
||||
// assert the type for the item
|
||||
someThing := item.(*thing)
|
||||
|
||||
// print the fields
|
||||
fmt.Println(someThing.Text)
|
||||
fmt.Printf("with number: %d\n", someThing.Number)
|
||||
}
|
||||
}
|
||||
|
||||
/* output: */
|
||||
// one thing
|
||||
// with number: 1
|
||||
// another thing
|
||||
// with number: 2
|
||||
// queue is empty
|
||||
```
|
||||
|
||||
### Documentation
|
||||
Documentation can be found at [godoc.org/github.com/foize/go.fifo](http://godoc.org/github.com/foize/go.fifo).
|
||||
For more detailed documentation, read the source.
|
||||
|
||||
### History
|
||||
This package is based on github.com/yasushi-saito/fifo_queue
|
||||
There are several differences:
|
||||
- renamed package to `fifo` to make usage simpler
|
||||
- removed intermediate type `Item` and now directly using interface{} instead.
|
||||
- renamed (*Queue).PushBack() to (*Queue).Add()
|
||||
- renamed (*Queue).PopFront() to (*Queue).Next()
|
||||
- Next() will not panic on empty queue, will just return nil interface{}
|
||||
- Add() does not accept nil interface{} and will panic when trying to add nil interface{}.
|
||||
- Made fifo.Queue thread/goroutine-safe (sync.Mutex)
|
||||
- Added a lot of comments
|
||||
- renamed internal variable/field names
|
||||
Reference in New Issue
Block a user