Skip to content
Closed
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
11 changes: 6 additions & 5 deletions java/lance-jni/src/fragment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub(crate) struct FragmentMergeResult {
#[derive(Debug, Clone)]
pub(crate) struct FragmentUpdateResult {
updated_fragment: Fragment,
fields_modified: Vec<u32>,
bitmap_prune_field_ids: Vec<u32>,
}

//////////////////
Expand Down Expand Up @@ -412,11 +412,11 @@ fn inner_update_column<'local>(
let reader = unsafe { ArrowArrayStreamReader::from_raw(stream_ptr) }?;
let left_on_str: String = left_on.extract(env)?;
let right_on_str: String = right_on.extract(env)?;
let (updated_fragment, fields_modified) =
let (updated_fragment, bitmap_prune_field_ids) =
RT.block_on(fragment.update_columns(reader, &left_on_str, &right_on_str))?;
let result = FragmentUpdateResult {
updated_fragment,
fields_modified,
bitmap_prune_field_ids,
};
result.into_java(env)
}
Expand Down Expand Up @@ -456,13 +456,14 @@ impl IntoJava for &FragmentMergeResult {
impl IntoJava for &FragmentUpdateResult {
fn into_java<'a>(self, env: &mut JNIEnv<'a>) -> Result<JObject<'a>> {
let java_updated_fragment = self.updated_fragment.into_java(env)?;
let java_fields_modified = JLance(self.fields_modified.clone()).into_java(env)?;
let java_bitmap_prune_field_ids =
JLance(self.bitmap_prune_field_ids.clone()).into_java(env)?;
Ok(env.new_object(
FRAGMENT_UPDATE_RESULT_CLASS,
FRAGMENT_UPDATE_RESULT_CONSTRUCTOR_SIG,
&[
JValueGen::Object(&java_updated_fragment),
JValueGen::Object(&java_fields_modified),
JValueGen::Object(&java_bitmap_prune_field_ids),
],
)?)
}
Expand Down
33 changes: 17 additions & 16 deletions java/lance-jni/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,9 +495,9 @@ fn convert_to_java_operation_inner<'local>(
removed_fragment_ids,
updated_fragments,
new_fragments,
fields_modified,
bitmap_prune_field_ids,
mem_wal_to_merge: _,
fields_for_preserving_frag_bitmap,
bitmap_preserve_field_ids,
update_mode,
} => {
let removed_ids: Vec<JLance<i64>> = removed_fragment_ids
Expand All @@ -507,9 +507,9 @@ fn convert_to_java_operation_inner<'local>(
let removed_fragment_ids_obj = export_vec(env, &removed_ids)?;
let updated_fragments_obj = export_vec(env, &updated_fragments)?;
let new_fragments_obj = export_vec(env, &new_fragments)?;
let fields_modified = JLance(fields_modified.clone()).into_java(env)?;
let fields_for_preserving_frag_bitmap =
JLance(fields_for_preserving_frag_bitmap.clone()).into_java(env)?;
let bitmap_prune_field_ids = JLance(bitmap_prune_field_ids.clone()).into_java(env)?;
let bitmap_preserve_field_ids =
JLance(bitmap_preserve_field_ids.clone()).into_java(env)?;
let update_mode = match update_mode {
Some(update_mode) => update_mode.into_java(env),
None => Ok(JObject::null()),
Expand All @@ -529,8 +529,8 @@ fn convert_to_java_operation_inner<'local>(
JValue::Object(&removed_fragment_ids_obj),
JValue::Object(&updated_fragments_obj),
JValue::Object(&new_fragments_obj),
JValueGen::Object(&fields_modified),
JValueGen::Object(&fields_for_preserving_frag_bitmap),
JValueGen::Object(&bitmap_prune_field_ids),
JValueGen::Object(&bitmap_preserve_field_ids),
JValue::Object(&update_mode_optional),
],
)?)
Expand Down Expand Up @@ -939,16 +939,17 @@ fn convert_to_rust_operation(
fragment.extract_object(env)
})?;

let fields_modified = env
.call_method(java_operation, "fieldsModified", "()[J", &[])?
let bitmap_prune_field_ids = env
.call_method(java_operation, "bitmapPruneFieldIds", "()[J", &[])?
.l()?;
let fields_modified = JLongArray::from(fields_modified).extract_object(env)?;
let bitmap_prune_field_ids =
JLongArray::from(bitmap_prune_field_ids).extract_object(env)?;

let fields_for_preserving_frag_bitmap = env
.call_method(java_operation, "fieldsForPreservingFragBitmap", "()[J", &[])?
let bitmap_preserve_field_ids = env
.call_method(java_operation, "bitmapPreserveExcludeFieldIds", "()[J", &[])?
.l()?;
let fields_for_preserving_frag_bitmap =
JLongArray::from(fields_for_preserving_frag_bitmap).extract_object(env)?;
let bitmap_preserve_field_ids =
JLongArray::from(bitmap_preserve_field_ids).extract_object(env)?;

let update_mode: Option<UpdateMode> =
env.get_optional_from_method(java_operation, "updateMode", |env, update_mode| {
Expand All @@ -959,9 +960,9 @@ fn convert_to_rust_operation(
removed_fragment_ids,
updated_fragments,
new_fragments,
fields_modified,
bitmap_prune_field_ids,
mem_wal_to_merge: None,
fields_for_preserving_frag_bitmap,
bitmap_preserve_field_ids,
update_mode,
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,26 @@
*/
public class FragmentUpdateResult {
private final FragmentMetadata updatedFragment;
private final long[] fieldsModified;
private final long[] bitmapPruneFieldIds;

public FragmentUpdateResult(FragmentMetadata updatedFragment, long[] updatedFieldIds) {
public FragmentUpdateResult(FragmentMetadata updatedFragment, long[] bitmapPruneFieldIds) {
this.updatedFragment = updatedFragment;
this.fieldsModified = updatedFieldIds;
this.bitmapPruneFieldIds = bitmapPruneFieldIds;
}

public FragmentMetadata getUpdatedFragment() {
return updatedFragment;
}

public long[] getFieldsModified() {
return fieldsModified;
public long[] getBitmapPruneFieldIds() {
return bitmapPruneFieldIds;
}

@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("fragmentMetadata", updatedFragment)
.add("updatedFieldIds", fieldsModified)
.add("bitmapPruneFieldIds", bitmapPruneFieldIds)
.toString();
}
}
44 changes: 22 additions & 22 deletions java/src/main/java/com/lancedb/lance/operation/Update.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,22 @@ public class Update implements Operation {
private final List<Long> removedFragmentIds;
private final List<FragmentMetadata> updatedFragments;
private final List<FragmentMetadata> newFragments;
private final long[] fieldsModified;
private final long[] fieldsForPreservingFragBitmap;
private final long[] bitmapPruneFieldIds;
private final long[] bitmapPreserveExcludeFieldIds;
private final Optional<UpdateMode> updateMode;

private Update(
List<Long> removedFragmentIds,
List<FragmentMetadata> updatedFragments,
List<FragmentMetadata> newFragments,
long[] fieldsModified,
long[] fieldsForPreservingFragBitmap,
long[] bitmapPruneFieldIds,
long[] bitmapPreserveExcludeFieldIds,
Optional<UpdateMode> updateMode) {
this.removedFragmentIds = removedFragmentIds;
this.updatedFragments = updatedFragments;
this.newFragments = newFragments;
this.fieldsModified = fieldsModified;
this.fieldsForPreservingFragBitmap = fieldsForPreservingFragBitmap;
this.bitmapPruneFieldIds = bitmapPruneFieldIds;
this.bitmapPreserveExcludeFieldIds = bitmapPreserveExcludeFieldIds;
this.updateMode = updateMode;
}

Expand All @@ -62,12 +62,12 @@ public List<FragmentMetadata> newFragments() {
return newFragments;
}

public long[] fieldsModified() {
return fieldsModified;
public long[] bitmapPruneFieldIds() {
return bitmapPruneFieldIds;
}

public long[] fieldsForPreservingFragBitmap() {
return fieldsForPreservingFragBitmap;
public long[] bitmapPreserveExcludeFieldIds() {
return bitmapPreserveExcludeFieldIds;
}

public Optional<UpdateMode> updateMode() {
Expand All @@ -84,8 +84,8 @@ public String toString() {
.add("removedFragmentIds", removedFragmentIds)
.add("updatedFragments", updatedFragments)
.add("newFragments", newFragments)
.add("fieldsModified", fieldsModified)
.add("fieldsForPreservingFragBitmap", fieldsForPreservingFragBitmap)
.add("bitmapPruneFieldIds", bitmapPruneFieldIds)
.add("bitmapPreserveExcludeFieldIds", bitmapPreserveExcludeFieldIds)
.add("updateMode", updateMode)
.toString();
}
Expand All @@ -98,8 +98,8 @@ public boolean equals(Object o) {
return Objects.equals(removedFragmentIds, that.removedFragmentIds)
&& Objects.equals(updatedFragments, that.updatedFragments)
&& Objects.equals(newFragments, that.newFragments)
&& Arrays.equals(fieldsModified, that.fieldsModified)
&& Arrays.equals(fieldsForPreservingFragBitmap, that.fieldsForPreservingFragBitmap)
&& Arrays.equals(bitmapPruneFieldIds, that.bitmapPruneFieldIds)
&& Arrays.equals(bitmapPreserveExcludeFieldIds, that.bitmapPreserveExcludeFieldIds)
&& Objects.equals(updateMode, that.updateMode);
}

Expand All @@ -112,8 +112,8 @@ public static class Builder {
private List<Long> removedFragmentIds = Collections.emptyList();
private List<FragmentMetadata> updatedFragments = Collections.emptyList();
private List<FragmentMetadata> newFragments = Collections.emptyList();
private long[] fieldsModified = new long[0];
private long[] fieldsForPreservingFragBitmap = new long[0];
private long[] bitmapPruneFieldIds = new long[0];
private long[] bitmapPreserveExcludeFieldIds = new long[0];
private Optional<UpdateMode> updateMode = Optional.empty();

private Builder() {}
Expand All @@ -133,13 +133,13 @@ public Builder newFragments(List<FragmentMetadata> newFragments) {
return this;
}

public Builder fieldsModified(long[] fieldsModified) {
this.fieldsModified = fieldsModified;
public Builder bitmapPruneFieldIds(long[] bitmapPruneFieldIds) {
this.bitmapPruneFieldIds = bitmapPruneFieldIds;
return this;
}

public Builder fieldsForPreservingFragBitmap(long[] fieldsForPreservingFragBitmap) {
this.fieldsForPreservingFragBitmap = fieldsForPreservingFragBitmap;
public Builder bitmapPreserveExcludeFieldIds(long[] bitmapPreserveExcludeFieldIds) {
this.bitmapPreserveExcludeFieldIds = bitmapPreserveExcludeFieldIds;
return this;
}

Expand All @@ -153,8 +153,8 @@ public Update build() {
removedFragmentIds,
updatedFragments,
newFragments,
fieldsModified,
fieldsForPreservingFragBitmap,
bitmapPruneFieldIds,
bitmapPreserveExcludeFieldIds,
updateMode);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ void testUpdateColumns(@TempDir Path tempDir) throws Exception {
Update.builder()
.updatedFragments(
Collections.singletonList(updateResult.getUpdatedFragment()))
.fieldsModified(updateResult.getFieldsModified())
.bitmapPruneFieldIds(updateResult.getBitmapPruneFieldIds())
.build())
.build();
try (Dataset dataset = updateTransaction.commit()) {
Expand Down
7 changes: 4 additions & 3 deletions protos/transaction.proto
Original file line number Diff line number Diff line change
Expand Up @@ -193,12 +193,13 @@ message Transaction {
repeated DataFragment updated_fragments = 2;
// The new fragments where updated rows have been moved to.
repeated DataFragment new_fragments = 3;
// The ids of the fields that have been modified.
/// Field IDs that drive index fragment bitmap pruning
repeated uint32 fields_modified = 4;
/// The MemWAL (pre-image) that should be marked as merged after this transaction
MemWalIndexDetails.MemWal mem_wal_to_merge = 5;
/// The fields that used to judge whether to preserve the new frag's id into
/// the frag bitmap of the specified indices.
/// Field IDs used to decide whether to preserve new fragment IDs in the
/// fragment bitmap of specified indices. Indices that do not cover these
/// fields may preserve the new fragment IDs when applicable.
repeated uint32 fields_for_preserving_frag_bitmap = 6;
// The mode of update
UpdateMode update_mode = 7;
Expand Down
23 changes: 12 additions & 11 deletions python/python/lance/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -3923,24 +3923,25 @@ class Update(BaseOperation):
The fragments that have been updated with new deletion vectors.
new_fragments: list[FragmentMetadata]
The fragments that contain the new rows.
fields_modified: list[int]
If any fields are modified in updated_fragments, then they must be
listed here so those fragments can be removed from indices covering
those fields.
fields_for_preserving_frag_bitmap: list[int]
The fields that used to judge whether to preserve the new frag's id into
the frag bitmap of the specified indices.
bitmap_prune_field_ids: list[int]
Field IDs that drive index fragment bitmap pruning. If any fields are
modified in updated_fragments,
then they must be listed here so those fragments can be removed from
indices that cover any of these fields.
bitmap_preserve_field_ids: list[int]
Field IDs used to decide whether to preserve new fragment IDs in an index's
fragment bitmap.
Indices that do not cover these fields may preserve the new fragment IDs
when applicable.
"""

removed_fragment_ids: List[int] = dataclasses.field(default_factory=list)
updated_fragments: List[FragmentMetadata] = dataclasses.field(
default_factory=list
)
new_fragments: List[FragmentMetadata] = dataclasses.field(default_factory=list)
fields_modified: List[int] = dataclasses.field(default_factory=list)
fields_for_preserving_frag_bitmap: List[int] = dataclasses.field(
default_factory=list
)
bitmap_prune_field_ids: List[int] = dataclasses.field(default_factory=list)
bitmap_preserve_field_ids: List[int] = dataclasses.field(default_factory=list)
update_mode: str = ""

def __post_init__(self):
Expand Down
4 changes: 2 additions & 2 deletions python/python/lance/fragment.py
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ def update_columns(
... })
>>> # Update the fragment
>>> fragment = dataset.get_fragment(0)
>>> updated_fragment, fields_modified = fragment.update_columns(
>>> updated_fragment, bitmap_prune_field_ids = fragment.update_columns(
... update_data,
... left_on="id",
... right_on="id"
Expand All @@ -689,7 +689,7 @@ def update_columns(
>>> from lance import LanceOperation
>>> op = LanceOperation.Update(
... updated_fragments=[updated_fragment],
... fields_modified=fields_modified,
... bitmap_prune_field_ids=bitmap_prune_field_ids,
... )
>>> dataset = lance.LanceDataset.commit(
... "dataset",
Expand Down
Loading