laney

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2022 License: MIT Imports: 3 Imported by: 0

README

laney

Fork of https://github.com/oleiade/lane to make it generic and update to latest Go

Laney package provides queue, priority queue, stack and deque data structures implementations. Its was designed with simplicity, performance, and concurrent usage in mind.

Priority Queue

Pqueue is a heap priority queue data structure implementation. It can be whether max or min ordered, is synchronized and is safe for concurrent operations. It performs insertion and max/min removal in O(log N) time.

Priority Queue Example
 // Let's create a new max ordered priority queue
 var priorityQueue = NewPQueue[string](MINPQ)

 // And push some prioritized content into it
 priorityQueue.Push("easy as", 3)
 priorityQueue.Push("123", 2)
 priorityQueue.Push("do re mi", 4)
 priorityQueue.Push("abc", 1)

 // Now let's take a look at the min element in
 // the priority queue
 headValue, headPriority := priorityQueue.Head()
 fmt.Println(headValue)    // "abc"
 fmt.Println(headPriority) // 1

 // Okay the song order seems to be preserved, let's
 // roll
 var jacksonFive = make([]string, priorityQueue.Size())

 for i := 0; i < len(jacksonFive); i++ {
  value, _ := priorityQueue.Pop()

  jacksonFive[i] = value
 }

 fmt.Println(strings.Join(jacksonFive, " "))

Deque

Deque is a head-tail linked list data structure implementation. It is based on a doubly-linked list container, so that every operations time complexity is O(1). All operations over an instiated Deque are synchronized and safe for concurrent usage.

Deques can optionally be created with a limited capacity, whereby the return value of the Append and Prepend return false if the Deque was full and the item was not added.

Deque Example
 // Let's create a new deque data structure
 deque := NewDeque[string]()

 // And push some content into it using the Append
 // and Prepend methods
 deque.Append("easy as")
 deque.Prepend("123")
 deque.Append("do re mi")
 deque.Prepend("abc")

 // Now let's take a look at what are the first and
 // last element stored in the Deque
 firstValue := deque.First()
 lastValue := deque.Last()
 fmt.Println(firstValue) // "abc"
 fmt.Println(lastValue)  // 1

 // Okay now let's play with the Pop and Shift
 // methods to bring the song words together
 jacksonFive := make([]string, deque.Size())

 for i := 0; i < len(jacksonFive); i++ {
  value := deque.Shift()
  jacksonFive[i] = value
 }

 // abc 123 easy as do re mi
 fmt.Println(strings.Join(jacksonFive, " "))
 // Let's create a new musical quartet
 quartet := NewCappedDeque[string](4)

 // List of young hopeful musicians
 musicians := []string{"John", "Paul", "George", "Ringo", "Stuart"}

 // Add as many of them to the band as we can.
 for _, name := range musicians {
  if quartet.Append(name) {
   fmt.Printf("%s is in the band!\n", name)
  } else {
   fmt.Printf("Sorry - %s is not in the band.\n", name)
  }
 }

 // Assemble our new rock sensation
 beatles := make([]string, quartet.Size())

 for i := 0; i < len(beatles); i++ {
  beatles[i] = quartet.Shift()
 }

 fmt.Println("The Beatles are:", strings.Join(beatles, ", "))

Queue

Queue is a FIFO ( First in first out ) data structure implementation. It is based on a deque container and focuses its API on core functionalities: Enqueue, Dequeue, Head, Size, Empty. Every operations time complexity is O(1). As it is implemented using a Deque container, every operations over an instiated Queue are synchronized and safe for concurrent usage.

Queue Example
    import (
        "fmt"
        "github.com/oleiade/laney"
        "sync"
    )

    func worker(item string, wg *sync.WaitGroup) {
        fmt.Println(item)
        wg.Done()
    }


    func main() {

        queue := laney.NewQueue[string]()
        queue.Enqueue("grumpyClient")
        queue.Enqueue("happyClient")
        queue.Enqueue("ecstaticClient")

        var wg sync.WaitGroup

        // Let's handle the clients asynchronously
        for queue.Head() != nil {
            item := queue.Dequeue()

            wg.Add(1)
            go worker(item, &wg)
        }

        // Wait until everything is printed
        wg.Wait()
    }

Stack

Stack is a LIFO ( Last in first out ) data structure implementation. It is based on a deque container and focuses its API on core functionalities: Push, Pop, Head, Size, Empty. Every operations time complexity is O(1). As it is implemented using a Deque container, every operations over an instiated Stack are synchronized and safe for concurrent usage.

Stack Example
 // Create a new stack and put some plates over it
 stack := NewStack[string]()

 // Let's put some plates on the stack
 stack.Push("redPlate")
 stack.Push("bluePlate")
 stack.Push("greenPlate")

 fmt.Println(stack.Head) // greenPlate

 // What's on top of the stack?
 value := stack.Pop()
 fmt.Println(value) // greenPlate

 stack.Push("yellowPlate")
 value = stack.Pop()
 fmt.Println(value) // yellowPlate

 // What's on top of the stack?
 value = stack.Pop()
 fmt.Println(value) // bluePlate

 // What's on top of the stack?
 value = stack.Pop()
 fmt.Println(value) // redPlate

Documentation

For a more detailled overview of laney, please refer to Documentation

Documentation

Overview

Lane package provides queue, priority queue, stack and deque data structures implementations. Its was designed with simplicity, performance, and concurrent usage in mind.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Deque

type Deque[T any] struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

Deque is a head-tail linked list data structure implementation. It is based on a doubly linked list container, so that every operations time complexity is O(1).

every operations over an instiated Deque are synchronized and safe for concurrent usage.

Example
// Let's create a new deque data structure
deque := NewDeque[string]()

// And push some content into it using the Append
// and Prepend methods
deque.Append("easy as")
deque.Prepend("123")
deque.Append("do re mi")
deque.Prepend("abc")

// Now let's take a look at what are the first and
// last element stored in the Deque
firstValue := deque.First()
lastValue := deque.Last()
fmt.Println(firstValue) // "abc"
fmt.Println(lastValue)  // 1

// Okay now let's play with the Pop and Shift
// methods to bring the song words together
jacksonFive := make([]string, deque.Size())

for i := 0; i < len(jacksonFive); i++ {
	value := deque.Shift()
	jacksonFive[i] = value
}

// abc 123 easy as do re mi
fmt.Println(strings.Join(jacksonFive, " "))
Output:

func NewCappedDeque

func NewCappedDeque[T any](capacity int) *Deque[T]

NewCappedDeque creates a Deque with the specified capacity limit.

func NewDeque

func NewDeque[T any]() *Deque[T]

NewDeque creates a Deque.

func (*Deque[T]) Append

func (s *Deque[T]) Append(item T) bool

Append inserts element at the back of the Deque in a O(1) time complexity, returning true if successful or false if the deque is at capacity.

func (*Deque[T]) Capacity

func (s *Deque[T]) Capacity() int

Capacity returns the capacity of the deque, or -1 if unlimited

func (*Deque[T]) Empty

func (s *Deque[T]) Empty() bool

Empty checks if the deque is empty

func (*Deque[T]) First

func (s *Deque[T]) First() T

First returns the first value stored in the deque in a O(1) time complexity

func (*Deque[T]) Full

func (s *Deque[T]) Full() bool

Full checks if the deque is full

func (*Deque[T]) Last

func (s *Deque[T]) Last() T

Last returns the last value stored in the deque in a O(1) time complexity

func (*Deque[T]) Pop

func (s *Deque[T]) Pop() T

Pop removes the last element of the deque in a O(1) time complexity

func (*Deque[T]) Prepend

func (s *Deque[T]) Prepend(item T) bool

Prepend inserts element at the Deques front in a O(1) time complexity, returning true if successful or false if the deque is at capacity.

func (*Deque[T]) Shift

func (s *Deque[T]) Shift() T

Shift removes the first element of the deque in a O(1) time complexity

func (*Deque[T]) Size

func (s *Deque[T]) Size() int

Size returns the actual deque size

type PQType

type PQType int

PQType represents a priority queue ordering kind (see MAXPQ and MINPQ)

const (
	MAXPQ PQType = iota
	MINPQ
)

type PQueue

type PQueue[T any] struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

PQueue is a heap priority queue data structure implementation. It can be whether max or min ordered and it is synchronized and is safe for concurrent operations.

Example
// Let's create a new max ordered priority queue
priorityQueue := NewPQueue[string](MINPQ)

// And push some prioritized content into it
priorityQueue.Push("easy as", 3)
priorityQueue.Push("123", 2)
priorityQueue.Push("do re mi", 4)
priorityQueue.Push("abc", 1)

// Now let's take a look at the min element in
// the priority queue
headValue, headPriority := priorityQueue.Head()
fmt.Println(headValue)    // "abc"
fmt.Println(headPriority) // 1

// Okay the song order seems to be preserved, let's
// roll
jacksonFive := make([]string, priorityQueue.Size())

for i := 0; i < len(jacksonFive); i++ {
	value, _ := priorityQueue.Pop()

	jacksonFive[i] = value
}

fmt.Println(strings.Join(jacksonFive, " "))
Output:

func NewPQueue

func NewPQueue[T any](pqType PQType) *PQueue[T]

NewPQueue creates a new priority queue with the provided pqtype ordering type

func (*PQueue[T]) Empty

func (pq *PQueue[T]) Empty() bool

Check queue is empty

func (*PQueue[T]) Head

func (pq *PQueue[T]) Head() (T, int)

Head returns the highest/lowest priority item (depending on whether you're using a MINPQ or MAXPQ) from the priority queue

func (*PQueue[T]) Pop

func (pq *PQueue[T]) Pop() (T, int)

Pop and returns the highest/lowest priority item (depending on whether you're using a MINPQ or MAXPQ) from the priority queue

func (*PQueue[T]) Push

func (pq *PQueue[T]) Push(value T, priority int)

Push the value item into the priority queue with provided priority.

func (*PQueue[T]) Size

func (pq *PQueue[T]) Size() int

Size returns the elements present in the priority queue count

type Queue

type Queue[T any] struct {
	*Deque[T]
}

Queue is a FIFO (First in first out) data structure implementation. It is based on a deque container and focuses its API on core functionalities: Enqueue, Dequeue, Head, Size, Empty. Every operations time complexity is O(1).

As it is implemented using a Deque container, every operations over an instiated Queue are synchronized and safe for concurrent usage.

Example
// Create a new queue and pretend we're handling starbucks
// clients
queue := NewQueue[string]()

// Let's add the incoming clients to the queue
queue.Enqueue("grumpyClient")
queue.Enqueue("happyClient")
queue.Enqueue("ecstaticClient")

fmt.Println(queue.Head()) // grumpyClient

// Let's handle the clients asynchronously
for client := queue.Dequeue(); client != ""; {
	go fmt.Println(client)
}
Output:

func NewQueue

func NewQueue[T any]() *Queue[T]

func (*Queue[T]) Dequeue

func (q *Queue[T]) Dequeue() T

Dequeue removes and returns the front queue item

func (*Queue[T]) Enqueue

func (q *Queue[T]) Enqueue(item T)

Enqueue adds an item at the back of the queue

func (*Queue[T]) Head

func (q *Queue[T]) Head() T

Head returns the front queue item

type Stack

type Stack[T any] struct {
	*Deque[T]
}

Stack is a LIFO (Last in first out) data structure implementation. It is based on a deque container and focuses its API on core functionalities: Push, Pop, Head, Size, Empty. Every operations time complexity is O(1).

As it is implemented using a Deque container, every operations over an instiated Stack are synchronized and safe for concurrent usage.

Example
// Create a new stack and put some plates over it
stack := NewStack[string]()

// Let's put some plates on the stack
stack.Push("redPlate")
stack.Push("bluePlate")
stack.Push("greenPlate")

fmt.Println(stack.Head()) // greenPlate

// What's on top of the stack?
value := stack.Pop()
fmt.Println(value) // greenPlate

stack.Push("yellowPlate")
value = stack.Pop()
fmt.Println(value) // yellowPlate

// What's on top of the stack?
value = stack.Pop()
fmt.Println(value) // bluePlate

// What's on top of the stack?
value = stack.Pop()
fmt.Println(value) // redPlate
Output:

func NewStack

func NewStack[T any]() *Stack[T]

func (*Stack[T]) Head

func (s *Stack[T]) Head() T

Head returns the item on the top of the stack

func (*Stack[T]) Pop

func (s *Stack[T]) Pop() T

Pop removes and returns the item on the top of the Stack

func (*Stack[T]) Push

func (s *Stack[T]) Push(item T)

Push adds on an item on the top of the Stack

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL