Naut/include/naut/piece.h
ookami125 b633b7d216 nautd/webui: scripting, labels, settings, set-location, pause fix
Session checkpoint on webui-plugin:
- engine dump (nautctl dump) + engine endgame integration
- per-file move locations persistence; torrent-level "Set location"
  with reset/keep-relative/leave-separate handling + residual prune
- Lua: naut.get_labels, define_settings/get_setting (script_host struct)
- daemon-owned labels (category+tags) + taxonomy persistence; webui write-through
- fix: pausing a completed/seeding torrent now sticks (stop wins over result)
- automation tab responsive layout; anime_sort label gating + settings

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 23:19:41 -04:00

106 lines
5.6 KiB
C

/* piece.h — download state: block requests, piece assembly, verify, persist.
*
* A piece is assembled in memory as its blocks arrive, verified against the
* metainfo hash (SHA-1 for v1/hybrid), then written to storage in one shot —
* so a corrupt piece never reaches disk.
*/
#ifndef NAUT_PIECE_H
#define NAUT_PIECE_H
#include "naut/common.h"
#include "naut/metainfo.h"
#include "naut/storage.h"
#include "naut/bitfield.h"
#include "naut/worker.h"
#include <stdio.h>
typedef struct naut_download naut_download;
naut_download *naut_download_create(const naut_metainfo *mi, naut_storage *st);
void naut_download_destroy(naut_download *d);
/* Scan existing storage and mark SHA-1 verified pieces complete before
* requesting from peers. Invalid or missing pieces are left for download. */
naut_err naut_download_resume(naut_download *d);
/* Optional hash offload. Completed-piece SHA-1 jobs run on the worker pool;
* naut_download_poll() finalizes verified pieces on the owning engine thread.
* The pool must outlive the download. */
void naut_download_set_worker_pool(naut_download *d, naut_worker_pool *pool);
naut_err naut_download_poll(naut_download *d, uint32_t *pieces_completed);
/* ---- multi-peer swarm interface (Phase 4) ------------------------------- *
* Availability: report what each peer has so rarest-first can rank pieces. A
* peer's bitfield is added on connect (BITFIELD) and removed on disconnect; a
* single HAVE bumps one piece. */
void naut_download_add_bitfield(naut_download *d, const naut_bitfield *peer_have);
void naut_download_remove_bitfield(naut_download *d, const naut_bitfield *peer_have);
void naut_download_inc_avail(naut_download *d, uint32_t piece);
/* Pick the next block to request for a peer with `peer_have`. Uses rarest-first,
* prefers finishing in-progress pieces, and switches to endgame (allowing a
* block to be requested from multiple peers) when few blocks remain. Returns
* false if this peer has nothing useful to request right now. */
bool naut_download_pick(naut_download *d, const naut_bitfield *peer_have,
uint32_t *index, uint32_t *begin, uint32_t *length);
/* Endgame may duplicate a block across peers, but never back to the same peer.
* `peer_has_request` lets the caller expose that peer's current request set.
* Outside endgame this behaves exactly like naut_download_pick(). */
typedef bool (*naut_request_active_cb)(void *ctx, uint32_t index, uint32_t begin);
bool naut_download_pick_for_peer(naut_download *d, const naut_bitfield *peer_have,
naut_request_active_cb peer_has_request, void *ctx,
uint32_t *index, uint32_t *begin, uint32_t *length);
/* Release a request (peer disconnected, or cancel) so the block can be re-picked. */
void naut_download_unrequest(naut_download *d, uint32_t index, uint32_t begin);
bool naut_download_have(const naut_download *d, uint32_t piece);
bool naut_download_in_endgame(const naut_download *d);
/* Per-file completion: fired the moment the last piece overlapping a file's byte
* range verifies (so the file's bytes on disk are final and it is safe to move).
* This is the engine seam for the user's "move files as they finish" feature —
* the scripting layer (Phase 7) forwards this to an on_file_complete hook and may
* then call naut_storage_relocate(). The callback runs on the engine thread; a
* script must marshal any action back through the command queue.
*
* NOTE: fires during naut_download_on_block(); a single block may complete
* several files (small files packed into one piece). Empty files are reported as
* complete via naut_download_file_complete() but do not fire the callback. */
typedef void (*naut_file_complete_cb)(void *ctx, uint32_t file_index, const char *path);
void naut_download_set_file_cb(naut_download *d, naut_file_complete_cb cb, void *ctx);
bool naut_download_file_complete(const naut_download *d, uint32_t file_index);
/* Optional owner-thread notification after a piece verifies and is persisted. */
typedef void (*naut_piece_complete_cb)(void *ctx, uint32_t piece_index);
void naut_download_set_piece_cb(naut_download *d, naut_piece_complete_cb cb,
void *ctx);
/* Hand out the next block to request. false => nothing left to hand out right
* now (all blocks have been requested). */
bool naut_download_next_request(naut_download *d,
uint32_t *index, uint32_t *begin, uint32_t *length);
/* Feed a received PIECE block. *piece_done is set true iff this block completed
* a piece that then verified and was written to storage. With a worker pool,
* completion is reported later through naut_download_poll(). */
naut_err naut_download_on_block(naut_download *d, uint32_t index, uint32_t begin,
const uint8_t *data, uint32_t len, bool *piece_done);
bool naut_download_complete(const naut_download *d);
uint32_t naut_download_num_pieces(const naut_download *d);
uint32_t naut_download_pieces_done(const naut_download *d);
uint64_t naut_download_bytes_done(const naut_download *d);
size_t naut_download_piece_states(const naut_download *d, uint8_t *out,
size_t capacity);
/* Diagnostic: write a human-readable dump of block-assembly state to `out` —
* overall progress plus, for every piece not yet verified, how many of its
* blocks have arrived and how many requests are outstanding. Pairs with
* engine_dump_torrent() (which covers piece selection across peers) to
* investigate pieces that never finish downloading. */
void naut_download_dump(const naut_download *d, FILE *out);
#endif /* NAUT_PIECE_H */