Summary
Lock-free join and periodic backpointer repair (Aspnes & Shah, arXiv:cs/0306043 — Algorithm 2 for insert/join, Algorithm 8 for self-stabilizing backpointer repair) both need two read-only queries the current RPC surface does not provide:
- GetMaxLevel — returns the highest level at which the queried node holds a neighbor (the height of its tower). A joining or repairing node uses this to know how many levels it must consider when splicing itself in.
- GetLink — returns the neighbor the queried node currently holds at a given
(level, direction), as a single direction-parameterized read. Order-verification during a join and the repair sweep use it to inspect a peer's current view of one link.
These are distinct from the existing GetLeftNode/GetRightNode neighbor lookups, which re-resolve the neighbor's live identity via an extra hop and are suppressed while a node is mid-insertion. GetLink is a direct read of the stored link and is not a re-add of that neighbor lookup.
This issue delivers only the read-query transport: the request types, packet classes, MiddleLayer dispatch, client senders, and thin read handlers. No join or repair orchestration is wired here.
Scope
src/main/java/underlay/packets/RequestType.java — add GetMaxLevel and GetLink enum entries.
src/main/java/underlay/packets/requests/ — add GetMaxLevelRequest (no payload beyond the inherited receiver routing) and GetLinkRequest (carries level and a direction discriminator, consistent with the existing lookup-table Direction / findLadder usage).
src/main/java/underlay/packets/responses/ — add one small response carrying an integer level (e.g. LevelResponse) for GetMaxLevel, since no existing response carries an int; reuse IdentityResponse for GetLink.
src/main/java/middlelayer/MiddleLayer.java — add a receive() dispatch case for each new type and a matching client sender, following existing conventions (receiverId routing, locked-response gating).
src/main/java/skipnode/SkipNodeInterface.java, src/main/java/skipnode/SkipNode.java — add thin read handlers (highest populated level; stored neighbor at a level+direction) backed by the existing lookup table. No changes to insert() or the join path.
Acceptance Criteria
Dependencies
None. This is foundational plumbing: the lock-free join orchestration (Algorithm 2) and the periodic backpointer-repair sweep (Algorithm 8) that consume these queries land in separate issues and are out of scope here.
Part of #33. Depends on: none — ready to start
Summary
Lock-free join and periodic backpointer repair (Aspnes & Shah, arXiv:cs/0306043 — Algorithm 2 for insert/join, Algorithm 8 for self-stabilizing backpointer repair) both need two read-only queries the current RPC surface does not provide:
(level, direction), as a single direction-parameterized read. Order-verification during a join and the repair sweep use it to inspect a peer's current view of one link.These are distinct from the existing
GetLeftNode/GetRightNodeneighbor lookups, which re-resolve the neighbor's live identity via an extra hop and are suppressed while a node is mid-insertion.GetLinkis a direct read of the stored link and is not a re-add of that neighbor lookup.This issue delivers only the read-query transport: the request types, packet classes,
MiddleLayerdispatch, client senders, and thin read handlers. No join or repair orchestration is wired here.Scope
src/main/java/underlay/packets/RequestType.java— addGetMaxLevelandGetLinkenum entries.src/main/java/underlay/packets/requests/— addGetMaxLevelRequest(no payload beyond the inherited receiver routing) andGetLinkRequest(carriesleveland adirectiondiscriminator, consistent with the existing lookup-tableDirection/findLadderusage).src/main/java/underlay/packets/responses/— add one small response carrying an integer level (e.g.LevelResponse) forGetMaxLevel, since no existing response carries an int; reuseIdentityResponseforGetLink.src/main/java/middlelayer/MiddleLayer.java— add areceive()dispatch case for each new type and a matching client sender, following existing conventions (receiverIdrouting, locked-response gating).src/main/java/skipnode/SkipNodeInterface.java,src/main/java/skipnode/SkipNode.java— add thin read handlers (highest populated level; stored neighbor at alevel+direction) backed by the existing lookup table. No changes toinsert()or the join path.Acceptance Criteria
RequestTypehasGetMaxLevelandGetLink; each has a request class underrequests/and maps to a response type — a new integer-level response forGetMaxLevel, reusedIdentityResponseforGetLink.MiddleLayer.receive()dispatches both new types, andMiddleLayerexposes a client sender for each, matching the existing sender/dispatch conventions.GetMaxLevelreturns the highest level at which the target holds a neighbor;GetLinkreturns the target's stored neighbor at the requested(level, direction), or the empty node when absent.make testandmake lintpass. Total change including the test stays within roughly 200 lines.Dependencies
None. This is foundational plumbing: the lock-free join orchestration (Algorithm 2) and the periodic backpointer-repair sweep (Algorithm 8) that consume these queries land in separate issues and are out of scope here.
Part of #33. Depends on: none — ready to start