diff --git a/.gitignore b/.gitignore index 9fc38bae4..25335ca03 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ target/ +local/ .mvn/wrapper/maven-wrapper.jar .java-version diff --git a/jvector-base/src/main/java/io/github/jbellis/jvector/graph/disk/AbstractGraphIndexWriter.java b/jvector-base/src/main/java/io/github/jbellis/jvector/graph/disk/AbstractGraphIndexWriter.java index 761024ff8..ecd3d95cd 100644 --- a/jvector-base/src/main/java/io/github/jbellis/jvector/graph/disk/AbstractGraphIndexWriter.java +++ b/jvector-base/src/main/java/io/github/jbellis/jvector/graph/disk/AbstractGraphIndexWriter.java @@ -29,10 +29,18 @@ import java.util.function.IntFunction; import java.util.stream.Collectors; +/** + * Abstract base class for writing graph indexes to disk. + * @param the type of the output writer + */ public abstract class AbstractGraphIndexWriter implements GraphIndexWriter { + /** EOF magic number. */ public static final int FOOTER_MAGIC = 0x4a564244; // "EOF magic" + /** The size of the offset in the footer. */ public static final int FOOTER_OFFSET_SIZE = Long.BYTES; // The size of the offset in the footer + /** The size of the magic number in the footer. */ public static final int FOOTER_MAGIC_SIZE = Integer.BYTES; // The size of the magic number in the footer + /** The total size of the footer. */ public static final int FOOTER_SIZE = FOOTER_MAGIC_SIZE + FOOTER_OFFSET_SIZE; // The total size of the footer final int version; final ImmutableGraphIndex graph; @@ -72,12 +80,17 @@ public abstract class AbstractGraphIndexWriter implements } /** + * Gets the maximum ordinal written so far. * @return the maximum ordinal written so far, or -1 if no ordinals have been written yet */ public int getMaxOrdinal() { return maxOrdinalWritten; } + /** + * Gets the set of features. + * @return the feature set + */ public Set getFeatureSet() { return featureMap.keySet(); } @@ -96,6 +109,8 @@ boolean isSeparated(Feature feature) { } /** + * Computes sequential renumbering for graph ordinals. + * @param graph the graph index to renumber * @return a Map of old to new graph ordinals where the new ordinals are sequential starting at 0, * while preserving the original relative ordering in `graph`. That is, for all node ids i and j, * if i < j in `graph` then map[i] < map[j] in the returned map. "Holes" left by @@ -150,6 +165,9 @@ void writeFooter(ImmutableGraphIndex.View view, long headerOffset) throws IOExce *

* Public so that you can write the index size (and thus usefully open an OnDiskGraphIndex against the index) * to read Features from it before writing the edges. + * @param view the graph index view + * @param startOffset the start offset + * @throws IOException if an I/O error occurs */ public synchronized void writeHeader(ImmutableGraphIndex.View view, long startOffset) throws IOException { // graph-level properties @@ -231,6 +249,8 @@ void writeSeparatedFeatures(Map> featureSt *

* K - the type of the writer to build * T - the type of the output stream + * @param the type of the writer to build + * @param the type of the output stream */ public abstract static class Builder, T extends IndexWriter> { final ImmutableGraphIndex graphIndex; @@ -239,6 +259,11 @@ public abstract static class Builder, T ex OrdinalMapper ordinalMapper; int version; + /** + * Constructs a Builder. + * @param graphIndex the graph index + * @param out the output writer + */ public Builder(ImmutableGraphIndex graphIndex, T out) { this.graphIndex = graphIndex; this.out = out; @@ -246,6 +271,11 @@ public Builder(ImmutableGraphIndex graphIndex, T out) { this.version = OnDiskGraphIndex.CURRENT_VERSION; } + /** + * Sets the version. + * @param version the version + * @return this builder + */ public Builder withVersion(int version) { if (version > OnDiskGraphIndex.CURRENT_VERSION) { throw new IllegalArgumentException("Unsupported version: " + version); @@ -255,16 +285,31 @@ public Builder withVersion(int version) { return this; } + /** + * Adds a feature. + * @param feature the feature + * @return this builder + */ public Builder with(Feature feature) { features.put(feature.id(), feature); return this; } + /** + * Sets the ordinal mapper. + * @param ordinalMapper the ordinal mapper + * @return this builder + */ public Builder withMapper(OrdinalMapper ordinalMapper) { this.ordinalMapper = ordinalMapper; return this; } + /** + * Builds the writer. + * @return the writer + * @throws IOException if an I/O error occurs + */ public K build() throws IOException { if (version < 3 && (!features.containsKey(FeatureId.INLINE_VECTORS) || features.size() > 1)) { throw new IllegalArgumentException("Only INLINE_VECTORS is supported until version 3"); @@ -289,12 +334,28 @@ public K build() throws IOException { return reallyBuild(dimension); } + /** + * Actually builds the writer with the given dimension. + * @param dimension the dimension + * @return the writer + * @throws IOException if an I/O error occurs + */ protected abstract K reallyBuild(int dimension) throws IOException; + /** + * Sets the ordinal mapping. + * @param oldToNewOrdinals the old to new ordinals map + * @return this builder + */ public Builder withMap(Map oldToNewOrdinals) { return withMapper(new OrdinalMapper.MapMapper(oldToNewOrdinals)); } + /** + * Gets a feature by ID. + * @param featureId the feature ID + * @return the feature + */ public Feature getFeature(FeatureId featureId) { return features.get(featureId); } diff --git a/jvector-base/src/main/java/io/github/jbellis/jvector/graph/disk/GraphIndexWriter.java b/jvector-base/src/main/java/io/github/jbellis/jvector/graph/disk/GraphIndexWriter.java index ac67900fe..8e3b8f131 100644 --- a/jvector-base/src/main/java/io/github/jbellis/jvector/graph/disk/GraphIndexWriter.java +++ b/jvector-base/src/main/java/io/github/jbellis/jvector/graph/disk/GraphIndexWriter.java @@ -36,6 +36,7 @@ public interface GraphIndexWriter extends Closeable { * Each supplier takes a node ordinal and returns a FeatureState suitable for Feature.writeInline. * * @param featureStateSuppliers a map of FeatureId to a function that returns a Feature.State + * @throws IOException if an I/O error occurs */ void write(Map> featureStateSuppliers) throws IOException; }