My agentic slop goes here. Not intended for anyone else!
at main 4.9 kB view raw
1(** File-backed persistent cache with streaming API and TTL support 2 3 Cacheio provides a robust file-backed caching system designed for high-performance 4 applications that need persistent storage with automatic expiry management. 5 6 {2 Key Features} 7 8 - {b SHA256-based key hashing}: Uniform distribution across subdirectories 9 - {b Maildir++-style naming}: Atomic operations with flag and TTL encoding 10 - {b Streaming API}: Built on Eio.Flow for efficient, non-blocking I/O 11 - {b Automatic expiry}: TTL-based cache expiration with manual control 12 - {b Thread-safe}: All operations are safe for concurrent access 13 - {b Chunk support}: Resume partial downloads with range-based chunks 14 - {b XDG integration}: Automatic directory management via XDG Base Directory spec 15 16 {2 Usage Example} 17 18 {[ 19 let cache = Cacheio.create ~base_dir:cache_dir in 20 21 (* Store data with 1 hour TTL *) 22 Eio.Switch.run @@ fun sw -> 23 let source = Eio.Flow.string_source "Hello, World!" in 24 Cacheio.put cache ~key:"greeting" ~source ~ttl:(Some 3600.0) (); 25 26 (* Retrieve data *) 27 Eio.Switch.run @@ fun sw -> 28 match Cacheio.get cache ~key:"greeting" ~sw with 29 | Some source -> 30 let content = Eio.Buf_read.(parse_exn take_all) source ~max_size:Int.max_int in 31 print_endline content 32 | None -> print_endline "Not found" 33 ]}*) 34 35(** {1 Core Operations} *) 36 37(** Abstract type representing a cache instance *) 38type t 39 40(** Create a new cache at the specified base directory *) 41val create : base_dir:Eio.Fs.dir_ty Eio.Path.t -> t 42 43(** Create a new cache using an Xdge context *) 44val create_with_xdge : Xdge.t -> t 45 46(** Check if a key exists in the cache. 47 Keys are strings that will be automatically hashed for filesystem storage. *) 48val exists : t -> key:string -> bool 49 50(** Get a stream source for reading cached data *) 51val get : t -> key:string -> sw:Eio.Switch.t -> Eio.Flow.source_ty Eio.Resource.t option 52 53(** Cache flags management *) 54module Flags = Flags 55 56(** Store data from a stream source with optional TTL and flags *) 57val put : t -> key:string -> source:Eio.Flow.source_ty Eio.Resource.t -> 58 ?ttl:float option -> ?flags:Flags.t -> unit -> unit 59 60(** Delete a cache entry *) 61val delete : t -> key:string -> unit 62 63(** Get the size of a cache entry in bytes *) 64val size : t -> key:string -> int64 option 65 66(** Get the path to a cache entry (for direct file access if needed) *) 67val get_path : t -> key:string -> Eio.Fs.dir_ty Eio.Path.t option 68 69(** {1 Flag Management} *) 70 71(** Add a flag to an entry *) 72val add_flag : t -> key:string -> Flags.flag -> unit 73 74(** Remove a flag from an entry *) 75val remove_flag : t -> key:string -> Flags.flag -> unit 76 77(** Set specific flags on an entry (replaces all existing) *) 78val set_flags : t -> key:string -> Flags.t -> unit 79 80(** Get current flags for an entry *) 81val get_flags : t -> key:string -> Flags.t option 82 83(** {1 Cache Management} *) 84 85(** Cache entry information *) 86module Entry = Entry 87 88(** Cache statistics *) 89module Stats = Stats 90 91(** Scan the cache and return all entries *) 92val scan : t -> Entry.t list 93 94(** Get cache statistics *) 95val stats : t -> Stats.t 96 97(** Remove expired entries and return count of removed entries *) 98val expire : t -> int 99 100(** Clear all entries (except pinned ones) *) 101val clear : t -> unit 102 103(** Clear all temporary entries *) 104val clear_temporary : t -> unit 105 106(** {1 Chunk Support for Partial Downloads} *) 107 108(** Range management for partial downloads *) 109module Range = Range 110 111(** Chunk file management *) 112module Chunk = Chunk 113 114(** Store a chunk of data with a specific byte range *) 115val put_chunk : t -> key:string -> range:Range.t -> 116 source:Eio.Flow.source_ty Eio.Resource.t -> 117 ?ttl:float option -> ?flags:Flags.t -> unit -> unit 118 119(** Get data for a specific range, returns either complete file or chunks *) 120val get_range : t -> key:string -> range:Range.t -> sw:Eio.Switch.t -> 121 [ `Complete of Eio.Flow.source_ty Eio.Resource.t 122 | `Chunks of (Range.t * Eio.Flow.source_ty Eio.Resource.t) list 123 | `Not_found ] 124 125(** List all chunks for a key *) 126val list_chunks : t -> key:string -> Chunk.t list 127 128(** Check if chunks form a complete sequence *) 129val has_complete_chunks : t -> key:string -> total_size:int64 -> bool 130 131(** Get missing byte ranges for incomplete downloads *) 132val missing_ranges : t -> key:string -> total_size:int64 -> Range.t list 133 134(** Coalesce chunks into a complete file asynchronously *) 135val coalesce_chunks : t -> key:string -> ?verify:bool -> ?flags:Flags.t -> 136 ?ttl:float option -> unit -> unit Eio.Promise.or_exn 137 138(** Clean up all chunks for a key *) 139val cleanup_chunks : t -> key:string -> unit 140 141(** {1 Pretty Printing} *) 142 143(** Pretty printer for cache *) 144val pp : Format.formatter -> t -> unit