Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions java/lance-jni/src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,15 @@ impl IntoJava for &Arc<dyn IndexDescription> {
let metadata_list = export_vec(env, self.metadata())?;
let details_json = self.details()?;
let details = env.new_string(details_json)?;
let total_size_bytes = if let Some(size) = self.total_size_bytes() {
env.new_object("java/lang/Long", "(J)V", &[JValue::Long(size as i64)])?
} else {
JObject::null()
};

let j_index_desc = env.new_object(
"org/lance/index/IndexDescription",
"(Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;JLjava/util/List;Ljava/lang/String;)V",
"(Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/lang/String;JLjava/util/List;Ljava/lang/String;Ljava/lang/Long;)V",
&[
JValue::Object(&name),
JValue::Object(&field_ids_list),
Expand All @@ -47,6 +52,7 @@ impl IntoJava for &Arc<dyn IndexDescription> {
JValue::Long(rows_indexed),
JValue::Object(&metadata_list),
JValue::Object(&details),
JValue::Object(&total_size_bytes),
],
)?;
Ok(j_index_desc)
Expand Down Expand Up @@ -125,13 +131,19 @@ impl IntoJava for &IndexMetadata {
JObject::null()
};

let size_bytes = if let Some(size) = self.total_size_bytes() {
env.new_object("java/lang/Long", "(J)V", &[JValue::Long(size as i64)])?
} else {
JObject::null()
};

// Determine index type from index_details type_url
let index_type = determine_index_type(env, &self.index_details)?;

// Create Index object
Ok(env.new_object(
"org/lance/index/Index",
"(Ljava/util/UUID;Ljava/util/List;Ljava/lang/String;JLjava/util/List;[BILjava/time/Instant;Ljava/lang/Integer;Lorg/lance/index/IndexType;)V",
"(Ljava/util/UUID;Ljava/util/List;Ljava/lang/String;JLjava/util/List;[BILjava/time/Instant;Ljava/lang/Integer;Ljava/lang/Long;Lorg/lance/index/IndexType;)V",
&[
JValue::Object(&uuid),
JValue::Object(&fields),
Expand All @@ -142,6 +154,7 @@ impl IntoJava for &IndexMetadata {
JValue::Int(self.index_version),
JValue::Object(&created_at),
JValue::Object(&base_id),
JValue::Object(&size_bytes),
JValue::Object(&index_type),
],
)?)
Expand Down
24 changes: 24 additions & 0 deletions java/src/main/java/org/lance/index/Index.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class Index {
private final int indexVersion;
private final Instant createdAt;
private final Integer baseId;
private final Long sizeBytes;
private final IndexType indexType;

private Index(
Expand All @@ -48,6 +49,7 @@ private Index(
int indexVersion,
Instant createdAt,
Integer baseId,
Long sizeBytes,
IndexType indexType) {
this.uuid = uuid;
this.fields = fields;
Expand All @@ -58,6 +60,7 @@ private Index(
this.indexVersion = indexVersion;
this.createdAt = createdAt;
this.baseId = baseId;
this.sizeBytes = sizeBytes;
this.indexType = indexType;
}

Expand Down Expand Up @@ -104,6 +107,17 @@ public Optional<Integer> baseId() {
return Optional.ofNullable(baseId);
}

/**
* Get the total size of all files in this physical index segment.
*
* <p>The size is unavailable for indices created before index file sizes were tracked.
*
* @return the segment size in bytes, or empty if unavailable
*/
public Optional<Long> getSizeBytes() {
return Optional.ofNullable(sizeBytes);
}

/**
* Get the index version.
*
Expand Down Expand Up @@ -145,6 +159,7 @@ public boolean equals(Object o) {
&& Arrays.equals(indexDetails, index.indexDetails)
&& Objects.equals(createdAt, index.createdAt)
&& Objects.equals(baseId, index.baseId)
&& Objects.equals(sizeBytes, index.sizeBytes)
&& indexType == index.indexType;
}

Expand All @@ -159,6 +174,7 @@ public int hashCode() {
indexVersion,
createdAt,
baseId,
sizeBytes,
fragments,
indexType);
result = 31 * result + Arrays.hashCode(indexDetails);
Expand All @@ -176,6 +192,7 @@ public String toString() {
.add("indexType", indexType)
.add("createdAt", createdAt)
.add("baseId", baseId)
.add("sizeBytes", sizeBytes)
.toString();
}

Expand All @@ -199,6 +216,7 @@ public static class Builder {
private int indexVersion;
private Instant createdAt;
private Integer baseId;
private Long sizeBytes;
private IndexType indexType;

private Builder() {}
Expand Down Expand Up @@ -248,6 +266,11 @@ public Builder baseId(Integer baseId) {
return this;
}

public Builder sizeBytes(Long sizeBytes) {
this.sizeBytes = sizeBytes;
return this;
}

public Builder indexType(IndexType indexType) {
this.indexType = indexType;
return this;
Expand All @@ -264,6 +287,7 @@ public Index build() {
indexVersion,
createdAt,
baseId,
sizeBytes,
indexType);
}
}
Expand Down
26 changes: 26 additions & 0 deletions java/src/main/java/org/lance/index/IndexDescription.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
* High-level description of an index, aggregating metadata across all segments.
Expand All @@ -31,6 +32,7 @@ public final class IndexDescription {
private final long rowsIndexed;
private final List<Index> metadata;
private final String detailsJson;
private final Long totalSizeBytes;

public IndexDescription(
String name,
Expand All @@ -40,13 +42,26 @@ public IndexDescription(
long rowsIndexed,
List<Index> metadata,
String detailsJson) {
this(name, fieldIds, typeUrl, indexType, rowsIndexed, metadata, detailsJson, null);
}

public IndexDescription(
String name,
List<Integer> fieldIds,
String typeUrl,
String indexType,
long rowsIndexed,
List<Index> metadata,
String detailsJson,
Long totalSizeBytes) {
this.name = Objects.requireNonNull(name, "name must not be null");
this.fieldIds = Objects.requireNonNull(fieldIds, "fieldIds must not be null");
this.typeUrl = Objects.requireNonNull(typeUrl, "typeUrl must not be null");
this.indexType = Objects.requireNonNull(indexType, "indexType must not be null");
this.rowsIndexed = rowsIndexed;
this.metadata = Objects.requireNonNull(metadata, "metadata must not be null");
this.detailsJson = detailsJson;
this.totalSizeBytes = totalSizeBytes;
}

/** The logical name of the index. */
Expand Down Expand Up @@ -100,4 +115,15 @@ public List<Index> getSegments() {
public String getDetailsJson() {
return detailsJson;
}

/**
* Total size of all files across all physical index segments.
*
* <p>The size is unavailable if any segment predates index file size tracking.
*
* @return the logical index size in bytes, or empty if unavailable
*/
public Optional<Long> getTotalSizeBytes() {
return Optional.ofNullable(totalSizeBytes);
}
}
9 changes: 9 additions & 0 deletions java/src/test/java/org/lance/DatasetTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2153,6 +2153,13 @@ public void testDescribeIndicesByName(@TempDir Path tempDir) throws Exception {

assertEquals(1, desc.getSegments().size(), "Expected exactly one physical segment");
assertEquals("index1", desc.getSegments().get(0).name());
assertTrue(
desc.getSegments().get(0).getSizeBytes().orElse(0L) > 0,
"segment size should be positive");
assertEquals(
desc.getSegments().get(0).getSizeBytes(),
desc.getTotalSizeBytes(),
"single-segment size should equal the logical index size");

descriptions = dataset.describeIndices();
assertEquals(2, descriptions.size(), "Expected exactly one matching index");
Expand All @@ -2165,6 +2172,8 @@ public void testDescribeIndicesByName(@TempDir Path tempDir) throws Exception {
indexDesc.getSegments(),
"segments alias should match metadata");
assertNotNull(indexDesc.getDetailsJson(), "Details JSON should not be null");
assertTrue(
indexDesc.getTotalSizeBytes().orElse(0L) > 0, "total index size should be positive");
}
}
}
Expand Down
Loading