Files
node/utils/buffer/unbounded_blocking_deque.go
zeekay 7cf87b230b node-unified is the node
The module already called itself github.com/luxfi/node while containing no node
in Go: cmd/luxd was twenty-one lines that printed the size of a few types, and
the Go column of the matrix measured a VM plugin. A repo that fetches the thing
it claims to be has not replaced it, so the Go sources move in — 1515 files,
the daemon and everything under it — and the build reaches outside this module
for nothing.

Rust and C++ sit beside it unchanged and are still measured against it by the
differential. That is the point of one repo: the reference implementation and
the two ports are the same checkout, so parity is a thing you can run rather
than a thing you assert.

Verified: builds, and the closure carries no lux-private — checked at build time
rather than believed. The daemon starts twelve chains on a local network
(P X C Q Z A B G K M F, plus D through its plugin) and reports healthy.
2026-09-07 16:15:25 -07:00

170 lines
2.9 KiB
Go

// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package buffer
import (
"sync"
"github.com/luxfi/node/utils"
)
var _ BlockingDeque[int] = (*unboundedBlockingDeque[int])(nil)
type BlockingDeque[T any] interface {
Deque[T]
// Close and empty the deque.
Close()
}
// Returns a new unbounded deque with the given initial size.
// Note that the returned deque is always empty -- [initSize] is just
// a hint to prevent unnecessary resizing.
func NewUnboundedBlockingDeque[T any](initSize int) BlockingDeque[T] {
q := &unboundedBlockingDeque[T]{
Deque: NewUnboundedDeque[T](initSize),
}
q.cond = sync.NewCond(&q.lock)
return q
}
type unboundedBlockingDeque[T any] struct {
lock sync.RWMutex
cond *sync.Cond
closed bool
Deque[T]
}
// If the deque is closed returns false.
func (q *unboundedBlockingDeque[T]) PushRight(elt T) bool {
q.cond.L.Lock()
defer q.cond.L.Unlock()
if q.closed {
return false
}
// Add the item to the queue
q.Deque.PushRight(elt)
// Signal a waiting thread
q.cond.Signal()
return true
}
// If the deque is closed returns false.
func (q *unboundedBlockingDeque[T]) PopRight() (T, bool) {
q.cond.L.Lock()
defer q.cond.L.Unlock()
for {
if q.closed {
return utils.Zero[T](), false
}
if q.Deque.Len() != 0 {
return q.Deque.PopRight()
}
q.cond.Wait()
}
}
func (q *unboundedBlockingDeque[T]) PeekRight() (T, bool) {
q.lock.RLock()
defer q.lock.RUnlock()
if q.closed {
return utils.Zero[T](), false
}
return q.Deque.PeekRight()
}
// If the deque is closed returns false.
func (q *unboundedBlockingDeque[T]) PushLeft(elt T) bool {
q.cond.L.Lock()
defer q.cond.L.Unlock()
if q.closed {
return false
}
// Add the item to the queue
q.Deque.PushLeft(elt)
// Signal a waiting thread
q.cond.Signal()
return true
}
// If the deque is closed returns false.
func (q *unboundedBlockingDeque[T]) PopLeft() (T, bool) {
q.cond.L.Lock()
defer q.cond.L.Unlock()
for {
if q.closed {
return utils.Zero[T](), false
}
if q.Deque.Len() != 0 {
return q.Deque.PopLeft()
}
q.cond.Wait()
}
}
func (q *unboundedBlockingDeque[T]) PeekLeft() (T, bool) {
q.lock.RLock()
defer q.lock.RUnlock()
if q.closed {
return utils.Zero[T](), false
}
return q.Deque.PeekLeft()
}
func (q *unboundedBlockingDeque[T]) Index(i int) (T, bool) {
q.lock.RLock()
defer q.lock.RUnlock()
if q.closed {
return utils.Zero[T](), false
}
return q.Deque.Index(i)
}
func (q *unboundedBlockingDeque[T]) Len() int {
q.lock.RLock()
defer q.lock.RUnlock()
if q.closed {
return 0
}
return q.Deque.Len()
}
func (q *unboundedBlockingDeque[T]) List() []T {
q.lock.RLock()
defer q.lock.RUnlock()
if q.closed {
return nil
}
return q.Deque.List()
}
func (q *unboundedBlockingDeque[T]) Close() {
q.cond.L.Lock()
defer q.cond.L.Unlock()
if q.closed {
return
}
q.Deque = nil
// Mark the queue as closed
q.closed = true
q.cond.Broadcast()
}