JeonDaehong commented on code in PR #3232:
URL: https://github.com/apache/iceberg-rust/pull/3232#discussion_r4181995275


##########
crates/iceberg/src/delete_vector.rs:
##########
@@ -122,6 +122,52 @@ impl DeleteVector {
 
         Ok(DeleteVector { inner })
     }
+
+    /// Serializes this `DeleteVector` into a `deletion-vector-v1` Puffin blob 
that
+    /// [`DeleteVector::deserialize`] reads back, conforming to the Iceberg 
Puffin
+    /// `deletion-vector-v1` layout:
+    ///
+    /// ```text
+    /// [length: u32 big-endian][magic: D1 D3 39 64][vector][crc: u32 
big-endian]
+    /// ```
+    ///
+    /// `length` counts the magic and vector bytes (not itself or the CRC). 
The CRC-32 is computed
+    /// over the magic and vector. `vector` is the roaring bitmap in the 
portable 64-bit format: a
+    /// directory of 32-bit key / 32-bit roaring bitmap pairs ordered by 
unsigned comparison of the
+    /// keys, one bitmap per key. `roaring`'s `RoaringTreemap::serialize_into` 
emits exactly that
+    /// directory (a `u64` little-endian count followed by ascending 
`u32`-keyed bitmaps), which the
+    /// round-trip tests verify against [`decode_roaring_directory`].
+    ///
+    /// The roaring vector is written as-is, not run-length-encoded, using 
sparse-key encoding: only
+    /// the non-empty 32-bit containers are emitted. For the same logical set 
of positions these
+    /// bytes therefore need not match Iceberg-Java's 
`BitmapPositionDeleteIndex` output, which
+    /// run-optimizes the bitmap and writes dense keys. Both encodings are 
`deletion-vector-v1`
+    /// spec-conformant and decode to the same positions, so each side reads 
back what the other
+    /// writes. Callers that want size-optimal, Java-like blobs should 
`optimize()` the underlying
+    /// roaring bitmap (`RoaringTreemap::optimize`) before serializing.
+    ///
+    /// This produces the raw blob only; wrapping it in a Puffin `Blob` with 
the associated
+    /// snapshot and sequence-number properties is handled separately.
+    ///
+    /// # Errors
+    ///
+    /// Returns [`ErrorKind::DataInvalid`] if the framed body (the magic plus 
the vector) would
+    /// exceed `u32::MAX` bytes, since the `deletion-vector-v1` length prefix 
is a `u32`; reaching
+    /// this requires a deletion vector of roughly 4 GiB, far larger than any 
realistic set of row
+    /// positions. Returns [`ErrorKind::Unexpected`] if writing the roaring 
treemap into the
+    /// in-memory buffer fails, which does not happen under Rust's allocator 
model (an allocation
+    /// failure aborts rather than returning an error); it guards only against 
a hypothetical future
+    /// change to `roaring`'s API that would make `serialize_into` fallible 
for an in-memory `Vec`.
+    // Nothing in non-test crate code calls this yet (the delete-vector write 
path wires it in
+    // later), and `delete_vector` is a private module, so it otherwise reads 
as dead code.
+    #[allow(unused)]
+    pub fn serialize(&self) -> Result<Vec<u8>> {

Review Comment:
   The spec says the vector supports positive 64-bit positions ("the most 
significant bit must be 0"), but insert accepts any u64 and serialize doesn't 
check, so a position >= 2^63 would be written as a key >= 2^31. Iceberg Java 
rejects that on read (RoaringPositionBitmap.readKey requires key <= 
Integer.MAX_VALUE - 1), so the "mutually decodable" note wouldn't hold for that 
range.
   
   Real row positions won't get there, so this is mostly defensive, but would 
it make sense for serialize to return an error when the highest key has its top 
bit set, like the length check below? That would keep us from writing a blob 
other implementations can't read.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to