@@ -4,12 +4,12 @@ use super::{
4
4
Buffer , FileDescriptor , PageAllocator , PageAllocatorRegistry , PageDelta , PageIndex , PageMap ,
5
5
PageMapSerialization ,
6
6
} ;
7
- use crate :: page_map:: TestPageAllocatorFileDescriptorImpl ;
7
+ use crate :: page_map:: { MemoryRegion , TestPageAllocatorFileDescriptorImpl } ;
8
8
use ic_sys:: PAGE_SIZE ;
9
9
use ic_types:: { Height , MAX_STABLE_MEMORY_IN_BYTES } ;
10
10
use nix:: unistd:: dup;
11
- use std:: fs:: OpenOptions ;
12
11
use std:: sync:: Arc ;
12
+ use std:: { fs:: OpenOptions , ops:: Range } ;
13
13
14
14
fn assert_equal_page_maps ( page_map1 : & PageMap , page_map2 : & PageMap ) {
15
15
assert_eq ! ( page_map1. num_host_pages( ) , page_map2. num_host_pages( ) ) ;
@@ -405,3 +405,90 @@ fn calc_dirty_pages_matches_actual_change() {
405
405
)
406
406
. unwrap ( )
407
407
}
408
+
409
+ #[ test]
410
+ fn zeros_region_after_delta ( ) {
411
+ let mut page_map = PageMap :: new_for_testing ( ) ;
412
+ let tmp = tempfile:: Builder :: new ( )
413
+ . prefix ( "checkpoints" )
414
+ . tempdir ( )
415
+ . unwrap ( ) ;
416
+ let heap_file = tmp. path ( ) . join ( "heap" ) ;
417
+ let pages = & [ ( PageIndex :: new ( 1 ) , & [ 1u8 ; PAGE_SIZE ] ) ] ;
418
+ page_map. update ( pages) ;
419
+
420
+ page_map. persist_delta ( & heap_file) . unwrap ( ) ;
421
+
422
+ let mut page_map = PageMap :: open (
423
+ & heap_file,
424
+ Height :: new ( 0 ) ,
425
+ Arc :: new ( TestPageAllocatorFileDescriptorImpl :: new ( ) ) ,
426
+ )
427
+ . unwrap ( ) ;
428
+
429
+ let zero_range = page_map. get_memory_region ( PageIndex :: new ( 5 ) ) ;
430
+ assert_eq ! (
431
+ MemoryRegion :: Zeros ( Range {
432
+ start: PageIndex :: new( 2 ) ,
433
+ end: PageIndex :: new( u64 :: MAX )
434
+ } ) ,
435
+ zero_range
436
+ ) ;
437
+
438
+ let pages = & [ ( PageIndex :: new ( 3 ) , & [ 1u8 ; PAGE_SIZE ] ) ] ;
439
+ page_map. update ( pages) ;
440
+
441
+ let zero_range = page_map. get_memory_region ( PageIndex :: new ( 5 ) ) ;
442
+ assert_eq ! (
443
+ MemoryRegion :: Zeros ( Range {
444
+ start: PageIndex :: new( 4 ) ,
445
+ end: PageIndex :: new( u64 :: MAX )
446
+ } ) ,
447
+ zero_range
448
+ ) ;
449
+ }
450
+
451
+ #[ test]
452
+ fn zeros_region_within_delta ( ) {
453
+ let mut page_map = PageMap :: new_for_testing ( ) ;
454
+ let tmp = tempfile:: Builder :: new ( )
455
+ . prefix ( "checkpoints" )
456
+ . tempdir ( )
457
+ . unwrap ( ) ;
458
+ let heap_file = tmp. path ( ) . join ( "heap" ) ;
459
+ let pages = & [ ( PageIndex :: new ( 1 ) , & [ 1u8 ; PAGE_SIZE ] ) ] ;
460
+ page_map. update ( pages) ;
461
+
462
+ page_map. persist_delta ( & heap_file) . unwrap ( ) ;
463
+
464
+ let mut page_map = PageMap :: open (
465
+ & heap_file,
466
+ Height :: new ( 0 ) ,
467
+ Arc :: new ( TestPageAllocatorFileDescriptorImpl :: new ( ) ) ,
468
+ )
469
+ . unwrap ( ) ;
470
+
471
+ let zero_range = page_map. get_memory_region ( PageIndex :: new ( 5 ) ) ;
472
+ assert_eq ! (
473
+ MemoryRegion :: Zeros ( Range {
474
+ start: PageIndex :: new( 2 ) ,
475
+ end: PageIndex :: new( u64 :: MAX )
476
+ } ) ,
477
+ zero_range
478
+ ) ;
479
+
480
+ let pages = & [
481
+ ( PageIndex :: new ( 3 ) , & [ 1u8 ; PAGE_SIZE ] ) ,
482
+ ( PageIndex :: new ( 10 ) , & [ 1u8 ; PAGE_SIZE ] ) ,
483
+ ] ;
484
+ page_map. update ( pages) ;
485
+
486
+ let zero_range = page_map. get_memory_region ( PageIndex :: new ( 5 ) ) ;
487
+ assert_eq ! (
488
+ MemoryRegion :: Zeros ( Range {
489
+ start: PageIndex :: new( 4 ) ,
490
+ end: PageIndex :: new( 10 )
491
+ } ) ,
492
+ zero_range
493
+ ) ;
494
+ }
0 commit comments