goutils/pkg/datastructs/queues.go
Samuel Becker e2e40cb56e Init go module and some files
Idk why maputils cant find sliceutils
2022-08-07 19:52:10 +02:00

95 lines
2 KiB
Go

package datastructs
import (
"encoding/json"
"errors"
)
type Queue[T any] struct {
head *ChainElem[T]
tail *ChainElem[T]
}
// isValid checks if the queue is still valid.
func (q *Queue[T]) isValid() bool {
return q.head != nil &&
q.tail != nil &&
reachable(q.head, q.tail)
}
// IsEmpty checks if the queue is empty.
func (q *Queue[T]) IsEmpty() bool {
return q.head == q.tail
}
// Push adds a new element to the end of the queue.
func (q *Queue[T]) Push(elem *T) error {
if !q.isValid() {
return errors.New("invalid queue")
}
e := emptyElem[T]()
q.tail.Elem = elem
q.tail.Next = e
q.tail = e
return nil
}
// Pop removes the first element of the queue.
// It errors out if there is no element or the queue is invalid.
func (q *Queue[T]) Pop() (*T, error) {
if !q.isValid() {
return nil, errors.New("invalid queue")
}
if q.IsEmpty() {
return nil, errors.New("empty queue")
}
Elem := q.head.Elem
q.head = q.head.Next
return Elem, nil
}
// Top returns the first element of the queue without removing it.
// It errors out if there is no element or the queue is invalid.
func (q *Queue[T]) Top() (*T, error) {
if !q.isValid() {
return nil, errors.New("queue invalid")
}
if q.IsEmpty() {
return nil, errors.New("queue empty")
}
return q.head.Elem, nil
}
// HeadElem returns the first ChainElem of the queue without removing it.
// It errors out if there is no element or the queue is invalid.
func (q *Queue[T]) HeadElem() (*ChainElem[T], error) {
if !q.isValid() {
return nil, errors.New("queue invalid")
}
if q.IsEmpty() {
return nil, errors.New("queue empty")
}
return q.head, nil
}
// MarshalJSON is used for generating json data when using json.Marshal.
func (q *Queue[T]) MarshalJSON() ([]byte, error) {
if !q.isValid() {
return nil, errors.New("queue invalid")
}
if q.IsEmpty() {
return nil, errors.New("queue empty")
}
return json.Marshal(q.head)
}
func BuildQueue[T any]() *Queue[T] {
empty := emptyElem[T]()
return &Queue[T]{
head: empty,
tail: empty,
}
}