Skip to content

fix(kvblock): stop Lookup at first prefix-chain break#688

Open
Iceber wants to merge 1 commit into
llm-d:mainfrom
Iceber:fix-kvblock
Open

fix(kvblock): stop Lookup at first prefix-chain break#688
Iceber wants to merge 1 commit into
llm-d:mainfrom
Iceber:fix-kvblock

Conversation

@Iceber

@Iceber Iceber commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Changes

  • Stop Index.Lookup at the first break in the prefix chain for InMemoryIndex and CostAwareMemoryIndex.
  • Treat a missing key, an empty pod cache, or a pod filter with no matches as a chain break.
  • Add shared coverage for missing-key and filtered-miss cases, and adjust eviction tests to check surviving keys directly.

Why

KV-cache hits are only useful while the prefix is continuous. If a block in the middle of the chain is missing, later blocks cannot be used even if they still exist in the index.

The previous in-memory lookup behavior skipped over gaps and kept scanning the rest of requestKeys. That could overstate a pod's cache locality and give it a higher score than it should receive.

For example:

block 0: pod-target
block 1: pod-other     # pod-target has no hit here, so its chain stops
block 2: pod-target    # not usable without block 1

Before this change, a lookup filtered to pod-target could still return block 2. After this change, lookup returns only the continuous prefix up to block 0, matching the prefix-cache semantics and the Redis-backed index behavior.

Signed-off-by: Iceber Gu <caiwei95@hotmail.com>
Copilot AI review requested due to automatic review settings June 29, 2026 09:36
@github-actions github-actions Bot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Jun 29, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aligns the in-memory KV-block index lookup behavior with prefix-cache semantics (and the Redis-backed index) by stopping lookup at the first “prefix-chain break”, preventing later blocks from being counted as usable cache hits when an earlier block is missing or filtered out.

Changes:

  • Update InMemoryIndex.Lookup and CostAwareMemoryIndex.Lookup to stop scanning at the first missing/empty/filtered-miss key in the request-key chain.
  • Treat “no matching pods after filtering” as a chain break (early stop) in both in-memory implementations.
  • Adjust eviction-related tests to avoid relying on multi-key lookup behavior that now early-stops.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
pkg/kvcache/kvblock/in_memory.go Early-stop lookup on missing keys and filtered-miss to enforce continuous-prefix semantics.
pkg/kvcache/kvblock/in_memory_test.go Update eviction test to lookup surviving keys directly (avoid prefix-chain early-stop dependency).
pkg/kvcache/kvblock/cost_aware_memory.go Mirror early-stop prefix behavior in cost-aware in-memory lookup implementation.
pkg/kvcache/kvblock/cost_aware_memory_test.go Adjust cost-aware eviction test to avoid multi-key lookup semantics impacted by early-stop.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 149 to 152
} else {
traceLogger.Info("key not found in index", "key", requestKey)
return podsPerKey, nil // early stop since prefix-chain breaks here
}
Comment on lines 326 to 329
} else {
traceLogger.Info("key not found in index", "key", key)
return podsPerKey, nil // early stop since prefix-chain breaks here
}
Comment on lines +78 to 83
// Lookup the surviving key directly so this test verifies cost-based
// eviction without depending on prefix-chain early-stop semantics.
podsPerKey, err := index.Lookup(ctx, []BlockHash{requestKey3}, nil)
require.NoError(t, err)

assert.Len(t, podsPerKey, 1) // Only requestKey3 should be present
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/M Denotes a PR that changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants