@@ -22,10 +22,12 @@ use std::cmp::Ordering;
2222use  std:: collections:: HashMap ; 
2323use  std:: fmt:: { Display ,  Formatter } ; 
2424use  std:: hash:: Hash ; 
25+ use  std:: io:: Read  as  _; 
2526use  std:: sync:: Arc ; 
2627
2728use  _serde:: TableMetadataEnum ; 
2829use  chrono:: { DateTime ,  Utc } ; 
30+ use  flate2:: read:: GzDecoder ; 
2931use  serde:: { Deserialize ,  Serialize } ; 
3032use  serde_repr:: { Deserialize_repr ,  Serialize_repr } ; 
3133use  uuid:: Uuid ; 
@@ -413,9 +415,20 @@ impl TableMetadata {
413415        file_io :  & FileIO , 
414416        metadata_location :  impl  AsRef < str > , 
415417    )  -> Result < TableMetadata >  { 
416-         let  input_file = file_io. new_input ( metadata_location) ?; 
418+         let  input_file = file_io. new_input ( metadata_location. as_ref ( ) ) ?; 
417419        let  metadata_content = input_file. read ( ) . await ?; 
418-         let  metadata = serde_json:: from_slice :: < TableMetadata > ( & metadata_content) ?; 
420+ 
421+         let  metadata = if  metadata_location. as_ref ( ) . ends_with ( ".gz.metadata.json" )  { 
422+             let  mut  decoder = GzDecoder :: new ( metadata_content. as_ref ( ) ) ; 
423+             let  mut  decompressed_data = Vec :: new ( ) ; 
424+             decoder
425+                 . read_to_end ( & mut  decompressed_data) 
426+                 . map_err ( |e| Error :: new ( ErrorKind :: DataInvalid ,  e. to_string ( ) ) ) ?; 
427+             serde_json:: from_slice ( & decompressed_data) ?
428+         }  else  { 
429+             serde_json:: from_slice ( & metadata_content) ?
430+         } ; 
431+ 
419432        Ok ( metadata) 
420433    } 
421434
@@ -1318,6 +1331,7 @@ impl SnapshotLog {
13181331mod  tests { 
13191332    use  std:: collections:: HashMap ; 
13201333    use  std:: fs; 
1334+     use  std:: io:: Write  as  _; 
13211335    use  std:: sync:: Arc ; 
13221336
13231337    use  anyhow:: Result ; 
@@ -3033,7 +3047,7 @@ mod tests {
30333047        let  original_metadata:  TableMetadata  = get_test_table_metadata ( "TableMetadataV2Valid.json" ) ; 
30343048
30353049        // Define the metadata location 
3036-         let  metadata_location = format ! ( "{}/metadata.json" ,  temp_path ) ; 
3050+         let  metadata_location = format ! ( "{temp_path }/metadata.json" ) ; 
30373051
30383052        // Write the metadata 
30393053        original_metadata
@@ -3053,6 +3067,30 @@ mod tests {
30533067        assert_eq ! ( read_metadata,  original_metadata) ; 
30543068    } 
30553069
3070+     #[ tokio:: test]  
3071+     async  fn  test_table_metadata_read_compressed ( )  { 
3072+         let  temp_dir = TempDir :: new ( ) . unwrap ( ) ; 
3073+         let  metadata_location = temp_dir. path ( ) . join ( "v1.gz.metadata.json" ) ; 
3074+ 
3075+         let  original_metadata:  TableMetadata  = get_test_table_metadata ( "TableMetadataV2Valid.json" ) ; 
3076+         let  json = serde_json:: to_string ( & original_metadata) . unwrap ( ) ; 
3077+ 
3078+         let  mut  encoder = flate2:: write:: GzEncoder :: new ( Vec :: new ( ) ,  flate2:: Compression :: default ( ) ) ; 
3079+         encoder. write_all ( json. as_bytes ( ) ) . unwrap ( ) ; 
3080+         std:: fs:: write ( & metadata_location,  encoder. finish ( ) . unwrap ( ) ) 
3081+             . expect ( "failed to write metadata" ) ; 
3082+ 
3083+         // Read the metadata back 
3084+         let  file_io = FileIOBuilder :: new_fs_io ( ) . build ( ) . unwrap ( ) ; 
3085+         let  metadata_location = metadata_location. to_str ( ) . unwrap ( ) ; 
3086+         let  read_metadata = TableMetadata :: read_from ( & file_io,  metadata_location) 
3087+             . await 
3088+             . unwrap ( ) ; 
3089+ 
3090+         // Verify the metadata matches 
3091+         assert_eq ! ( read_metadata,  original_metadata) ; 
3092+     } 
3093+ 
30563094    #[ tokio:: test]  
30573095    async  fn  test_table_metadata_read_nonexistent_file ( )  { 
30583096        // Create a FileIO instance 
0 commit comments