3232import java .util .concurrent .CompletableFuture ;
3333
3434/**
35- * Implementations and attributes common to all concrete implementations of {@link StorageAdapter}.
35+ * An abstract base class for {@link StorageAdapter} implementations.
36+ * <p>
37+ * This class provides the common infrastructure for managing HNSW graph data within {@link Subspace}.
38+ * It handles the configuration, node creation, and listener management, while delegating the actual
39+ * storage-specific read and write operations to concrete subclasses through the {@code fetchNodeInternal}
40+ * and {@code writeNodeInternal} abstract methods.
41+ *
42+ * @param <N> the type of {@link NodeReference} used to reference nodes in the graph
3643 */
3744abstract class AbstractStorageAdapter <N extends NodeReference > implements StorageAdapter <N > {
3845 @ Nonnull
@@ -51,6 +58,19 @@ abstract class AbstractStorageAdapter<N extends NodeReference> implements Storag
5158
5259 private final Subspace dataSubspace ;
5360
61+ /**
62+ * Constructs a new {@code AbstractStorageAdapter}.
63+ * <p>
64+ * This constructor initializes the adapter with the necessary configuration,
65+ * factories, and listeners for managing an HNSW graph. It also sets up a
66+ * dedicated data subspace within the provided main subspace for storing node data.
67+ *
68+ * @param config the HNSW graph configuration
69+ * @param nodeFactory the factory to create new nodes of type {@code <N>}
70+ * @param subspace the primary subspace for storing all graph-related data
71+ * @param onWriteListener the listener to be called on write operations
72+ * @param onReadListener the listener to be called on read operations
73+ */
5474 protected AbstractStorageAdapter (@ Nonnull final HNSW .Config config , @ Nonnull final NodeFactory <N > nodeFactory ,
5575 @ Nonnull final Subspace subspace ,
5676 @ Nonnull final OnWriteListener onWriteListener ,
@@ -63,55 +83,138 @@ protected AbstractStorageAdapter(@Nonnull final HNSW.Config config, @Nonnull fin
6383 this .dataSubspace = subspace .subspace (Tuple .from (SUBSPACE_PREFIX_DATA ));
6484 }
6585
86+ /**
87+ * Returns the configuration used to build and search this HNSW graph.
88+ *
89+ * @return the current {@link HNSW.Config} object, never {@code null}.
90+ */
6691 @ Override
6792 @ Nonnull
6893 public HNSW .Config getConfig () {
6994 return config ;
7095 }
7196
97+ /**
98+ * Gets the factory responsible for creating new nodes.
99+ * <p>
100+ * This factory is used to instantiate nodes of the generic type {@code N}
101+ * for the current context. The {@code @Nonnull} annotation guarantees that
102+ * this method will never return {@code null}.
103+ *
104+ * @return the non-null {@link NodeFactory} instance.
105+ */
72106 @ Nonnull
73107 @ Override
74108 public NodeFactory <N > getNodeFactory () {
75109 return nodeFactory ;
76110 }
77111
112+ /**
113+ * Gets the kind of this node, which uniquely identifies the type of node.
114+ * <p>
115+ * This method is an override and provides a way to determine the concrete
116+ * type of node without using {@code instanceof} checks.
117+ *
118+ * @return the non-null {@link NodeKind} representing the type of this node.
119+ */
78120 @ Nonnull
79121 @ Override
80122 public NodeKind getNodeKind () {
81123 return getNodeFactory ().getNodeKind ();
82124 }
83125
126+ /**
127+ * Gets the subspace in which this key or value is stored.
128+ * <p>
129+ * This subspace provides a logical separation for keys within the underlying key-value store.
130+ *
131+ * @return the non-null {@link Subspace} for this context
132+ */
84133 @ Override
85134 @ Nonnull
86135 public Subspace getSubspace () {
87136 return subspace ;
88137 }
89138
139+ /**
140+ * Gets the subspace for the data associated with this component.
141+ * <p>
142+ * The data subspace defines the portion of the directory space where the data
143+ * for this component is stored.
144+ *
145+ * @return the non-null {@link Subspace} for the data
146+ */
90147 @ Override
91148 @ Nonnull
92149 public Subspace getDataSubspace () {
93150 return dataSubspace ;
94151 }
95152
153+ /**
154+ * Returns the listener that is notified upon write events.
155+ * <p>
156+ * This method is an override and guarantees a non-null return value,
157+ * as indicated by the {@code @Nonnull} annotation.
158+ *
159+ * @return the configured {@link OnWriteListener} instance; will never be {@code null}.
160+ */
96161 @ Override
97162 @ Nonnull
98163 public OnWriteListener getOnWriteListener () {
99164 return onWriteListener ;
100165 }
101166
167+ /**
168+ * Gets the listener that is notified upon completion of a read operation.
169+ * <p>
170+ * This method is an override and provides the currently configured listener instance.
171+ * The returned listener is guaranteed to be non-null as indicated by the
172+ * {@code @Nonnull} annotation.
173+ *
174+ * @return the non-null {@link OnReadListener} instance.
175+ */
102176 @ Override
103177 @ Nonnull
104178 public OnReadListener getOnReadListener () {
105179 return onReadListener ;
106180 }
107181
182+ /**
183+ * Asynchronously fetches a node from a specific layer of the HNSW.
184+ * <p>
185+ * The node is identified by its {@code layer} and {@code primaryKey}. The entire fetch operation is
186+ * performed within the given {@link ReadTransaction}. After the underlying
187+ * fetch operation completes, the retrieved node is validated by the
188+ * {@link #checkNode(Node)} method before the returned future is completed.
189+ *
190+ * @param readTransaction the non-null transaction to use for the read operation
191+ * @param layer the layer of the tree from which to fetch the node
192+ * @param primaryKey the non-null primary key that identifies the node to fetch
193+ *
194+ * @return a {@link CompletableFuture} that will complete with the fetched {@link Node}
195+ * once it has been read from storage and validated
196+ */
108197 @ Nonnull
109198 @ Override
110199 public CompletableFuture <Node <N >> fetchNode (@ Nonnull final ReadTransaction readTransaction ,
111200 int layer , @ Nonnull Tuple primaryKey ) {
112201 return fetchNodeInternal (readTransaction , layer , primaryKey ).thenApply (this ::checkNode );
113202 }
114203
204+ /**
205+ * Asynchronously fetches a specific node from the data store for a given layer and primary key.
206+ * <p>
207+ * This is an internal, abstract method that concrete subclasses must implement to define
208+ * the storage-specific logic for retrieving a node. The operation is performed within the
209+ * context of the provided {@link ReadTransaction}.
210+ *
211+ * @param readTransaction the transaction to use for the read operation; must not be {@code null}
212+ * @param layer the layer index from which to fetch the node
213+ * @param primaryKey the primary key that uniquely identifies the node to be fetched; must not be {@code null}
214+ *
215+ * @return a {@link CompletableFuture} that will be completed with the fetched {@link Node}.
216+ * The future will complete with {@code null} if no node is found for the given key and layer.
217+ */
115218 @ Nonnull
116219 protected abstract CompletableFuture <Node <N >> fetchNodeInternal (@ Nonnull ReadTransaction readTransaction ,
117220 int layer , @ Nonnull Tuple primaryKey );
@@ -129,6 +232,21 @@ private Node<N> checkNode(@Nullable final Node<N> node) {
129232 return node ;
130233 }
131234
235+ /**
236+ * Writes a given node and its neighbor modifications to the underlying storage.
237+ * <p>
238+ * This operation is executed within the context of the provided {@link Transaction}.
239+ * It handles persisting the node's data at a specific {@code layer} and applies
240+ * the changes to its neighbors as defined in the {@link NeighborsChangeSet}.
241+ * This method delegates the core writing logic to an internal method and provides
242+ * debug logging upon completion.
243+ *
244+ * @param transaction the non-null {@link Transaction} context for this write operation
245+ * @param node the non-null {@link Node} to be written to storage
246+ * @param layer the layer index where the node is being written
247+ * @param changeSet the non-null {@link NeighborsChangeSet} detailing the modifications
248+ * to the node's neighbors
249+ */
132250 @ Override
133251 public void writeNode (@ Nonnull Transaction transaction , @ Nonnull Node <N > node , int layer ,
134252 @ Nonnull NeighborsChangeSet <N > changeSet ) {
@@ -138,6 +256,20 @@ public void writeNode(@Nonnull Transaction transaction, @Nonnull Node<N> node, i
138256 }
139257 }
140258
259+ /**
260+ * Writes a single node to the data store as part of a larger transaction.
261+ * <p>
262+ * This is an abstract method that concrete implementations must provide.
263+ * It is responsible for the low-level persistence of the given {@code node} at a
264+ * specific {@code layer}. The implementation should also handle the modifications
265+ * to the node's neighbors, as detailed in the {@code changeSet}.
266+ *
267+ * @param transaction the non-null transaction context for the write operation
268+ * @param node the non-null {@link Node} to write
269+ * @param layer the layer or level of the node in the structure
270+ * @param changeSet the non-null {@link NeighborsChangeSet} detailing additions or
271+ * removals of neighbor links
272+ */
141273 protected abstract void writeNodeInternal (@ Nonnull Transaction transaction , @ Nonnull Node <N > node , int layer ,
142274 @ Nonnull NeighborsChangeSet <N > changeSet );
143275
0 commit comments