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,439 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Standard
3
+ from typing import TYPE_CHECKING, Any
4
+
5
+ # First Party
6
+ from lmcache.logging import init_logger
7
+ from lmcache.v1.cache_controller.controllers.full_sync_tracker import FullSyncTracker
8
+ from lmcache.v1.cache_controller.message import (
9
+ BatchedKVOperationMsg,
10
+ BatchedP2PLookupMsg,
11
+ BatchedP2PLookupRetMsg,
12
+ CheckFinishMsg,
13
+ CheckFinishRetMsg,
14
+ ClearMsg,
15
+ ClearRetMsg,
16
+ CompressMsg,
17
+ CompressRetMsg,
18
+ DecompressMsg,
19
+ DecompressRetMsg,
20
+ FullSyncBatchMsg,
21
+ FullSyncEndMsg,
22
+ FullSyncStartMsg,
23
+ FullSyncStartRetMsg,
24
+ FullSyncStatusMsg,
25
+ FullSyncStatusRetMsg,
26
+ KVOpEvent,
27
+ LookupMsg,
28
+ LookupRetMsg,
29
+ MoveMsg,
30
+ MoveRetMsg,
31
+ OpType,
32
+ PinMsg,
33
+ PinRetMsg,
34
+ )
35
+ from lmcache.v1.cache_controller.observability import PrometheusLogger
36
+ from lmcache.v1.cache_controller.utils import RegistryTree
37
+ from lmcache.v1.token_database import ChunkedTokenDatabase
38
+
39
+ if TYPE_CHECKING:
40
+ # First Party
41
+ from lmcache.v1.cache_controller.controllers import RegistrationController
42
+
43
+ logger = init_logger(__name__)
44
+
45
+
46
+ """
47
+ The kv controller use `(instance_id, worker_id)` -> [location -> set[chunk_hash]]
48
+ as kv_pool. When the the number of instance is small and stable, the time complexity
49
+ of `lookup` in kv controller is O(n). If the number of instance is large or unknown,
50
+ the time complexity will degrade to O(n^2), and the ReverseIndexKVController is a
51
+ better choice.
52
+ """
53
+
54
+
55
+ class KVController:
56
+ def __init__(
57
+ self,
58
+ registry: RegistryTree,
59
+ full_sync_completion_threshold: float = 0.8,
60
+ full_sync_timeout_s: float = 300.0,
61
+ ) -> None:
62
+ # TODO(Jiayi): remove this hardcode
63
+ self.token_database = ChunkedTokenDatabase()
64
+ self.registry = registry
65
+ self.cluster_executor: Any = None
66
+
67
+ # Full sync tracker
68
+ self.full_sync_tracker = FullSyncTracker(
69
+ registry_tree=registry,
70
+ completion_threshold=full_sync_completion_threshold,
71
+ sync_timeout_s=full_sync_timeout_s,
72
+ )
73
+
74
+ def _setup_metrics(self) -> None:
75
+ prometheus_logger = PrometheusLogger.GetInstanceOrNone()
76
+ if prometheus_logger is not None:
77
+ prometheus_logger.kv_pool_keys_count.set_function(
78
+ self.registry.get_total_kv_count
79
+ )
80
+ prometheus_logger.kv_op_seq_discontinuity_count.set_function(
81
+ self.registry.get_seq_discontinuity_count
82
+ )
83
+ # Full sync metrics
84
+ prometheus_logger.full_sync_workers_syncing.set_function(
85
+ self.full_sync_tracker.get_syncing_count
86
+ )
87
+ prometheus_logger.full_sync_workers_completed.set_function(
88
+ self.full_sync_tracker.get_completed_count
89
+ )
90
+ prometheus_logger.full_sync_global_progress.set_function(
91
+ self.full_sync_tracker.get_global_progress
92
+ )
93
+ prometheus_logger.full_sync_missing_batches_total.set_function(
94
+ self.full_sync_tracker.get_total_missing_batches_count
95
+ )
96
+
97
+ def post_init(
98
+ self, reg_controller: "RegistrationController", cluster_executor: Any
99
+ ) -> None:
100
+ """
101
+ Post initialization of the KV controller.
102
+ """
103
+ self.reg_controller = reg_controller
104
+ self.cluster_executor = cluster_executor
105
+ self._setup_metrics()
106
+
107
+ async def clear(self, msg: ClearMsg) -> ClearRetMsg:
108
+ """
109
+ Clear kv chunks of instance-worker(s).
110
+ """
111
+ assert self.cluster_executor is not None
112
+ return await self.cluster_executor.execute("clear", msg)
113
+
114
+ async def pin(self, msg: PinMsg) -> PinRetMsg:
115
+ """
116
+ Pin kv chunks of instance-worker(s).
117
+ """
118
+ assert self.cluster_executor is not None
119
+ return await self.cluster_executor.execute("pin", msg)
120
+
121
+ async def compress(self, msg: CompressMsg) -> CompressRetMsg:
122
+ """
123
+ Compress kv chunks of instance-worker(s).
124
+ """
125
+ assert self.cluster_executor is not None
126
+ return await self.cluster_executor.execute("compress", msg)
127
+
128
+ async def decompress(self, msg: DecompressMsg) -> DecompressRetMsg:
129
+ """
130
+ Decompress kv chunks of instance-worker(s).
131
+ """
132
+ assert self.cluster_executor is not None
133
+ return await self.cluster_executor.execute("decompress", msg)
134
+
135
+ async def move(self, msg: MoveMsg) -> MoveRetMsg:
136
+ """
137
+ Move kv chunks of instance-worker(s).
138
+ """
139
+ assert self.cluster_executor is not None
140
+ return await self.cluster_executor.execute("move", msg)
141
+
142
+ async def check_finish(self, msg: CheckFinishMsg) -> CheckFinishRetMsg:
143
+ """
144
+ Check if an event is finished.
145
+ """
146
+ assert self.cluster_executor is not None
147
+ return await self.cluster_executor.execute("check_finish", msg)
148
+
149
+ async def handle_batched_kv_operations(self, msg: BatchedKVOperationMsg) -> None:
150
+ """Handle batched KV operations by forwarding to registry."""
151
+ if not msg.operations:
152
+ return
153
+
154
+ # Check if worker is currently in full sync
155
+ if self.full_sync_tracker.is_worker_syncing(msg.instance_id, msg.worker_id):
156
+ # During full sync, incremental operations should be discarded
157
+ logger.debug(
158
+ "Discarding incremental KV operations during full sync: "
159
+ "instance=%s, worker=%d, sync_id=%s, operation_count=%d",
160
+ msg.instance_id,
161
+ msg.worker_id,
162
+ self.full_sync_tracker.get_sync_id(msg.instance_id, msg.worker_id),
163
+ len(msg.operations),
164
+ )
165
+ return
166
+
167
+ if not self.registry.handle_batched_kv_operations(msg):
168
+ logger.warning(
169
+ "Failed to handle batched KV operations, instance: %s, worker: %d",
170
+ msg.instance_id,
171
+ msg.worker_id,
172
+ )
173
+
174
+ # ============= Full Sync Message Handlers =============
175
+
176
+ async def handle_full_sync_start(
177
+ self, msg: FullSyncStartMsg
178
+ ) -> FullSyncStartRetMsg:
179
+ """
180
+ Handle full sync start request from a worker.
181
+
182
+ This is called when a worker wants to start full sync.
183
+ The controller should:
184
+ 1. Clear existing keys for this worker
185
+ 2. Mark the worker as syncing (incremental events will be discarded)
186
+ 3. Return acceptance
187
+ """
188
+ instance_id = msg.instance_id
189
+ worker_id = msg.worker_id
190
+ sync_id = msg.sync_id
191
+ report_id = (instance_id, worker_id)
192
+
193
+ # Start sync tracking first (mark worker as SYNCING)
194
+ success = self.full_sync_tracker.start_sync(
195
+ instance_id=instance_id,
196
+ worker_id=worker_id,
197
+ sync_id=sync_id,
198
+ total_keys=msg.total_keys,
199
+ batch_count=msg.batch_count,
200
+ )
201
+
202
+ if not success:
203
+ logger.warning(
204
+ "Failed to start sync for worker %s: sync_id=%s", report_id, sync_id
205
+ )
206
+ return FullSyncStartRetMsg(
207
+ sync_id=sync_id,
208
+ accepted=False,
209
+ error_msg="Failed to start sync: worker already syncing with "
210
+ "different sync_id or worker not found",
211
+ )
212
+
213
+ # Now clear existing keys for this worker/location using efficient batch method
214
+ # This prevents new incremental messages from being processed while we clear
215
+ existing_keys = self.registry.get_worker_kv_keys(
216
+ instance_id, worker_id, msg.location
217
+ )
218
+ if existing_keys:
219
+ old_count = len(existing_keys)
220
+ # Use efficient batch clear method
221
+ cleared = self.registry.clear_worker_kv(
222
+ instance_id, worker_id, msg.location
223
+ )
224
+ if cleared:
225
+ logger.info(
226
+ "Cleared %d existing keys for worker %s location %s "
227
+ "before full sync",
228
+ old_count,
229
+ report_id,
230
+ msg.location,
231
+ )
232
+ else:
233
+ logger.warning(
234
+ "Failed to clear keys for worker %s location %s",
235
+ report_id,
236
+ msg.location,
237
+ )
238
+
239
+ logger.info(
240
+ "Accepted full sync start: worker=%s, sync_id=%s, "
241
+ "total_keys=%d, batch_count=%d",
242
+ report_id,
243
+ sync_id,
244
+ msg.total_keys,
245
+ msg.batch_count,
246
+ )
247
+ return FullSyncStartRetMsg(sync_id=sync_id, accepted=True)
248
+
249
+ async def handle_full_sync_batch(self, msg: FullSyncBatchMsg) -> None:
250
+ """
251
+ Handle full sync batch message from a worker.
252
+
253
+ This adds the keys from the batch to the registry.
254
+ """
255
+ instance_id = msg.instance_id
256
+ worker_id = msg.worker_id
257
+ location = msg.location
258
+ sync_id = msg.sync_id
259
+ batch_id = msg.batch_id
260
+ keys = msg.keys
261
+ report_id = (instance_id, worker_id)
262
+
263
+ # Record batch receipt
264
+ if not self.full_sync_tracker.receive_batch(
265
+ instance_id=instance_id,
266
+ worker_id=worker_id,
267
+ sync_id=sync_id,
268
+ batch_id=batch_id,
269
+ keys_count=len(keys),
270
+ ):
271
+ logger.warning(
272
+ "Failed to record batch %d for worker %s", batch_id, report_id
273
+ )
274
+ return
275
+
276
+ # Add keys to registry using batched operations
277
+ operations = []
278
+ for seq_num, key in enumerate(keys):
279
+ operations.append(
280
+ KVOpEvent(
281
+ op_type=OpType.ADMIT,
282
+ key=key,
283
+ seq_num=seq_num,
284
+ )
285
+ )
286
+ if operations:
287
+ batch_msg = BatchedKVOperationMsg(
288
+ instance_id=instance_id,
289
+ worker_id=worker_id,
290
+ location=location,
291
+ operations=operations,
292
+ )
293
+ self.registry.handle_batched_kv_operations(batch_msg, is_full_sync=True)
294
+
295
+ current_keys = self.registry.get_worker_kv_keys(
296
+ instance_id, worker_id, location
297
+ )
298
+ logger.debug(
299
+ "Added %d keys from batch %d for worker %s, total now: %d",
300
+ len(keys),
301
+ batch_id,
302
+ report_id,
303
+ len(current_keys),
304
+ )
305
+
306
+ async def handle_full_sync_end(self, msg: FullSyncEndMsg) -> None:
307
+ """
308
+ Handle full sync end message from a worker.
309
+
310
+ This marks the sync as end-received and records actual total keys.
311
+ """
312
+ instance_id = msg.instance_id
313
+ worker_id = msg.worker_id
314
+ sync_id = msg.sync_id
315
+ actual_total_keys = msg.actual_total_keys
316
+ report_id = (instance_id, worker_id)
317
+
318
+ success = self.full_sync_tracker.complete_sync(
319
+ instance_id=instance_id,
320
+ worker_id=worker_id,
321
+ sync_id=sync_id,
322
+ actual_total_keys=actual_total_keys,
323
+ )
324
+
325
+ if success:
326
+ # Verify registry has the expected number of keys
327
+ actual_keys_in_pool = len(
328
+ self.registry.get_worker_kv_keys(instance_id, worker_id, msg.location)
329
+ )
330
+ logger.info(
331
+ "Full sync completed for worker %s: sync_id=%s, "
332
+ "reported_keys=%d, keys_in_pool=%d",
333
+ report_id,
334
+ sync_id,
335
+ actual_total_keys,
336
+ actual_keys_in_pool,
337
+ )
338
+ else:
339
+ logger.warning(
340
+ "Failed to complete full sync for worker %s: sync_id=%s",
341
+ report_id,
342
+ sync_id,
343
+ )
344
+
345
+ async def handle_full_sync_status(
346
+ self, msg: FullSyncStatusMsg
347
+ ) -> FullSyncStatusRetMsg:
348
+ """
349
+ Handle full sync status query from a worker.
350
+
351
+ Returns the sync status including any missing batches that need resending.
352
+ """
353
+ is_complete, global_progress, can_exit_freeze, missing_batches = (
354
+ self.full_sync_tracker.get_sync_status(
355
+ instance_id=msg.instance_id,
356
+ worker_id=msg.worker_id,
357
+ sync_id=msg.sync_id,
358
+ )
359
+ )
360
+
361
+ if missing_batches:
362
+ logger.info(
363
+ "Full sync status query: worker=(%s, %d), sync_id=%s, "
364
+ "is_complete=%s, missing_batches=%s",
365
+ msg.instance_id,
366
+ msg.worker_id,
367
+ msg.sync_id,
368
+ is_complete,
369
+ missing_batches,
370
+ )
371
+
372
+ return FullSyncStatusRetMsg(
373
+ sync_id=msg.sync_id,
374
+ is_complete=is_complete,
375
+ global_progress=global_progress,
376
+ can_exit_freeze=can_exit_freeze,
377
+ missing_batches=missing_batches,
378
+ )
379
+
380
+ # TODO(Jiayi): The current implementation does not handle
381
+ # the case where the prefix chunks are evicted while the
382
+ # suffix chunk is still in the system. LMCache should guarantee
383
+ # this does not happen.
384
+ # TODO(Jiayi): The current implementation does not consider
385
+ # the location of the kv chunks. It simply returns the
386
+ # `instance_id` with longest prefix.
387
+ # TODO(Jiayi): Need to get rid of the hash somehow
388
+ async def lookup(self, msg: LookupMsg) -> LookupRetMsg:
389
+ tokens = msg.tokens
390
+ layout_info = {}
391
+ for start, end, key in self.token_database.process_tokens(
392
+ tokens, make_key=False
393
+ ):
394
+ result = self.registry.find_kv(key)
395
+ if result is None:
396
+ break
397
+ matched_instance = result.instance_id
398
+ matched_location = result.location
399
+ layout_info[matched_instance] = (matched_location, end)
400
+ return LookupRetMsg(layout_info=layout_info, event_id=msg.event_id)
401
+
402
+ # TODO: improve the matching logic, return multi results
403
+ async def batched_p2p_lookup(
404
+ self, msg: BatchedP2PLookupMsg
405
+ ) -> BatchedP2PLookupRetMsg:
406
+ """
407
+ Perform batched P2P lookup for multiple keys.
408
+
409
+ :param BatchedP2PLookupMsg msg: The batched P2P lookup message containing keys.
410
+
411
+ :return: A BatchedP2PLookupRetMsg containing the lookup results.
412
+ """
413
+ hashes = msg.hashes
414
+ if not hashes:
415
+ return BatchedP2PLookupRetMsg(layout_info=[("", "", 0, "")])
416
+
417
+ # Single lookup to get all needed info (optimized path)
418
+ result = self.registry.find_kv_with_worker_info(
419
+ hashes[0], exclude_instance_id=msg.instance_id
420
+ )
421
+ if result is None:
422
+ return BatchedP2PLookupRetMsg(layout_info=[("", "", 0, "")])
423
+
424
+ kv_info, peer_init_url, current_keys = result
425
+ if peer_init_url is None:
426
+ return BatchedP2PLookupRetMsg(layout_info=[("", "", 0, "")])
427
+
428
+ # Count hits efficiently
429
+ num_hit_chunks = 0
430
+ for key in hashes:
431
+ if key not in current_keys:
432
+ break
433
+ num_hit_chunks += 1
434
+
435
+ return BatchedP2PLookupRetMsg(
436
+ layout_info=[
437
+ (kv_info.instance_id, kv_info.location, num_hit_chunks, peer_init_url),
438
+ ]
439
+ )