This is an automated email from the ASF dual-hosted git repository.

voonhous pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hudi.git


The following commit(s) were added to refs/heads/master by this push:
     new 1ca682ca13b5 docs(hudi-io): fill in the HFile format details the doc 
was missing (#19721)
1ca682ca13b5 is described below

commit 1ca682ca13b545a2268631a81e0a377edcc9b0b6
Author: Ranga Reddy <[email protected]>
AuthorDate: Tue Aug 25 16:36:03 2026 +0530

    docs(hudi-io): fill in the HFile format details the doc was missing (#19721)
    
    Closes #17030 (HUDI-9454).
    
    hfile_format.md describes the HFile subset Hudi uses. Four things it left 
out or got
    wrong, all checked against hudi-io's reader and writer:
    
    Block magics. The list named 4 of the 12 types in HFileBlockType, and 
TRABLK"$ appeared
    in the Trailer section without ever being listed as a magic. Split the list 
into what
    Hudi writes and what its reader additionally accepts so it can read 
HBase-written files:
    the leaf/intermediate index magics, HBase's three bloom block types, the 
encoded data
    block, and the v1 index block.
    
    Checksum Type. The field was described only as "type of checksum used" with 
no values.
    ChecksumType defines NULL = 0, CRC32 = 1, CRC32C = 2.
    
    Multi-level data block index. num_data_index_levels is listed in the 
trailer fields but
    nothing described what more than one level means, even though 
HFileLeafIndexBlock and
    HFileIntermediateIndexBlock exist and HFileReaderImpl walks down the 
levels. Added a
    section covering it, including that Hudi's writer always emits a single 
root level and
    sets num_data_index_levels to 1, so the multi-level path exists only for 
reading HBase
    files.
    
    File Info keys. The list had two entries, one of which was wrong: the doc 
gave
    hfile.MAX_MEMSTORE_TS_KEY, but HFileInfo declares MAX_MEMSTORE_TS_KEY and
    KEY_VALUE_VERSION without the reserved hfile. prefix, which LASTKEY, 
CREATE_TIME_TS,
    AVG_KEY_LEN and AVG_VALUE_LEN do carry. Corrected that, added the four 
missing keys, and
    called the inconsistency out so a reader does not go looking for a prefixed 
name that
    does not exist.
    
    Also names the meta block key Hudi stores its bloom filter under, 
"bloomFilter". The
    document mentioned bloom filters in the section overview but never said how 
to find one,
    and it is easy to confuse with HBase's own bloom blocks, which Hudi never 
writes.
    
    Documentation only, no code change.
---
 hudi-io/hfile_format.md | 54 ++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 47 insertions(+), 7 deletions(-)

diff --git a/hudi-io/hfile_format.md b/hudi-io/hfile_format.md
index 3687c6fbc007..3352fd39b7dd 100644
--- a/hudi-io/hfile_format.md
+++ b/hudi-io/hfile_format.md
@@ -109,18 +109,30 @@ Note that one tick mark represents one bit position.
 
 Header:
 
-- **Block Magic**: 8 bytes, a sequence of bytes indicating the block type. 
Supported block types are:
+- **Block Magic**: 8 bytes, a sequence of bytes indicating the block type. The 
block types Hudi writes are:
     - `DATABLK*`: `DATA` block type for data blocks
     - `METABLKc`: `META` block type for meta blocks
     - `IDXROOT2`: `ROOT_INDEX` block type for root-level index blocks
     - `FILEINF2`: `FILE_INFO` block type for the file info block, a small 
key-value map of metadata
+    - `TRABLK"$`: `TRAILER` block type, described in the [Trailer](#trailer) 
section below
+
+  Hudi's reader also recognises the remaining HFile v3 block types, so it can 
read files written by
+  HBase. It never writes them:
+    - `IDXLEAF2` / `IDXINTE2`: `LEAF_INDEX` and `INTERMEDIATE_INDEX`, the 
lower levels of a
+      multi-level data block index (see [Multi-level data block 
index](#multi-level-data-block-index))
+    - `BLMFBLK2`, `BLMFMET2`, `DFBLMET2`: `BLOOM_CHUNK`, `GENERAL_BLOOM_META` 
and
+      `DELETE_FAMILY_BLOOM_META`, HBase's own bloom filter blocks. These are 
unrelated to the bloom
+      filter Hudi stores, which goes in an ordinary meta block (see [Meta 
Block](#meta-block))
+    - `DATABLKE`: `ENCODED_DATA`, a data block using an HBase data block 
encoding
+    - `IDXBLK)+`: `INDEX_V1`, the index block of the superseded HFile v1 format
 - **On-disk Size Without Header**: 4 bytes, integer, compressed size of the 
block's data, not including the header. Can
   be used for skipping the current data block when scanning HFile data.
 - **Uncompressed Size Without Header**: 4 bytes, integer, uncompressed size of 
the block's data, not including the
   header. This is equal to the compressed size if the compression algorithm is 
NONE.
 - **Previous Block Offset**: 8 bytes, long, file offset of the previous block 
of the same type. Can be used for seeking
   to the previous data/index block.
-- **Checksum Type**: 1 byte, type of checksum used.
+- **Checksum Type**: 1 byte, type of checksum used: `0` = `NULL` (no 
checksum), `1` = `CRC32`,
+  `2` = `CRC32C`.
 - **Bytes Per Checksum**: 4 bytes, integer, number of data bytes covered per 
checksum.
 - **On-disk Data Size With Header**: 4 bytes, integer, on disk data size with 
header.
 
@@ -213,8 +225,11 @@ This is used by HBase and written to HFile. For Hudi, this 
field should always b
 ## Meta Block
 
 The "Data" part of the Meta Block contains the meta information in byte array. 
The key of the meta block can be found in
-the
-Meta Index Block.
+the Meta Index Block.
+
+Hudi stores the bloom filter of a file in a meta block under the key 
`bloomFilter`, which is the key the
+reader looks up when serving a bloom filter. This is Hudi's own meta block and 
is unrelated to HBase's
+`BLMFMET2` / `BLMFBLK2` bloom blocks, which Hudi never writes.
 
 ## Index Block
 
@@ -299,6 +314,23 @@ For Data Index, the "Key Bytes" part has the following 
format (same as the key f
 
 For Meta Index, the "Key Bytes" part is the byte array of the key of the Meta 
Block.
 
+### Multi-level data block index
+
+The block index can have more than one level. `num_data_index_levels` in the 
[Trailer](#trailer) says how
+many. With one level, the Root Data Index Block in the "Load-on-open" section 
points straight at the data
+blocks, and that is all Hudi's writer ever produces: it writes a single root 
level and sets
+`num_data_index_levels` to `1`.
+
+With more than one level, the root index entries point at index blocks rather 
than data blocks. Those
+intermediate levels use the `IDXINTE2` (`INTERMEDIATE_INDEX`) magic and the 
bottom level uses `IDXLEAF2`
+(`LEAF_INDEX`); both carry the same block index entry layout described above. 
HBase produces these once a
+file has more data blocks than fit in a single root index.
+
+Hudi's reader handles this so it can read HFiles written by HBase: starting 
from the root entries it walks
+down `num_data_index_levels`, reading each level's index blocks until the 
entries it holds are data block
+entries, then uses those for lookups. Reading a multi-level file therefore 
costs one extra block read per
+level beyond the root.
+
 ## File Info Block
 
 The "Data" part of the File Info Block has the following format:
@@ -337,11 +369,19 @@ message InfoProto {
 The key and value are represented in byte array. When Hudi adds more key-value 
metadata entry to the file info, the key
 and value are encoded from String into byte array using UTF-8.
 
-Here are common metadata stored in the File Info Block:
+Here are common metadata stored in the File Info Block. Note that only some of 
these keys carry the
+reserved `hfile.` prefix; `KEY_VALUE_VERSION` and `MAX_MEMSTORE_TS_KEY` do 
not, and looking them up with
+the prefix finds nothing:
 
 - `hfile.LASTKEY`: The last key of the file (byte array)
-- `hfile.MAX_MEMSTORE_TS_KEY`: Maximum MVCC timestamp of the key-value pairs 
in the file. In Hudi, this should always be
-    0.
+- `hfile.CREATE_TIME_TS`: File creation timestamp
+- `hfile.AVG_KEY_LEN`: Average key length in the file, integer
+- `hfile.AVG_VALUE_LEN`: Average value length in the file, integer
+- `KEY_VALUE_VERSION`: Whether the key-value entries carry an MVCC timestamp. 
`1`
+  (`KEY_VALUE_VERSION_WITH_MVCC_TS`) means they do. Hudi writes the MVCC 
timestamp as a single zero byte
+  on every entry, as described in [Data Block](#data-block).
+- `MAX_MEMSTORE_TS_KEY`: Maximum MVCC timestamp of the key-value pairs in the 
file. In Hudi, this should
+  always be 0, and the reader validates that assumption when parsing the file 
info.
 
 ## Trailer
 

Reply via email to