Skip to content

[Protocol] Add GetMaxLevel and GetLink query RPCs #35

Description

@thep2p

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

  • RequestType has GetMaxLevel and GetLink; each has a request class under requests/ and maps to a response type — a new integer-level response for GetMaxLevel, reused IdentityResponse for GetLink.
  • MiddleLayer.receive() dispatches both new types, and MiddleLayer exposes a client sender for each, matching the existing sender/dispatch conventions.
  • GetMaxLevel returns the highest level at which the target holds a neighbor; GetLink returns the target's stored neighbor at the requested (level, direction), or the empty node when absent.
  • Handlers are read-only: no lookup-table writes, no new table primitive, no changes to insertion/join.
  • New public types and methods carry Javadoc (checkstyle clean).
  • A test sends both requests end-to-end between two nodes over the mock underlay and asserts the returned level and neighbor identity. make test and make lint pass. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions