|
|
|
|
@ -341,6 +341,18 @@ int stream_buffer_range(struct stream_buffer *b, uint8_t subblock, uint64_t *fir
|
|
|
|
|
return STREAM_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* При GAP потребитель сохраняет все ещё декодируемые пачки, даже если выбранные upstream уже далеко впереди. */ |
|
|
|
|
int stream_buffer_next_decodable(struct stream_buffer *b, uint64_t seq, uint64_t *next) { |
|
|
|
|
if (!b || !next) { DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "buffer next decodable invalid arguments"); return STREAM_ERR_ARGUMENT; } |
|
|
|
|
uint64_t found = UINT64_MAX; |
|
|
|
|
for (uint32_t i = 0; i < b->stats.batches; i++) { |
|
|
|
|
struct stream_cached_batch *batch = b->heap[i]; |
|
|
|
|
if (batch->seq >= seq && batch->seq < found && batch->count >= b->descriptor.n - b->descriptor.r) found = batch->seq; |
|
|
|
|
} |
|
|
|
|
if (found == UINT64_MAX) return STREAM_WAIT; |
|
|
|
|
*next = found; return STREAM_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* RS пишет в собственный scratch; ошибка или недостающие блоки не повреждают выход потребителя. */ |
|
|
|
|
int stream_buffer_decode(struct stream_buffer *b, uint64_t seq, uint8_t *output, size_t capacity, size_t *length) { |
|
|
|
|
if (!b || !output || !length || seq == UINT64_MAX) { |
|
|
|
|
|