@@ -27,10 +27,7 @@ use crate::{
27
27
catalog:: manifest:: { File , Manifest } ,
28
28
handlers:: http:: cluster:: INTERNAL_STREAM_NAME ,
29
29
metadata:: { error:: stream_info:: MetadataError , STREAM_INFO } ,
30
- option:: {
31
- validation:: { bytes_to_human_size, human_size_to_bytes} ,
32
- CONFIG ,
33
- } ,
30
+ option:: { validation:: bytes_to_human_size, CONFIG } ,
34
31
storage:: { ObjectStorage , ObjectStorageError } ,
35
32
utils:: extract_datetime,
36
33
validator:: error:: HotTierValidationError ,
@@ -53,9 +50,10 @@ pub const STREAM_HOT_TIER_FILENAME: &str = ".hot_tier.json";
53
50
pub const MIN_STREAM_HOT_TIER_SIZE_BYTES : u64 = 10737418240 ; // 10 GiB
54
51
const HOT_TIER_SYNC_DURATION : Interval = clokwerk:: Interval :: Minutes ( 1 ) ;
55
52
pub const INTERNAL_STREAM_HOT_TIER_SIZE_BYTES : u64 = 10485760 ; //10 MiB
56
-
53
+ pub const CURRENT_HOT_TIER_VERSION : & str = "v2" ;
57
54
#[ derive( Debug , serde:: Deserialize , serde:: Serialize ) ]
58
55
pub struct StreamHotTier {
56
+ pub version : Option < String > ,
59
57
#[ serde( rename = "size" ) ]
60
58
pub size : String ,
61
59
#[ serde( skip_serializing_if = "Option::is_none" ) ]
@@ -97,9 +95,13 @@ impl HotTierManager {
97
95
for stream in STREAM_INFO . list_streams ( ) {
98
96
if self . check_stream_hot_tier_exists ( & stream) && stream != current_stream {
99
97
let stream_hot_tier = self . get_hot_tier ( & stream) . await ?;
100
- total_hot_tier_size += human_size_to_bytes ( & stream_hot_tier. size ) . unwrap ( ) ;
101
- total_hot_tier_used_size +=
102
- human_size_to_bytes ( & stream_hot_tier. used_size . unwrap ( ) ) . unwrap ( ) ;
98
+ total_hot_tier_size += & stream_hot_tier. size . parse :: < u64 > ( ) . unwrap ( ) ;
99
+ total_hot_tier_used_size += & stream_hot_tier
100
+ . used_size
101
+ . clone ( )
102
+ . unwrap ( )
103
+ . parse :: < u64 > ( )
104
+ . unwrap ( ) ;
103
105
}
104
106
}
105
107
Ok ( ( total_hot_tier_size, total_hot_tier_used_size) )
@@ -112,19 +114,21 @@ impl HotTierManager {
112
114
pub async fn validate_hot_tier_size (
113
115
& self ,
114
116
stream : & str ,
115
- size : & str ,
117
+ stream_hot_tier_size : & str ,
116
118
) -> Result < u64 , HotTierError > {
119
+ let stream_hot_tier_size = stream_hot_tier_size. parse :: < u64 > ( ) . unwrap ( ) ;
117
120
let mut existing_hot_tier_used_size = 0 ;
118
121
if self . check_stream_hot_tier_exists ( stream) {
119
122
//delete existing hot tier if its size is less than the updated hot tier size else return error
120
123
let existing_hot_tier = self . get_hot_tier ( stream) . await ?;
121
124
existing_hot_tier_used_size =
122
- human_size_to_bytes ( & existing_hot_tier. used_size . unwrap ( ) ) . unwrap ( ) ;
123
- if human_size_to_bytes ( size) < human_size_to_bytes ( & existing_hot_tier. size ) {
125
+ existing_hot_tier. used_size . unwrap ( ) . parse :: < u64 > ( ) . unwrap ( ) ;
126
+
127
+ if stream_hot_tier_size < existing_hot_tier_used_size {
124
128
return Err ( HotTierError :: ObjectStorageError ( ObjectStorageError :: Custom ( format ! (
125
129
"Reducing hot tier size is not supported, failed to reduce the hot tier size from {} to {}" ,
126
- existing_hot_tier . size ,
127
- size
130
+ bytes_to_human_size ( existing_hot_tier_used_size ) ,
131
+ bytes_to_human_size ( stream_hot_tier_size )
128
132
) ) ) ) ;
129
133
}
130
134
}
@@ -134,7 +138,6 @@ impl HotTierManager {
134
138
if let ( Some ( total_disk_space) , _, Some ( used_disk_space) ) =
135
139
( total_disk_space, available_disk_space, used_disk_space)
136
140
{
137
- let stream_hot_tier_size = human_size_to_bytes ( size) . unwrap ( ) ;
138
141
let ( total_hot_tier_size, total_hot_tier_used_size) =
139
142
self . get_hot_tiers_size ( stream) . await ?;
140
143
let disk_threshold =
@@ -147,7 +150,7 @@ impl HotTierManager {
147
150
148
151
if stream_hot_tier_size as f64 > max_allowed_hot_tier_size {
149
152
log:: error!( "disk_threshold: {}, used_disk_space: {}, total_hot_tier_used_size: {}, existing_hot_tier_used_size: {}, total_hot_tier_size: {}" ,
150
- disk_threshold, used_disk_space, total_hot_tier_used_size, existing_hot_tier_used_size, total_hot_tier_size) ;
153
+ bytes_to_human_size ( disk_threshold as u64 ) , bytes_to_human_size ( used_disk_space) , bytes_to_human_size ( total_hot_tier_used_size) , bytes_to_human_size ( existing_hot_tier_used_size) , bytes_to_human_size ( total_hot_tier_size) ) ;
151
154
return Err ( HotTierError :: ObjectStorageError ( ObjectStorageError :: Custom ( format ! (
152
155
"{} is the total usable disk space for hot tier, cannot set a bigger value." , bytes_to_human_size( max_allowed_hot_tier_size as u64 )
153
156
) ) ) ) ;
@@ -255,8 +258,12 @@ impl HotTierManager {
255
258
/// delete the files from the hot tier directory if the available date range is outside the hot tier range
256
259
async fn process_stream ( & self , stream : String ) -> Result < ( ) , HotTierError > {
257
260
let stream_hot_tier = self . get_hot_tier ( & stream) . await ?;
258
- let mut parquet_file_size =
259
- human_size_to_bytes ( stream_hot_tier. used_size . as_ref ( ) . unwrap ( ) ) . unwrap ( ) ;
261
+ let mut parquet_file_size = stream_hot_tier
262
+ . used_size
263
+ . as_ref ( )
264
+ . unwrap ( )
265
+ . parse :: < u64 > ( )
266
+ . unwrap ( ) ;
260
267
261
268
let object_store = CONFIG . storage ( ) . get_object_store ( ) ;
262
269
let mut s3_manifest_file_list = object_store. list_manifest_files ( & stream) . await ?;
@@ -348,7 +355,12 @@ impl HotTierManager {
348
355
let mut file_processed = false ;
349
356
let mut stream_hot_tier = self . get_hot_tier ( stream) . await ?;
350
357
if !self . is_disk_available ( parquet_file. file_size ) . await ?
351
- || human_size_to_bytes ( & stream_hot_tier. available_size . clone ( ) . unwrap ( ) ) . unwrap ( )
358
+ || stream_hot_tier
359
+ . available_size
360
+ . as_ref ( )
361
+ . unwrap ( )
362
+ . parse :: < u64 > ( )
363
+ . unwrap ( )
352
364
<= parquet_file. file_size
353
365
{
354
366
if !self
@@ -362,8 +374,12 @@ impl HotTierManager {
362
374
{
363
375
return Ok ( file_processed) ;
364
376
}
365
- * parquet_file_size =
366
- human_size_to_bytes ( & stream_hot_tier. used_size . clone ( ) . unwrap ( ) ) . unwrap ( ) ;
377
+ * parquet_file_size = stream_hot_tier
378
+ . used_size
379
+ . as_ref ( )
380
+ . unwrap ( )
381
+ . parse :: < u64 > ( )
382
+ . unwrap ( ) ;
367
383
}
368
384
let parquet_file_path = RelativePathBuf :: from ( parquet_file. file_path . clone ( ) ) ;
369
385
fs:: create_dir_all ( parquet_path. parent ( ) . unwrap ( ) ) . await ?;
@@ -375,12 +391,18 @@ impl HotTierManager {
375
391
. await ?;
376
392
file. write_all ( & parquet_data) . await ?;
377
393
* parquet_file_size += parquet_file. file_size ;
378
- stream_hot_tier. used_size = Some ( bytes_to_human_size ( * parquet_file_size) ) ;
379
-
380
- stream_hot_tier. available_size = Some ( bytes_to_human_size (
381
- human_size_to_bytes ( & stream_hot_tier. available_size . clone ( ) . unwrap ( ) ) . unwrap ( )
382
- - parquet_file. file_size ,
383
- ) ) ;
394
+ stream_hot_tier. used_size = Some ( parquet_file_size. to_string ( ) ) ;
395
+
396
+ stream_hot_tier. available_size = Some (
397
+ ( stream_hot_tier
398
+ . available_size
399
+ . as_ref ( )
400
+ . unwrap ( )
401
+ . parse :: < u64 > ( )
402
+ . unwrap ( )
403
+ - parquet_file. file_size )
404
+ . to_string ( ) ,
405
+ ) ;
384
406
self . put_hot_tier ( stream, & mut stream_hot_tier) . await ?;
385
407
file_processed = true ;
386
408
let mut hot_tier_manifest = self
@@ -583,20 +605,34 @@ impl HotTierManager {
583
605
fs:: remove_dir_all ( path_to_delete. parent ( ) . unwrap ( ) ) . await ?;
584
606
delete_empty_directory_hot_tier ( path_to_delete. parent ( ) . unwrap ( ) ) . await ?;
585
607
586
- stream_hot_tier. used_size = Some ( bytes_to_human_size (
587
- human_size_to_bytes ( & stream_hot_tier. used_size . clone ( ) . unwrap ( ) )
608
+ stream_hot_tier. used_size = Some (
609
+ ( stream_hot_tier
610
+ . used_size
611
+ . as_ref ( )
588
612
. unwrap ( )
589
- - file_size,
590
- ) ) ;
591
- stream_hot_tier. available_size = Some ( bytes_to_human_size (
592
- human_size_to_bytes ( & stream_hot_tier. available_size . clone ( ) . unwrap ( ) )
613
+ . parse :: < u64 > ( )
593
614
. unwrap ( )
594
- + file_size,
595
- ) ) ;
615
+ - file_size)
616
+ . to_string ( ) ,
617
+ ) ;
618
+ stream_hot_tier. available_size = Some (
619
+ ( stream_hot_tier
620
+ . available_size
621
+ . as_ref ( )
622
+ . unwrap ( )
623
+ . parse :: < u64 > ( )
624
+ . unwrap ( )
625
+ + file_size)
626
+ . to_string ( ) ,
627
+ ) ;
596
628
self . put_hot_tier ( stream, stream_hot_tier) . await ?;
597
629
delete_successful = true ;
598
630
599
- if human_size_to_bytes ( & stream_hot_tier. available_size . clone ( ) . unwrap ( ) )
631
+ if stream_hot_tier
632
+ . available_size
633
+ . as_ref ( )
634
+ . unwrap ( )
635
+ . parse :: < u64 > ( )
600
636
. unwrap ( )
601
637
<= parquet_file_size
602
638
{
@@ -679,7 +715,7 @@ impl HotTierManager {
679
715
. to_string_lossy ( )
680
716
. trim_start_matches ( "minute=" )
681
717
. to_string ( ) ;
682
- let oldest_date_time = format ! ( "{} {}:{}:00" , date, hour_str, minute_str) ;
718
+ let oldest_date_time = format ! ( "{}T {}:{}:00.000Z " , date, hour_str, minute_str) ;
683
719
return Ok ( Some ( oldest_date_time) ) ;
684
720
}
685
721
}
@@ -693,6 +729,7 @@ impl HotTierManager {
693
729
&& !self . check_stream_hot_tier_exists ( INTERNAL_STREAM_NAME )
694
730
{
695
731
let mut stream_hot_tier = StreamHotTier {
732
+ version : Some ( CURRENT_HOT_TIER_VERSION . to_string ( ) ) ,
696
733
size : INTERNAL_STREAM_HOT_TIER_SIZE_BYTES . to_string ( ) ,
697
734
used_size : Some ( "0" . to_string ( ) ) ,
698
735
available_size : Some ( INTERNAL_STREAM_HOT_TIER_SIZE_BYTES . to_string ( ) ) ,
0 commit comments