lmcache-cli 0.4.5.dev0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (399) hide show
  1. lmcache/__init__.py +84 -0
  2. lmcache/_version.py +24 -0
  3. lmcache/cli/__init__.py +1 -0
  4. lmcache/cli/commands/__init__.py +34 -0
  5. lmcache/cli/commands/base.py +157 -0
  6. lmcache/cli/commands/bench/__init__.py +557 -0
  7. lmcache/cli/commands/bench/engine_bench/__init__.py +1 -0
  8. lmcache/cli/commands/bench/engine_bench/config.py +245 -0
  9. lmcache/cli/commands/bench/engine_bench/interactive/__init__.py +274 -0
  10. lmcache/cli/commands/bench/engine_bench/interactive/config.json +10 -0
  11. lmcache/cli/commands/bench/engine_bench/interactive/schema.py +352 -0
  12. lmcache/cli/commands/bench/engine_bench/interactive/state.py +327 -0
  13. lmcache/cli/commands/bench/engine_bench/interactive/terminal.py +291 -0
  14. lmcache/cli/commands/bench/engine_bench/progress.py +145 -0
  15. lmcache/cli/commands/bench/engine_bench/request_sender.py +232 -0
  16. lmcache/cli/commands/bench/engine_bench/stats.py +275 -0
  17. lmcache/cli/commands/bench/engine_bench/workloads/__init__.py +153 -0
  18. lmcache/cli/commands/bench/engine_bench/workloads/base.py +122 -0
  19. lmcache/cli/commands/bench/engine_bench/workloads/long_doc_permutator.py +435 -0
  20. lmcache/cli/commands/bench/engine_bench/workloads/long_doc_qa.py +281 -0
  21. lmcache/cli/commands/bench/engine_bench/workloads/multi_round_chat.py +337 -0
  22. lmcache/cli/commands/bench/engine_bench/workloads/random_prefill.py +178 -0
  23. lmcache/cli/commands/describe.py +310 -0
  24. lmcache/cli/commands/kvcache.py +133 -0
  25. lmcache/cli/commands/mock.py +75 -0
  26. lmcache/cli/commands/ping.py +113 -0
  27. lmcache/cli/commands/query/__init__.py +155 -0
  28. lmcache/cli/commands/query/prompt.py +134 -0
  29. lmcache/cli/commands/query/request.py +357 -0
  30. lmcache/cli/commands/server.py +99 -0
  31. lmcache/cli/commands/tool/__init__.py +63 -0
  32. lmcache/cli/commands/tool/cache_simulator.py +113 -0
  33. lmcache/cli/commands/trace/__init__.py +505 -0
  34. lmcache/cli/commands/trace/dispatch.py +249 -0
  35. lmcache/cli/commands/trace/driver.py +372 -0
  36. lmcache/cli/commands/trace/stats.py +289 -0
  37. lmcache/cli/documents/lmcache.txt +11 -0
  38. lmcache/cli/main.py +42 -0
  39. lmcache/cli/metrics/__init__.py +29 -0
  40. lmcache/cli/metrics/formatter.py +171 -0
  41. lmcache/cli/metrics/handler.py +94 -0
  42. lmcache/cli/metrics/metrics.py +161 -0
  43. lmcache/cli/metrics/section.py +77 -0
  44. lmcache/connections.py +173 -0
  45. lmcache/integration/__init__.py +2 -0
  46. lmcache/integration/base_service_factory.py +165 -0
  47. lmcache/integration/request_telemetry/__init__.py +1 -0
  48. lmcache/integration/request_telemetry/base.py +51 -0
  49. lmcache/integration/request_telemetry/factory.py +113 -0
  50. lmcache/integration/request_telemetry/fastapi.py +109 -0
  51. lmcache/integration/request_telemetry/noop.py +35 -0
  52. lmcache/integration/sglang/__init__.py +2 -0
  53. lmcache/integration/sglang/sglang_adapter.py +326 -0
  54. lmcache/integration/sglang/utils.py +39 -0
  55. lmcache/integration/vllm/__init__.py +1 -0
  56. lmcache/integration/vllm/lmcache_connector_v1.py +213 -0
  57. lmcache/integration/vllm/lmcache_connector_v1_085.py +150 -0
  58. lmcache/integration/vllm/lmcache_mp_connector_0180.py +1072 -0
  59. lmcache/integration/vllm/tests/test_mm_hash_utils.py +112 -0
  60. lmcache/integration/vllm/utils.py +433 -0
  61. lmcache/integration/vllm/vllm_multi_process_adapter.py +1090 -0
  62. lmcache/integration/vllm/vllm_service_factory.py +339 -0
  63. lmcache/integration/vllm/vllm_v1_adapter.py +1713 -0
  64. lmcache/logging.py +107 -0
  65. lmcache/native_storage_ops.pyi +230 -0
  66. lmcache/non_cuda_equivalents.py +1424 -0
  67. lmcache/observability.py +1958 -0
  68. lmcache/storage_backend/serde/__init__.py +1 -0
  69. lmcache/storage_backend/serde/cachegen_basics.py +210 -0
  70. lmcache/storage_backend/serde/cachegen_decoder.py +207 -0
  71. lmcache/storage_backend/serde/cachegen_encoder.py +394 -0
  72. lmcache/storage_backend/serde/serde.py +75 -0
  73. lmcache/tools/__init__.py +1 -0
  74. lmcache/tools/cache_simulator/README.md +392 -0
  75. lmcache/tools/cache_simulator/__init__.py +1 -0
  76. lmcache/tools/cache_simulator/docs/simulate_example.png +0 -0
  77. lmcache/tools/cache_simulator/docs/sweep_example.png +0 -0
  78. lmcache/tools/cache_simulator/gen_bench_dataset.py +360 -0
  79. lmcache/tools/cache_simulator/lru_cache.py +124 -0
  80. lmcache/tools/cache_simulator/plot_hit_rate.py +231 -0
  81. lmcache/tools/cache_simulator/simulator.py +795 -0
  82. lmcache/tools/controller_benchmark/README.md +161 -0
  83. lmcache/tools/controller_benchmark/__init__.py +1 -0
  84. lmcache/tools/controller_benchmark/__main__.py +331 -0
  85. lmcache/tools/controller_benchmark/benchmark.py +660 -0
  86. lmcache/tools/controller_benchmark/config.py +44 -0
  87. lmcache/tools/controller_benchmark/constants.py +10 -0
  88. lmcache/tools/controller_benchmark/handlers/__init__.py +46 -0
  89. lmcache/tools/controller_benchmark/handlers/admit.py +52 -0
  90. lmcache/tools/controller_benchmark/handlers/base.py +47 -0
  91. lmcache/tools/controller_benchmark/handlers/deregister.py +49 -0
  92. lmcache/tools/controller_benchmark/handlers/evict.py +52 -0
  93. lmcache/tools/controller_benchmark/handlers/heartbeat.py +56 -0
  94. lmcache/tools/controller_benchmark/handlers/p2p_lookup.py +47 -0
  95. lmcache/tools/controller_benchmark/handlers/register.py +56 -0
  96. lmcache/tools/mp_status_viewer/__init__.py +1 -0
  97. lmcache/tools/mp_status_viewer/__main__.py +95 -0
  98. lmcache/usage_context.py +417 -0
  99. lmcache/utils.py +665 -0
  100. lmcache/v1/__init__.py +2 -0
  101. lmcache/v1/api_server/__init__.py +2 -0
  102. lmcache/v1/api_server/__main__.py +537 -0
  103. lmcache/v1/basic_check.py +112 -0
  104. lmcache/v1/cache_controller/__init__.py +9 -0
  105. lmcache/v1/cache_controller/commands/__init__.py +15 -0
  106. lmcache/v1/cache_controller/commands/base.py +35 -0
  107. lmcache/v1/cache_controller/commands/full_sync.py +49 -0
  108. lmcache/v1/cache_controller/config.py +176 -0
  109. lmcache/v1/cache_controller/controller_manager.py +535 -0
  110. lmcache/v1/cache_controller/controllers/__init__.py +11 -0
  111. lmcache/v1/cache_controller/controllers/full_sync_tracker.py +473 -0
  112. lmcache/v1/cache_controller/controllers/kv_controller.py +439 -0
  113. lmcache/v1/cache_controller/controllers/registration_controller.py +282 -0
  114. lmcache/v1/cache_controller/executor.py +463 -0
  115. lmcache/v1/cache_controller/frontend/static/css/style.css +201 -0
  116. lmcache/v1/cache_controller/frontend/static/img/logo.png +0 -0
  117. lmcache/v1/cache_controller/frontend/static/index.html +234 -0
  118. lmcache/v1/cache_controller/frontend/static/js/controller_app.js +660 -0
  119. lmcache/v1/cache_controller/full_sync_sender.py +475 -0
  120. lmcache/v1/cache_controller/locks.py +149 -0
  121. lmcache/v1/cache_controller/message.py +828 -0
  122. lmcache/v1/cache_controller/observability.py +208 -0
  123. lmcache/v1/cache_controller/utils.py +679 -0
  124. lmcache/v1/cache_controller/worker.py +665 -0
  125. lmcache/v1/cache_engine.py +2058 -0
  126. lmcache/v1/cache_interface.py +19 -0
  127. lmcache/v1/check/__init__.py +74 -0
  128. lmcache/v1/check/check_mode_gen.py +86 -0
  129. lmcache/v1/check/check_mode_test_l2_adapter.py +284 -0
  130. lmcache/v1/check/check_mode_test_remote.py +155 -0
  131. lmcache/v1/check/check_mode_test_storage_manager.py +142 -0
  132. lmcache/v1/check/utils.py +571 -0
  133. lmcache/v1/compute/__init__.py +2 -0
  134. lmcache/v1/compute/attention/__init__.py +0 -0
  135. lmcache/v1/compute/attention/abstract.py +39 -0
  136. lmcache/v1/compute/attention/flash_attn.py +129 -0
  137. lmcache/v1/compute/attention/flash_infer_sparse.py +284 -0
  138. lmcache/v1/compute/attention/metadata.py +85 -0
  139. lmcache/v1/compute/attention/utils.py +14 -0
  140. lmcache/v1/compute/blend/__init__.py +7 -0
  141. lmcache/v1/compute/blend/blender.py +168 -0
  142. lmcache/v1/compute/blend/metadata.py +34 -0
  143. lmcache/v1/compute/blend/utils.py +63 -0
  144. lmcache/v1/compute/models/__init__.py +0 -0
  145. lmcache/v1/compute/models/base.py +141 -0
  146. lmcache/v1/compute/models/llama.py +9 -0
  147. lmcache/v1/compute/models/qwen3.py +24 -0
  148. lmcache/v1/compute/models/utils.py +68 -0
  149. lmcache/v1/compute/positional_encoding.py +199 -0
  150. lmcache/v1/config.py +848 -0
  151. lmcache/v1/config_base.py +848 -0
  152. lmcache/v1/distributed/api.py +248 -0
  153. lmcache/v1/distributed/config.py +321 -0
  154. lmcache/v1/distributed/error.py +64 -0
  155. lmcache/v1/distributed/eviction.py +192 -0
  156. lmcache/v1/distributed/eviction_policy/__init__.py +21 -0
  157. lmcache/v1/distributed/eviction_policy/factory.py +27 -0
  158. lmcache/v1/distributed/eviction_policy/lru.py +244 -0
  159. lmcache/v1/distributed/eviction_policy/noop.py +50 -0
  160. lmcache/v1/distributed/internal_api.py +170 -0
  161. lmcache/v1/distributed/l1_manager.py +835 -0
  162. lmcache/v1/distributed/l2_adapters/__init__.py +67 -0
  163. lmcache/v1/distributed/l2_adapters/base.py +360 -0
  164. lmcache/v1/distributed/l2_adapters/config.py +385 -0
  165. lmcache/v1/distributed/l2_adapters/factory.py +205 -0
  166. lmcache/v1/distributed/l2_adapters/fs_l2_adapter.py +747 -0
  167. lmcache/v1/distributed/l2_adapters/fs_native_l2_adapter.py +167 -0
  168. lmcache/v1/distributed/l2_adapters/mock_l2_adapter.py +516 -0
  169. lmcache/v1/distributed/l2_adapters/mooncake_store_l2_adapter.py +135 -0
  170. lmcache/v1/distributed/l2_adapters/native_connector_l2_adapter.py +468 -0
  171. lmcache/v1/distributed/l2_adapters/native_plugin_l2_adapter.py +199 -0
  172. lmcache/v1/distributed/l2_adapters/nixl_store_dynamic_l2_adapter.py +831 -0
  173. lmcache/v1/distributed/l2_adapters/nixl_store_l2_adapter.py +983 -0
  174. lmcache/v1/distributed/l2_adapters/plugin_l2_adapter.py +210 -0
  175. lmcache/v1/distributed/l2_adapters/resp_l2_adapter.py +176 -0
  176. lmcache/v1/distributed/memory_manager.py +179 -0
  177. lmcache/v1/distributed/storage_controller.py +39 -0
  178. lmcache/v1/distributed/storage_controllers/__init__.py +43 -0
  179. lmcache/v1/distributed/storage_controllers/eviction_controller.py +242 -0
  180. lmcache/v1/distributed/storage_controllers/prefetch_controller.py +830 -0
  181. lmcache/v1/distributed/storage_controllers/prefetch_policy.py +193 -0
  182. lmcache/v1/distributed/storage_controllers/store_controller.py +452 -0
  183. lmcache/v1/distributed/storage_controllers/store_policy.py +213 -0
  184. lmcache/v1/distributed/storage_manager.py +532 -0
  185. lmcache/v1/event_manager.py +145 -0
  186. lmcache/v1/exceptions/__init__.py +16 -0
  187. lmcache/v1/gpu_connector/__init__.py +126 -0
  188. lmcache/v1/gpu_connector/gpu_connectors.py +1906 -0
  189. lmcache/v1/gpu_connector/gpu_ops.py +85 -0
  190. lmcache/v1/gpu_connector/hpu_connector.py +326 -0
  191. lmcache/v1/gpu_connector/mock_gpu_connector.py +67 -0
  192. lmcache/v1/gpu_connector/utils.py +890 -0
  193. lmcache/v1/gpu_connector/xpu_connectors.py +916 -0
  194. lmcache/v1/health_monitor/__init__.py +1 -0
  195. lmcache/v1/health_monitor/base.py +587 -0
  196. lmcache/v1/health_monitor/checks/__init__.py +1 -0
  197. lmcache/v1/health_monitor/checks/remote_backend_check.py +304 -0
  198. lmcache/v1/health_monitor/constants.py +36 -0
  199. lmcache/v1/internal_api_server/__init__.py +0 -0
  200. lmcache/v1/internal_api_server/api_registry.py +59 -0
  201. lmcache/v1/internal_api_server/api_server.py +120 -0
  202. lmcache/v1/internal_api_server/common/__init__.py +1 -0
  203. lmcache/v1/internal_api_server/common/env_api.py +22 -0
  204. lmcache/v1/internal_api_server/common/loglevel_api.py +57 -0
  205. lmcache/v1/internal_api_server/common/metrics_api.py +29 -0
  206. lmcache/v1/internal_api_server/common/periodic_thread_api.py +138 -0
  207. lmcache/v1/internal_api_server/common/run_script_api.py +73 -0
  208. lmcache/v1/internal_api_server/common/thread_api.py +63 -0
  209. lmcache/v1/internal_api_server/controller/__init__.py +1 -0
  210. lmcache/v1/internal_api_server/controller/key_stats_api.py +81 -0
  211. lmcache/v1/internal_api_server/controller/worker_info_api.py +136 -0
  212. lmcache/v1/internal_api_server/utils.py +43 -0
  213. lmcache/v1/internal_api_server/vllm/__init__.py +1 -0
  214. lmcache/v1/internal_api_server/vllm/backend_api.py +221 -0
  215. lmcache/v1/internal_api_server/vllm/bypass_api.py +204 -0
  216. lmcache/v1/internal_api_server/vllm/cache_api.py +895 -0
  217. lmcache/v1/internal_api_server/vllm/chunk_statistics_api.py +141 -0
  218. lmcache/v1/internal_api_server/vllm/conf_api.py +147 -0
  219. lmcache/v1/internal_api_server/vllm/freeze_api.py +172 -0
  220. lmcache/v1/internal_api_server/vllm/hot_cache_api.py +184 -0
  221. lmcache/v1/internal_api_server/vllm/inference_api.py +65 -0
  222. lmcache/v1/internal_api_server/vllm/load_fs_chunks_api.py +320 -0
  223. lmcache/v1/internal_api_server/vllm/lookup_api.py +145 -0
  224. lmcache/v1/internal_api_server/vllm/version_api.py +25 -0
  225. lmcache/v1/kv_layer_groups.py +267 -0
  226. lmcache/v1/lazy_memory_allocator.py +284 -0
  227. lmcache/v1/lookup_client/__init__.py +25 -0
  228. lmcache/v1/lookup_client/abstract_client.py +77 -0
  229. lmcache/v1/lookup_client/async_lookup_message.py +50 -0
  230. lmcache/v1/lookup_client/chunk_statistics_lookup_client.py +200 -0
  231. lmcache/v1/lookup_client/factory.py +251 -0
  232. lmcache/v1/lookup_client/hit_limit_lookup_client.py +86 -0
  233. lmcache/v1/lookup_client/lmcache_async_lookup_client.py +407 -0
  234. lmcache/v1/lookup_client/lmcache_lookup_client.py +285 -0
  235. lmcache/v1/lookup_client/lmcache_lookup_client_bypass.py +99 -0
  236. lmcache/v1/lookup_client/mooncake_lookup_client.py +87 -0
  237. lmcache/v1/lookup_client/record_strategies/__init__.py +77 -0
  238. lmcache/v1/lookup_client/record_strategies/base.py +327 -0
  239. lmcache/v1/lookup_client/record_strategies/file_hash.py +130 -0
  240. lmcache/v1/lookup_client/record_strategies/memory_bloom_filter.py +81 -0
  241. lmcache/v1/manager.py +539 -0
  242. lmcache/v1/memory_management.py +2619 -0
  243. lmcache/v1/metadata.py +114 -0
  244. lmcache/v1/mp_observability/AGENTS.override.md +21 -0
  245. lmcache/v1/mp_observability/README.md +204 -0
  246. lmcache/v1/mp_observability/config.py +340 -0
  247. lmcache/v1/mp_observability/event.py +100 -0
  248. lmcache/v1/mp_observability/event_bus.py +313 -0
  249. lmcache/v1/mp_observability/otel_init.py +145 -0
  250. lmcache/v1/mp_observability/subscribers/__init__.py +28 -0
  251. lmcache/v1/mp_observability/subscribers/logging/__init__.py +19 -0
  252. lmcache/v1/mp_observability/subscribers/logging/l1.py +56 -0
  253. lmcache/v1/mp_observability/subscribers/logging/l2.py +73 -0
  254. lmcache/v1/mp_observability/subscribers/logging/lookup_hash.py +209 -0
  255. lmcache/v1/mp_observability/subscribers/logging/mp_server.py +90 -0
  256. lmcache/v1/mp_observability/subscribers/logging/sm.py +59 -0
  257. lmcache/v1/mp_observability/subscribers/metrics/__init__.py +20 -0
  258. lmcache/v1/mp_observability/subscribers/metrics/l0_lifecycle.py +290 -0
  259. lmcache/v1/mp_observability/subscribers/metrics/l1.py +55 -0
  260. lmcache/v1/mp_observability/subscribers/metrics/l1_lifecycle.py +166 -0
  261. lmcache/v1/mp_observability/subscribers/metrics/l2.py +121 -0
  262. lmcache/v1/mp_observability/subscribers/metrics/sm.py +69 -0
  263. lmcache/v1/mp_observability/subscribers/tracing/__init__.py +12 -0
  264. lmcache/v1/mp_observability/subscribers/tracing/mp_server.py +333 -0
  265. lmcache/v1/mp_observability/subscribers/tracing/span_registry.py +148 -0
  266. lmcache/v1/mp_observability/trace/__init__.py +50 -0
  267. lmcache/v1/mp_observability/trace/codecs.py +255 -0
  268. lmcache/v1/mp_observability/trace/decorator.py +147 -0
  269. lmcache/v1/mp_observability/trace/format.py +132 -0
  270. lmcache/v1/mp_observability/trace/lifecycle.py +83 -0
  271. lmcache/v1/mp_observability/trace/reader.py +167 -0
  272. lmcache/v1/mp_observability/trace/recorder.py +300 -0
  273. lmcache/v1/multiprocess/__init__.py +0 -0
  274. lmcache/v1/multiprocess/affinity_pool.py +102 -0
  275. lmcache/v1/multiprocess/blend_server_v2.py +891 -0
  276. lmcache/v1/multiprocess/config.py +253 -0
  277. lmcache/v1/multiprocess/custom_types.py +281 -0
  278. lmcache/v1/multiprocess/futures.py +194 -0
  279. lmcache/v1/multiprocess/gpu_context.py +511 -0
  280. lmcache/v1/multiprocess/http_server.py +235 -0
  281. lmcache/v1/multiprocess/mp_runtime_plugin_launcher.py +130 -0
  282. lmcache/v1/multiprocess/mq.py +732 -0
  283. lmcache/v1/multiprocess/protocol.py +86 -0
  284. lmcache/v1/multiprocess/protocols/README.md +213 -0
  285. lmcache/v1/multiprocess/protocols/__init__.py +127 -0
  286. lmcache/v1/multiprocess/protocols/base.py +89 -0
  287. lmcache/v1/multiprocess/protocols/blend.py +109 -0
  288. lmcache/v1/multiprocess/protocols/blend_v2.py +57 -0
  289. lmcache/v1/multiprocess/protocols/controller.py +53 -0
  290. lmcache/v1/multiprocess/protocols/debug.py +34 -0
  291. lmcache/v1/multiprocess/protocols/engine.py +146 -0
  292. lmcache/v1/multiprocess/protocols/observability.py +39 -0
  293. lmcache/v1/multiprocess/server.py +1134 -0
  294. lmcache/v1/multiprocess/session.py +190 -0
  295. lmcache/v1/multiprocess/token_hasher.py +441 -0
  296. lmcache/v1/offload_server/__init__.py +17 -0
  297. lmcache/v1/offload_server/abstract_server.py +37 -0
  298. lmcache/v1/offload_server/message.py +30 -0
  299. lmcache/v1/offload_server/zmq_server.py +122 -0
  300. lmcache/v1/periodic_thread.py +579 -0
  301. lmcache/v1/pin_monitor.py +246 -0
  302. lmcache/v1/plugin/__init__.py +0 -0
  303. lmcache/v1/plugin/runtime_plugin_launcher.py +211 -0
  304. lmcache/v1/protocol.py +317 -0
  305. lmcache/v1/rpc/__init__.py +17 -0
  306. lmcache/v1/rpc/transport.py +105 -0
  307. lmcache/v1/rpc/zmq_transport.py +213 -0
  308. lmcache/v1/rpc_utils.py +165 -0
  309. lmcache/v1/server/__init__.py +2 -0
  310. lmcache/v1/server/__main__.py +170 -0
  311. lmcache/v1/server/storage_backend/__init__.py +21 -0
  312. lmcache/v1/server/storage_backend/abstract_backend.py +80 -0
  313. lmcache/v1/server/storage_backend/local_backend.py +75 -0
  314. lmcache/v1/server/utils.py +21 -0
  315. lmcache/v1/standalone/__init__.py +1 -0
  316. lmcache/v1/standalone/__main__.py +583 -0
  317. lmcache/v1/standalone/manager.py +80 -0
  318. lmcache/v1/standalone/standalone_service_factory.py +86 -0
  319. lmcache/v1/storage_backend/__init__.py +313 -0
  320. lmcache/v1/storage_backend/abstract_backend.py +445 -0
  321. lmcache/v1/storage_backend/audit_backend.py +233 -0
  322. lmcache/v1/storage_backend/batched_message_sender.py +222 -0
  323. lmcache/v1/storage_backend/cache_policy/__init__.py +45 -0
  324. lmcache/v1/storage_backend/cache_policy/base_policy.py +87 -0
  325. lmcache/v1/storage_backend/cache_policy/fifo.py +58 -0
  326. lmcache/v1/storage_backend/cache_policy/lfu.py +105 -0
  327. lmcache/v1/storage_backend/cache_policy/lru.py +81 -0
  328. lmcache/v1/storage_backend/cache_policy/mru.py +61 -0
  329. lmcache/v1/storage_backend/connector/__init__.py +443 -0
  330. lmcache/v1/storage_backend/connector/audit_adapter.py +77 -0
  331. lmcache/v1/storage_backend/connector/audit_connector.py +320 -0
  332. lmcache/v1/storage_backend/connector/base_connector.py +379 -0
  333. lmcache/v1/storage_backend/connector/blackhole_adapter.py +21 -0
  334. lmcache/v1/storage_backend/connector/blackhole_connector.py +37 -0
  335. lmcache/v1/storage_backend/connector/eic_adapter.py +31 -0
  336. lmcache/v1/storage_backend/connector/eic_connector.py +757 -0
  337. lmcache/v1/storage_backend/connector/external_adapter.py +79 -0
  338. lmcache/v1/storage_backend/connector/fs_adapter.py +51 -0
  339. lmcache/v1/storage_backend/connector/fs_connector.py +403 -0
  340. lmcache/v1/storage_backend/connector/infinistore_adapter.py +56 -0
  341. lmcache/v1/storage_backend/connector/infinistore_connector.py +177 -0
  342. lmcache/v1/storage_backend/connector/instrumented_connector.py +219 -0
  343. lmcache/v1/storage_backend/connector/lm_adapter.py +31 -0
  344. lmcache/v1/storage_backend/connector/lm_connector.py +176 -0
  345. lmcache/v1/storage_backend/connector/mock_adapter.py +57 -0
  346. lmcache/v1/storage_backend/connector/mock_connector.py +349 -0
  347. lmcache/v1/storage_backend/connector/mooncakestore_adapter.py +43 -0
  348. lmcache/v1/storage_backend/connector/mooncakestore_connector.py +614 -0
  349. lmcache/v1/storage_backend/connector/redis_adapter.py +181 -0
  350. lmcache/v1/storage_backend/connector/redis_connector.py +828 -0
  351. lmcache/v1/storage_backend/connector/s3_adapter.py +59 -0
  352. lmcache/v1/storage_backend/connector/s3_connector.py +699 -0
  353. lmcache/v1/storage_backend/connector/sagemaker_hyperpod_adapter.py +233 -0
  354. lmcache/v1/storage_backend/connector/sagemaker_hyperpod_connector.py +987 -0
  355. lmcache/v1/storage_backend/connector/valkey_adapter.py +114 -0
  356. lmcache/v1/storage_backend/connector/valkey_connector.py +627 -0
  357. lmcache/v1/storage_backend/gds_backend.py +1199 -0
  358. lmcache/v1/storage_backend/job_executor/__init__.py +0 -0
  359. lmcache/v1/storage_backend/job_executor/base_executor.py +34 -0
  360. lmcache/v1/storage_backend/job_executor/pq_executor.py +235 -0
  361. lmcache/v1/storage_backend/local_cpu_backend.py +810 -0
  362. lmcache/v1/storage_backend/local_disk_backend.py +656 -0
  363. lmcache/v1/storage_backend/maru_backend.py +734 -0
  364. lmcache/v1/storage_backend/naive_serde/__init__.py +50 -0
  365. lmcache/v1/storage_backend/naive_serde/cachegen_basics.py +133 -0
  366. lmcache/v1/storage_backend/naive_serde/cachegen_decoder.py +135 -0
  367. lmcache/v1/storage_backend/naive_serde/cachegen_encoder.py +83 -0
  368. lmcache/v1/storage_backend/naive_serde/kivi_serde.py +22 -0
  369. lmcache/v1/storage_backend/naive_serde/naive_serde.py +18 -0
  370. lmcache/v1/storage_backend/naive_serde/serde.py +37 -0
  371. lmcache/v1/storage_backend/native_clients/connector_client_base.py +165 -0
  372. lmcache/v1/storage_backend/native_clients/resp_client.py +35 -0
  373. lmcache/v1/storage_backend/nixl_storage_backend.py +1400 -0
  374. lmcache/v1/storage_backend/p2p_backend.py +788 -0
  375. lmcache/v1/storage_backend/path_sharder.py +117 -0
  376. lmcache/v1/storage_backend/pd_backend.py +646 -0
  377. lmcache/v1/storage_backend/plugins/dax_backend.py +1443 -0
  378. lmcache/v1/storage_backend/plugins/rust_raw_block_backend.py +1361 -0
  379. lmcache/v1/storage_backend/remote_backend.py +624 -0
  380. lmcache/v1/storage_backend/resp_client.py +227 -0
  381. lmcache/v1/storage_backend/storage_backend_listener.py +19 -0
  382. lmcache/v1/storage_backend/storage_manager.py +1352 -0
  383. lmcache/v1/system_detection.py +110 -0
  384. lmcache/v1/token_database.py +551 -0
  385. lmcache/v1/transfer_channel/__init__.py +83 -0
  386. lmcache/v1/transfer_channel/abstract.py +285 -0
  387. lmcache/v1/transfer_channel/mock_memory_channel.py +156 -0
  388. lmcache/v1/transfer_channel/nixl_channel.py +639 -0
  389. lmcache/v1/transfer_channel/py_socket_channel.py +260 -0
  390. lmcache/v1/transfer_channel/transfer_utils.py +63 -0
  391. lmcache/v1/utils/__init__.py +1 -0
  392. lmcache/v1/utils/bloom_filter.py +109 -0
  393. lmcache/v1/utils/cache_utils.py +125 -0
  394. lmcache_cli-0.4.5.dev0.dist-info/METADATA +185 -0
  395. lmcache_cli-0.4.5.dev0.dist-info/RECORD +399 -0
  396. lmcache_cli-0.4.5.dev0.dist-info/WHEEL +5 -0
  397. lmcache_cli-0.4.5.dev0.dist-info/entry_points.txt +2 -0
  398. lmcache_cli-0.4.5.dev0.dist-info/licenses/LICENSE +201 -0
  399. lmcache_cli-0.4.5.dev0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,248 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ """
3
+ Defines the data structures that will be used by the
4
+ distributed storage manager public functions
5
+
6
+ Could be implemented by native code in the future
7
+ """
8
+
9
+ # Standard
10
+ from dataclasses import dataclass
11
+
12
+ # Third Party
13
+ import torch
14
+
15
+ # First Party
16
+ from lmcache.logging import init_logger
17
+ from lmcache.v1.multiprocess.custom_types import IPCCacheEngineKey
18
+
19
+ logger = init_logger(__name__)
20
+
21
+
22
+ @dataclass(frozen=True)
23
+ class ObjectKey:
24
+ """
25
+ The unique identifier for an object in the distributed storage manager
26
+ """
27
+
28
+ chunk_hash: bytes
29
+ """ Content hash of this particular chunk """
30
+
31
+ model_name: str
32
+ """ Name of the model this chunk belongs to.
33
+
34
+ Invariant: must not contain ``@``. The L2 adapters use ``@`` as the
35
+ field separator in serialized keys/filenames and rely on this
36
+ invariant for unambiguous parsing. HuggingFace model IDs use
37
+ alphanumerics + ``/-_.`` so this rejects nothing that appears in
38
+ practice.
39
+ """
40
+
41
+ kv_rank: int
42
+ """ The rank that uniquely identifies the slice of the KV cache """
43
+
44
+ cache_salt: str = ""
45
+ """ Per-user isolation salt. Same content from different users with
46
+ different cache_salt values produces different ObjectKeys, giving
47
+ strict per-user cache isolation. Defaults to empty string, in which
48
+ case serialized keys and filenames match the pre-cache_salt shape
49
+ (no trailing salt field) — no migration is needed for un-salted
50
+ deployments.
51
+
52
+ Invariant: must not contain ``@``, ``/``, ``\\``, or NUL. The L2
53
+ adapters use ``@`` as the field separator; ``/`` and ``\\`` are
54
+ filesystem path separators (FS adapter embeds the salt into
55
+ filenames); NUL terminates C strings (C++ connector). Max length
56
+ 128 to stay well within ``NAME_MAX`` (255) after the model, rank,
57
+ hash, and extension are added.
58
+ """
59
+
60
+ _SALT_FORBIDDEN_CHARS = frozenset("@/\\\x00")
61
+ _SALT_MAX_LEN = 128
62
+
63
+ def __post_init__(self) -> None:
64
+ if "@" in self.model_name:
65
+ raise ValueError(
66
+ f"model_name must not contain '@' (got {self.model_name!r})"
67
+ )
68
+ bad = self._SALT_FORBIDDEN_CHARS & set(self.cache_salt)
69
+ if bad:
70
+ raise ValueError(
71
+ f"cache_salt must not contain {bad!r} (got {self.cache_salt!r})"
72
+ )
73
+ if len(self.cache_salt) > self._SALT_MAX_LEN:
74
+ raise ValueError(
75
+ f"cache_salt exceeds max length {self._SALT_MAX_LEN} "
76
+ f"(got {len(self.cache_salt)})"
77
+ )
78
+
79
+ @staticmethod
80
+ def IntHash2Bytes(chunk_hash: int) -> bytes:
81
+ # NOTE: this is only used by tests
82
+ return chunk_hash.to_bytes(4, byteorder="big")
83
+
84
+ @staticmethod
85
+ def Bytes2IntHash(chunk_hash: bytes) -> int:
86
+ # NOTE: this is only used by tests
87
+ return int.from_bytes(chunk_hash, byteorder="big") & ((1 << 64) - 1)
88
+
89
+ @staticmethod
90
+ def ComputeKVRank(
91
+ world_size: int,
92
+ global_rank: int,
93
+ local_world_size: int,
94
+ local_rank: int,
95
+ ) -> int:
96
+ """
97
+ Compute the kv_rank from world_size and worker_id
98
+
99
+ Args:
100
+ world_size (int): The total number of workers (include TP + PP)
101
+ global_rank (int): The global worker id (from 0 to world_size - 1)
102
+ local_world_size (int): The local world size (for local node),
103
+ should NOT be greater than 8
104
+ local_rank (int): The local world rank (for local node)
105
+
106
+ Returns:
107
+ The special KV rank (bitmap) used by the objectkey
108
+
109
+ Example:
110
+ In the case of TP=4, PP=2, the TP worker 1 on node 1 has:
111
+ - world_size = 8
112
+ - global_rank = 5
113
+ - local_world_size = 4
114
+ - local_rank = 1
115
+
116
+ The output KV rank is the bitmap:
117
+ +--head--+
118
+ |00000000|
119
+ |00000000|
120
+ |00000000|
121
+ |00000000| layers
122
+ |00001100|
123
+ |00001100|
124
+ |00001100|
125
+ |00001100|
126
+ +--------+
127
+ """
128
+ # TODO(ApostaC): in the long run, we want to have the above bitmap based
129
+ # representation for asymmetric parallelism (e.g., sharing across different
130
+ # TP/PP settings).
131
+ # For now, let's have a simple implementation that just
132
+ # differentiate between different parallel setups
133
+
134
+ # For each number, we use 8-bit, and pack them together
135
+ return (
136
+ (world_size << 24)
137
+ | (global_rank << 16)
138
+ | (local_world_size << 8)
139
+ | local_rank
140
+ )
141
+
142
+
143
+ @dataclass(frozen=True)
144
+ class MemoryLayoutDesc:
145
+ """
146
+ Describes the layout of a memory object
147
+ """
148
+
149
+ shapes: list[torch.Size]
150
+ dtypes: list[torch.dtype]
151
+
152
+ def __post_init__(self):
153
+ if len(self.shapes) != len(self.dtypes):
154
+ raise ValueError(
155
+ "MemoryLayoutDesc: shapes and dtype must have the same length"
156
+ )
157
+
158
+
159
+ @dataclass(frozen=True)
160
+ class PrefetchHandle:
161
+ """Opaque handle returned by ``StorageManager.submit_prefetch_task``.
162
+
163
+ Carries the bookkeeping needed to later query lookup / prefetch status
164
+ without exposing controller internals.
165
+ """
166
+
167
+ prefetch_request_id: int
168
+ """Opaque ID for tracking L2 prefetch in the controller.
169
+ -1 if no L2 request was submitted."""
170
+
171
+ external_request_id: str
172
+ """Request ID from the caller for end-to-end tracing."""
173
+
174
+ l1_prefix_hit_count: int
175
+ """Number of leading keys already in L1 at submission time."""
176
+
177
+ total_requested_keys: int
178
+ """Total number of keys originally requested."""
179
+
180
+ submit_time: float
181
+ """Monotonic timestamp when the prefetch task was submitted."""
182
+
183
+
184
+ def ipc_key_to_object_keys(
185
+ ipc_key: IPCCacheEngineKey,
186
+ chunk_hashes: list[bytes],
187
+ ) -> list[ObjectKey]:
188
+ """
189
+ Convert a single IPCCacheEngineKey and its chunk hashes to a list of ObjectKey.
190
+
191
+ When the ipc_key's worker_id is None, each chunk hash is exploded into
192
+ multiple ObjectKeys (one per worker in world_size).
193
+
194
+ ``cache_salt`` is read directly from ``ipc_key`` so the produced
195
+ ObjectKeys are per-user isolated whenever the sender set a non-empty
196
+ salt. There is intentionally no separate ``cache_salt`` parameter —
197
+ duplicating the source of truth would risk silent isolation bugs
198
+ where a caller passes ``ipc_key`` but forgets the salt.
199
+
200
+ Args:
201
+ ipc_key: The IPC key providing model_name, world_size, worker_id,
202
+ and cache_salt.
203
+ chunk_hashes: List of chunk hash bytes, one per chunk.
204
+
205
+ Returns:
206
+ list[ObjectKey]: The converted list of ObjectKey.
207
+ """
208
+ cache_salt = ipc_key.cache_salt
209
+ storage_keys = []
210
+ for chunk_hash in chunk_hashes:
211
+ if ipc_key.worker_id is None:
212
+ # For look up request, we want to expand to all workers
213
+ for worker_id in range(ipc_key.world_size):
214
+ # TODO (ApostaC): include local world size/rank info
215
+ # in the future once it's in IPCCacheEngineKey
216
+ kv_rank = ObjectKey.ComputeKVRank(
217
+ world_size=ipc_key.world_size,
218
+ global_rank=worker_id,
219
+ local_world_size=ipc_key.world_size,
220
+ local_rank=worker_id,
221
+ )
222
+
223
+ storage_keys.append(
224
+ ObjectKey(
225
+ chunk_hash=chunk_hash,
226
+ model_name=ipc_key.model_name,
227
+ kv_rank=kv_rank,
228
+ cache_salt=cache_salt,
229
+ )
230
+ )
231
+ else:
232
+ kv_rank = ObjectKey.ComputeKVRank(
233
+ world_size=ipc_key.world_size,
234
+ global_rank=ipc_key.worker_id,
235
+ local_world_size=ipc_key.world_size,
236
+ local_rank=ipc_key.worker_id,
237
+ )
238
+
239
+ storage_keys.append(
240
+ ObjectKey(
241
+ chunk_hash=chunk_hash,
242
+ model_name=ipc_key.model_name,
243
+ kv_rank=kv_rank,
244
+ cache_salt=cache_salt,
245
+ )
246
+ )
247
+
248
+ return storage_keys
@@ -0,0 +1,321 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+
3
+ """
4
+ Configuration for distributed storage manager
5
+ """
6
+
7
+ # Standard
8
+ from dataclasses import dataclass, field
9
+ from typing import Literal
10
+ import argparse
11
+
12
+ # First Party
13
+ from lmcache.v1.distributed.l2_adapters.config import (
14
+ L2AdaptersConfig,
15
+ add_l2_adapters_args,
16
+ parse_args_to_l2_adapters_config,
17
+ )
18
+
19
+
20
+ @dataclass
21
+ class L1MemoryManagerConfig:
22
+ """
23
+ The configuration for L1 memory manager.
24
+ """
25
+
26
+ size_in_bytes: int
27
+ """ The size of L1 memory in bytes. """
28
+
29
+ use_lazy: bool
30
+ """ Whether to use lazy initialization for L1 memory. """
31
+
32
+ init_size_in_bytes: int = field(default=20 << 30)
33
+ """ The initial size when using lazy allocation. Default is 20GB. """
34
+
35
+ align_bytes: int = field(default=0x1000)
36
+ """ The alignment size in bytes. Default is 4KB. """
37
+
38
+ def __post_init__(self):
39
+ self.init_size_in_bytes = min(self.init_size_in_bytes, self.size_in_bytes)
40
+
41
+
42
+ @dataclass
43
+ class L1ManagerConfig:
44
+ """
45
+ Special config for the L1 Object/Key manager
46
+ """
47
+
48
+ memory_config: L1MemoryManagerConfig
49
+ """ The memory manager configuration for L1 cache. """
50
+
51
+ write_ttl_seconds: int = field(default=600)
52
+ """ Time to live for each object's write lock. Default is 600s (10 minutes). """
53
+
54
+ read_ttl_seconds: int = field(default=300)
55
+ """ Time to live for each object's read lock. Default is 300s (5 minutes). """
56
+
57
+
58
+ @dataclass
59
+ class EvictionConfig:
60
+ """
61
+ The configuration for eviction policies (L1 and optionally L2).
62
+ """
63
+
64
+ eviction_policy: Literal["LRU", "noop"]
65
+ """ The eviction policy to use. """
66
+
67
+ trigger_watermark: float = field(default=0.8)
68
+ """ The memory usage watermark to trigger eviction (0.0 to 1.0). """
69
+
70
+ eviction_ratio: float = field(default=0.2)
71
+ """ The fraction of *allocated* memory to evict when triggered (0.0 to 1.0). """
72
+
73
+
74
+ @dataclass
75
+ class StorageManagerConfig:
76
+ """
77
+ The configuration for the distributed storage manager.
78
+ """
79
+
80
+ l1_manager_config: L1ManagerConfig
81
+ """ The configuration for the L1 manager. """
82
+
83
+ eviction_config: EvictionConfig
84
+ """ The configuration for eviction policies. """
85
+
86
+ l2_adapter_config: L2AdaptersConfig = field(
87
+ default_factory=lambda: L2AdaptersConfig([])
88
+ )
89
+ """ The configuration for L2 adapters. """
90
+
91
+ store_policy: str = "default"
92
+ """ The L2 store policy name. """
93
+
94
+ prefetch_policy: str = "default"
95
+ """ The L2 prefetch policy name. """
96
+
97
+ prefetch_max_in_flight: int = 8
98
+ """ Maximum number of concurrent prefetch requests. """
99
+
100
+
101
+ def add_storage_manager_args(
102
+ parser: argparse.ArgumentParser,
103
+ ) -> argparse.ArgumentParser:
104
+ """
105
+ Add storage manager configuration arguments to an existing parser.
106
+
107
+ This function allows other modules to integrate storage manager arguments
108
+ into their own argument parsers. Arguments are organized into groups to
109
+ avoid naming conflicts with other modules.
110
+
111
+ Args:
112
+ parser: The argument parser to add arguments to.
113
+
114
+ Returns:
115
+ argparse.ArgumentParser: The same parser with storage manager
116
+ arguments added.
117
+
118
+ Example:
119
+ >>> # In another module that needs its own arguments
120
+ >>> parser = argparse.ArgumentParser(description="My Application")
121
+ >>> parser.add_argument("--my-arg", type=str)
122
+ >>> add_storage_manager_args(parser)
123
+ >>> args = parser.parse_args()
124
+ >>> config = parse_args_to_config(args)
125
+ """
126
+ # L1 Memory Manager Config
127
+ memory_group = parser.add_argument_group(
128
+ "L1 Memory Manager", "Configuration for L1 memory manager"
129
+ )
130
+ memory_group.add_argument(
131
+ "--l1-size-gb",
132
+ type=float,
133
+ required=True,
134
+ help="The size of L1 memory in GB.",
135
+ )
136
+ memory_group.add_argument(
137
+ "--l1-use-lazy",
138
+ action=argparse.BooleanOptionalAction,
139
+ default=True,
140
+ help="Whether to use lazy loading for L1 memory. (Default is True)",
141
+ )
142
+ memory_group.add_argument(
143
+ "--l1-init-size-gb",
144
+ type=int,
145
+ default=20,
146
+ help="The initial size (GB) when using lazy allocation. Default is 20.",
147
+ )
148
+ memory_group.add_argument(
149
+ "--l1-align-bytes",
150
+ type=int,
151
+ default=4096,
152
+ help="The alignment size in bytes. Default is 4KB (4096 bytes).",
153
+ )
154
+
155
+ # L1 Manager Config (TTL settings)
156
+ ttl_group = parser.add_argument_group(
157
+ "L1 Manager TTL", "TTL configuration for L1 manager locks"
158
+ )
159
+ ttl_group.add_argument(
160
+ "--l1-write-ttl-seconds",
161
+ type=int,
162
+ default=600,
163
+ help="Time to live for each object's write lock. Default is 600s.",
164
+ )
165
+ ttl_group.add_argument(
166
+ "--l1-read-ttl-seconds",
167
+ type=int,
168
+ default=300,
169
+ help="Time to live for each object's read lock. Default is 300s.",
170
+ )
171
+
172
+ # Eviction Config
173
+ eviction_group = parser.add_argument_group(
174
+ "Eviction Policy", "Configuration for eviction policies"
175
+ )
176
+ eviction_group.add_argument(
177
+ "--eviction-policy",
178
+ type=str,
179
+ choices=["LRU", "noop"],
180
+ required=True,
181
+ help="The eviction policy to use ('LRU' or 'noop').",
182
+ )
183
+ eviction_group.add_argument(
184
+ "--eviction-trigger-watermark",
185
+ type=float,
186
+ default=0.8,
187
+ help="The memory usage watermark to trigger eviction (0.0 to 1.0). "
188
+ "Default is 0.8.",
189
+ )
190
+ eviction_group.add_argument(
191
+ "--eviction-ratio",
192
+ type=float,
193
+ default=0.2,
194
+ help="The fraction of memory to evict when triggered (0.0 to 1.0). "
195
+ "Default is 0.2.",
196
+ )
197
+
198
+ # L2 Policies
199
+ # Import here to break circular dependency:
200
+ # config.py <-> storage_controllers (via eviction_controller)
201
+ # Safe because config.py is fully initialized by the time this
202
+ # function is called.
203
+ # First Party
204
+ from lmcache.v1.distributed.storage_controllers.prefetch_policy import (
205
+ get_registered_prefetch_policies,
206
+ )
207
+ from lmcache.v1.distributed.storage_controllers.store_policy import (
208
+ get_registered_store_policies,
209
+ )
210
+ import lmcache.v1.distributed.storage_controllers # noqa: F401
211
+
212
+ policy_group = parser.add_argument_group(
213
+ "L2 Policies", "Store and prefetch policy selection for L2 adapters"
214
+ )
215
+ policy_group.add_argument(
216
+ "--l2-store-policy",
217
+ type=str,
218
+ choices=get_registered_store_policies(),
219
+ default="default",
220
+ help="L2 store policy. Determines which adapters receive each key "
221
+ "and whether keys are deleted from L1 after L2 store. "
222
+ "Default is 'default' (store all keys to all adapters, keep L1).",
223
+ )
224
+ policy_group.add_argument(
225
+ "--l2-prefetch-policy",
226
+ type=str,
227
+ choices=get_registered_prefetch_policies(),
228
+ default="default",
229
+ help="L2 prefetch policy. Determines which adapter loads each key "
230
+ "when multiple adapters have it. "
231
+ "Default is 'default' (pick the first adapter by index).",
232
+ )
233
+ policy_group.add_argument(
234
+ "--l2-prefetch-max-in-flight",
235
+ type=int,
236
+ default=8,
237
+ help="Maximum number of concurrent prefetch requests. Default is 8.",
238
+ )
239
+
240
+ # Adapter config
241
+ add_l2_adapters_args(parser)
242
+ return parser
243
+
244
+
245
+ def get_arg_parser() -> argparse.ArgumentParser:
246
+ """
247
+ Get a standalone argument parser for storage manager configuration.
248
+
249
+ This creates a new parser with only storage manager arguments.
250
+ For integrating with other modules' parsers, use add_storage_manager_args()
251
+ instead.
252
+
253
+ Returns:
254
+ argparse.ArgumentParser: The argument parser with all storage manager
255
+ configuration options.
256
+ """
257
+ parser = argparse.ArgumentParser(
258
+ description="Distributed Storage Manager Configuration"
259
+ )
260
+ return add_storage_manager_args(parser)
261
+
262
+
263
+ def parse_args_to_config(
264
+ args: argparse.Namespace,
265
+ ) -> StorageManagerConfig:
266
+ """
267
+ Convert parsed command line arguments to a StorageManagerConfig.
268
+
269
+ Args:
270
+ args: Parsed arguments from the argument parser.
271
+
272
+ Returns:
273
+ StorageManagerConfig: The configuration object.
274
+ """
275
+ memory_config = L1MemoryManagerConfig(
276
+ size_in_bytes=int(args.l1_size_gb * (1 << 30)),
277
+ use_lazy=args.l1_use_lazy,
278
+ init_size_in_bytes=int(args.l1_init_size_gb * (1 << 30)),
279
+ align_bytes=args.l1_align_bytes,
280
+ )
281
+
282
+ l1_manager_config = L1ManagerConfig(
283
+ memory_config=memory_config,
284
+ write_ttl_seconds=args.l1_write_ttl_seconds,
285
+ read_ttl_seconds=args.l1_read_ttl_seconds,
286
+ )
287
+
288
+ eviction_config = EvictionConfig(
289
+ eviction_policy=args.eviction_policy,
290
+ trigger_watermark=args.eviction_trigger_watermark,
291
+ eviction_ratio=args.eviction_ratio,
292
+ )
293
+
294
+ l2_adapter_config = parse_args_to_l2_adapters_config(args)
295
+
296
+ return StorageManagerConfig(
297
+ l1_manager_config=l1_manager_config,
298
+ eviction_config=eviction_config,
299
+ l2_adapter_config=l2_adapter_config,
300
+ store_policy=args.l2_store_policy,
301
+ prefetch_policy=args.l2_prefetch_policy,
302
+ prefetch_max_in_flight=args.l2_prefetch_max_in_flight,
303
+ )
304
+
305
+
306
+ def parse_args(args: list[str] | None = None) -> StorageManagerConfig:
307
+ """
308
+ Parse command line arguments and return a StorageManagerConfig.
309
+
310
+ This is a convenience function that combines get_arg_parser() and
311
+ parse_args_to_config().
312
+
313
+ Args:
314
+ args: Optional list of arguments to parse. If None, uses sys.argv.
315
+
316
+ Returns:
317
+ StorageManagerConfig: The configuration object.
318
+ """
319
+ parser = get_arg_parser()
320
+ parsed_args = parser.parse_args(args)
321
+ return parse_args_to_config(parsed_args)
@@ -0,0 +1,64 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+
3
+ """
4
+ Definition of errors for class APIs.
5
+ """
6
+
7
+ # Standard
8
+ import enum
9
+
10
+
11
+ class L1Error(enum.Enum):
12
+ """Errors for L1Manager class APIs."""
13
+
14
+ SUCCESS = enum.auto()
15
+ """ Operation succeeded. """
16
+
17
+ KEY_NOT_EXIST = enum.auto()
18
+ """ The specified key does not exist. """
19
+
20
+ KEY_NOT_READABLE = enum.auto()
21
+ """ The specified key exists but cannot be read """
22
+
23
+ KEY_NOT_WRITABLE = enum.auto()
24
+ """ The specified key exists but cannot be written """
25
+
26
+ KEY_IN_WRONG_STATE = enum.auto()
27
+ """ The specified key is in the wrong state for the operation. """
28
+
29
+ KEY_IS_LOCKED = enum.auto()
30
+ """ The specified key is locked and cannot perform the operation. """
31
+
32
+ OUT_OF_MEMORY = enum.auto()
33
+ """ Not enough memory to complete the operation. """
34
+
35
+
36
+ ErrorType = L1Error
37
+
38
+
39
+ def strerror(error: ErrorType) -> str:
40
+ """Convert error code to human-readable string.
41
+
42
+ Args:
43
+ error (ErrorType): The error code.
44
+
45
+ Returns:
46
+ str: The human-readable string.
47
+ """
48
+ if isinstance(error, L1Error):
49
+ if error == L1Error.SUCCESS:
50
+ return "Operation succeeded."
51
+ elif error == L1Error.KEY_NOT_EXIST:
52
+ return "The specified key does not exist."
53
+ elif error == L1Error.KEY_NOT_READABLE:
54
+ return "The specified key exists but cannot be read."
55
+ elif error == L1Error.KEY_NOT_WRITABLE:
56
+ return "The specified key exists but cannot be written."
57
+ elif error == L1Error.KEY_IN_WRONG_STATE:
58
+ return "The specified key is in the wrong state for the operation."
59
+ elif error == L1Error.KEY_IS_LOCKED:
60
+ return "The specified key is locked and cannot perform the operation."
61
+ elif error == L1Error.OUT_OF_MEMORY:
62
+ return "Not enough memory to complete the operation."
63
+
64
+ return "Unknown error."