Referencia Zigzkit (SDK consumido)

src/bounded_queue.zig

Declaraciones públicas de src/bounded_queue.zig (zkit (SDK consumido)).

ImplementadoSin versión del tren todavía· generada desde apps/docs/generated/zig/zkit.json

Página generada desde zkit@zkit-0.0.0-_fk2iAa4BQCqGFKJeeY9WvMQClX5kiZQ2iOZrVsxVyyN (src/root.zig). No se edita a mano: bun run docs:gen la regenera y bun run docs:check falla si difiere.

BoundedQueue(T) — cola FIFO acotada y thread-safe, con la política de desborde como PARÁMETRO.

Es la versión concurrente de SubscriberQueue (nodo zkit/handle-concurrent, r44 #9 de styx) y la generalización de PendingDeliveryQueue de styx (moqt_pending_delivery.zig), que llevaba mezclados la cola, la política live/VOD, la espera por backpressure (con nanosleep de 0.5 ms en bucle) y los contadores de dominio. Aquí queda la parte genérica:

  • Anillo de capacidad fija reservado en init: push NUNCA reserva memoria, así que el hot path no tiene un error.OutOfMemory que convertir en pérdida silenciosa.
  • Overflow.reject: lleno ⇒ .full (o pushWait espera con un Condition, sin sondeo, hasta un plazo).
  • Overflow.drop_oldest: lleno ⇒ se expulsa el más viejo y se DEVUELVE al llamador (.evicted) para que libere lo que posea — la versión single-thread lo tiraba sin devolverlo, un leak para T con recursos. La siguiente pop devuelve .discontinuity (contrato de SubscriberQueue). El productor nunca espera ni es rechazado.
  • Drenado con RESERVA (beginDrain/settleDrain): lo que el consumidor no pudo entregar vuelve al FRENTE en orden. · .reject: lo sacado SIGUE contando contra la capacidad hasta que se liquida. Invariante en todo instante: len + reserved <= capacity, así que settleDrain nunca desborda ni pierde nada. · .drop_oldest: lo sacado NO bloquea al productor (lo fresco manda). Invariante: len <= capacity. Si al liquidar no cabe todo, se descartan los más viejos de lo devuelto (que son más viejos que todo lo encolado) y se entregan al llamador.
  • close() despierta a todos los que esperan; wakeAll() también, para que un productor que espera re-mire su flag de cancelación.

Los contadores de dominio (por pista, por sesión) se quedan en el consumidor; aquí sólo hay agregados baratos en stats().

bounded_queue.Overflow

type · línea 39

pub const Overflow = enum

Sin ///.

bounded_queue.Options

type · línea 47

pub const Options = struct

Sin ///.

bounded_queue.BoundedQueue

fn · línea 52

pub fn BoundedQueue(comptime T: type) type

Sin ///.

bounded_queue.BoundedQueue.InitError

const · línea 56

pub const InitError = error{ InvalidParameter, OutOfMemory }

Sin ///.

bounded_queue.BoundedQueue.Error

const · línea 57

pub const Error = error{Closed}

Sin ///.

bounded_queue.BoundedQueue.WaitError

const · línea 58

pub const WaitError = error{ Closed, Timeout, Cancelled }

Sin ///.

bounded_queue.BoundedQueue.PushResult

type · línea 60

pub const PushResult = union

Sin ///.

bounded_queue.BoundedQueue.PopResult

type · línea 70

pub const PopResult = union

Sin ///.

bounded_queue.BoundedQueue.Stats

type · línea 77

pub const Stats = struct

Sin ///.

bounded_queue.BoundedQueue.init

fn · línea 97

pub fn init(allocator: std.mem.Allocator, opts: Options) InitError!Self

Sin ///.

bounded_queue.BoundedQueue.deinit

fn · línea 108

pub fn deinit(self: *Self) void

Libera el anillo. Los items que queden NO se destruyen: si T posee recursos, vacíala antes con drainInto.

bounded_queue.BoundedQueue.capacity

fn · línea 117

pub fn capacity(self: *const Self) usize

Sin ///.

bounded_queue.BoundedQueue.len

fn · línea 121

pub fn len(self: *Self) usize

Sin ///.

bounded_queue.BoundedQueue.reservedCount

fn · línea 127

pub fn reservedCount(self: *Self) usize

Sin ///.

bounded_queue.BoundedQueue.stats

fn · línea 133

pub fn stats(self: *Self) Stats

Sin ///.

bounded_queue.BoundedQueue.close

fn · línea 142

pub fn close(self: *Self) void

Cierra la cola: los push posteriores fallan con error.Closed, y los que esperan se despiertan. Lo ya encolado se puede seguir sacando.

bounded_queue.BoundedQueue.wakeAll

fn · línea 154

pub fn wakeAll(self: *Self) void

Despierta a todos los que esperan para que re-evalúen su plazo o su flag de cancelación.

bounded_queue.BoundedQueue.push

fn · línea 165

pub fn push(self: *Self, item: T) Error!PushResult

Encola sin bloquear.

bounded_queue.BoundedQueue.pushWait

fn · línea 180

pub fn pushWait( self: *Self, item: T, deadline: time.Deadline, cancel: ?*const std.atomic.Value(bool), ) WaitError!PushResult

Encola; con .reject y la cola llena espera (sin sondeo) a que haya sitio hasta deadline. cancel se re-evalúa en cada despertar: quien lo pone a true debe llamar a wakeAll(). Con .drop_oldest no espera nunca.

bounded_queue.BoundedQueue.pop

fn · línea 242

pub fn pop(self: *Self) PopResult

Saca el más viejo sin bloquear.

bounded_queue.BoundedQueue.popWait

fn · línea 254

pub fn popWait(self: *Self, deadline: time.Deadline) error{ Closed, Timeout }!PopResult

Como pop, esperando hasta deadline si está vacía. error.Closed sólo cuando está cerrada Y vacía.

bounded_queue.BoundedQueue.takeDiscontinuity

fn · línea 283

pub fn takeDiscontinuity(self: *Self) bool

true (una vez) si hubo expulsiones desde la última consulta. Para consumidores por lotes que no usan pop.

bounded_queue.BoundedQueue.drainInto

fn · línea 291

pub fn drainInto(self: *Self, out: []T) usize

Mueve hasta out.len items a out (propiedad plena, sin reserva).

bounded_queue.BoundedQueue.beginDrain

fn · línea 300

pub fn beginDrain(self: *Self, out: []T) usize

Como drainInto, pero lo sacado SIGUE contando contra la capacidad hasta settleDrain. Un único consumidor: begin/settle estrictamente emparejados.

bounded_queue.BoundedQueue.settleDrain

fn · línea 311

pub fn settleDrain(self: *Self, held: []const T, evicted: []T) usize

Liquida el drenado en curso: held (lo que NO se pudo entregar, en su orden original, prefijo o subconjunto ordenado de lo sacado) vuelve al FRENTE. En .reject siempre cabe (invariante len + reserved <= capacity) y devuelve 0. En .drop_oldest lo que no quepa se descarta empezando por el más viejo de held: esos items se copian a evicted (el llamador es su dueño; evicted.len debe alcanzar held.len) y se devuelve cuántos.

BoundedQueue

fn · línea 52

pub fn BoundedQueue(comptime T: type) type

Sin ///.

BoundedQueue.InitError

const · línea 56

pub const InitError = error{ InvalidParameter, OutOfMemory }

Sin ///.

BoundedQueue.Error

const · línea 57

pub const Error = error{Closed}

Sin ///.

BoundedQueue.WaitError

const · línea 58

pub const WaitError = error{ Closed, Timeout, Cancelled }

Sin ///.

BoundedQueue.PushResult

type · línea 60

pub const PushResult = union

Sin ///.

BoundedQueue.PopResult

type · línea 70

pub const PopResult = union

Sin ///.

BoundedQueue.Stats

type · línea 77

pub const Stats = struct

Sin ///.

BoundedQueue.init

fn · línea 97

pub fn init(allocator: std.mem.Allocator, opts: Options) InitError!Self

Sin ///.

BoundedQueue.deinit

fn · línea 108

pub fn deinit(self: *Self) void

Libera el anillo. Los items que queden NO se destruyen: si T posee recursos, vacíala antes con drainInto.

BoundedQueue.capacity

fn · línea 117

pub fn capacity(self: *const Self) usize

Sin ///.

BoundedQueue.len

fn · línea 121

pub fn len(self: *Self) usize

Sin ///.

BoundedQueue.reservedCount

fn · línea 127

pub fn reservedCount(self: *Self) usize

Sin ///.

BoundedQueue.stats

fn · línea 133

pub fn stats(self: *Self) Stats

Sin ///.

BoundedQueue.close

fn · línea 142

pub fn close(self: *Self) void

Cierra la cola: los push posteriores fallan con error.Closed, y los que esperan se despiertan. Lo ya encolado se puede seguir sacando.

BoundedQueue.wakeAll

fn · línea 154

pub fn wakeAll(self: *Self) void

Despierta a todos los que esperan para que re-evalúen su plazo o su flag de cancelación.

BoundedQueue.push

fn · línea 165

pub fn push(self: *Self, item: T) Error!PushResult

Encola sin bloquear.

BoundedQueue.pushWait

fn · línea 180

pub fn pushWait( self: *Self, item: T, deadline: time.Deadline, cancel: ?*const std.atomic.Value(bool), ) WaitError!PushResult

Encola; con .reject y la cola llena espera (sin sondeo) a que haya sitio hasta deadline. cancel se re-evalúa en cada despertar: quien lo pone a true debe llamar a wakeAll(). Con .drop_oldest no espera nunca.

BoundedQueue.pop

fn · línea 242

pub fn pop(self: *Self) PopResult

Saca el más viejo sin bloquear.

BoundedQueue.popWait

fn · línea 254

pub fn popWait(self: *Self, deadline: time.Deadline) error{ Closed, Timeout }!PopResult

Como pop, esperando hasta deadline si está vacía. error.Closed sólo cuando está cerrada Y vacía.

BoundedQueue.takeDiscontinuity

fn · línea 283

pub fn takeDiscontinuity(self: *Self) bool

true (una vez) si hubo expulsiones desde la última consulta. Para consumidores por lotes que no usan pop.

BoundedQueue.drainInto

fn · línea 291

pub fn drainInto(self: *Self, out: []T) usize

Mueve hasta out.len items a out (propiedad plena, sin reserva).

BoundedQueue.beginDrain

fn · línea 300

pub fn beginDrain(self: *Self, out: []T) usize

Como drainInto, pero lo sacado SIGUE contando contra la capacidad hasta settleDrain. Un único consumidor: begin/settle estrictamente emparejados.

BoundedQueue.settleDrain

fn · línea 311

pub fn settleDrain(self: *Self, held: []const T, evicted: []T) usize

Liquida el drenado en curso: held (lo que NO se pudo entregar, en su orden original, prefijo o subconjunto ordenado de lo sacado) vuelve al FRENTE. En .reject siempre cabe (invariante len + reserved <= capacity) y devuelve 0. En .drop_oldest lo que no quepa se descarta empezando por el más viejo de held: esos items se copian a evicted (el llamador es su dueño; evicted.len debe alcanzar held.len) y se devuelve cuántos.