@@ -566,21 +566,51 @@ pub async fn remove_item<K: Key, S: MultiwriteNorFlash>(
566
566
flash_range. clone( ) ,
567
567
cache,
568
568
data_buffer,
569
- search_key. clone( )
569
+ Some ( search_key. clone( ) )
570
570
)
571
571
. await ,
572
572
repair = try_repair:: <K , _>( flash, flash_range. clone( ) , cache, data_buffer) . await ?
573
573
)
574
574
}
575
575
576
+ /// Fully remove all stored items. Additional calls to fetch with any key will return None until
577
+ /// new items are stored again.
578
+ ///
579
+ /// <div class="warning">
580
+ /// This might be really slow!
581
+ /// </div>
582
+ ///
583
+ /// <div class="warning">
584
+ ///
585
+ /// *You are required to, on a given flash range, use the same [Key] type every time. You are allowed to use*
586
+ /// *multiple [Value] types. See the module-level docs for more information about this.*
587
+ ///
588
+ /// </div>
589
+ pub async fn remove_all_items < K : Key , S : MultiwriteNorFlash > (
590
+ flash : & mut S ,
591
+ flash_range : Range < u32 > ,
592
+ cache : & mut impl KeyCacheImpl < K > ,
593
+ data_buffer : & mut [ u8 ] ,
594
+ ) -> Result < ( ) , Error < S :: Error > > {
595
+ run_with_auto_repair ! (
596
+ function =
597
+ remove_item_inner:: <K , _>( flash, flash_range. clone( ) , cache, data_buffer, None ) . await ,
598
+ repair = try_repair:: <K , _>( flash, flash_range. clone( ) , cache, data_buffer) . await ?
599
+ )
600
+ }
601
+
576
602
async fn remove_item_inner < K : Key , S : MultiwriteNorFlash > (
577
603
flash : & mut S ,
578
604
flash_range : Range < u32 > ,
579
605
cache : & mut impl KeyCacheImpl < K > ,
580
606
data_buffer : & mut [ u8 ] ,
581
- search_key : K ,
607
+ search_key : Option < K > ,
582
608
) -> Result < ( ) , Error < S :: Error > > {
583
- cache. notice_key_erased ( & search_key) ;
609
+ if let Some ( key) = & search_key {
610
+ cache. notice_key_erased ( key) ;
611
+ } else {
612
+ cache. invalidate_cache_state ( ) ;
613
+ }
584
614
585
615
// Search for the last used page. We're gonna erase from the one after this first.
586
616
// If we get an early shutoff or cancellation, this will make it so that we don't return
@@ -620,11 +650,15 @@ async fn remove_item_inner<K: Key, S: MultiwriteNorFlash>(
620
650
item:: MaybeItem :: Corrupted ( _, _) => continue ,
621
651
item:: MaybeItem :: Erased ( _, _) => continue ,
622
652
item:: MaybeItem :: Present ( item) => {
623
- let ( item_key, _) = K :: deserialize_from ( item. data ( ) ) ?;
624
-
653
+ let item_match = if let Some ( search_key) = & search_key {
654
+ let ( item_key, _) = K :: deserialize_from ( item. data ( ) ) ?;
655
+ & item_key == search_key
656
+ } else {
657
+ false
658
+ } ;
625
659
// If this item has the same key as the key we're trying to erase, then erase the item.
626
660
// But keep going! We need to erase everything.
627
- if item_key == search_key {
661
+ if search_key . is_none ( ) || item_match {
628
662
item. header
629
663
. erase_data ( flash, flash_range. clone ( ) , cache, item_address)
630
664
. await ?;
@@ -1357,6 +1391,71 @@ mod tests {
1357
1391
}
1358
1392
}
1359
1393
1394
+ #[ test]
1395
+ async fn remove_all ( ) {
1396
+ let mut flash = mock_flash:: MockFlashBase :: < 4 , 1 , 4096 > :: new (
1397
+ mock_flash:: WriteCountCheck :: Twice ,
1398
+ None ,
1399
+ true ,
1400
+ ) ;
1401
+ let mut data_buffer = AlignedBuf ( [ 0 ; 128 ] ) ;
1402
+ const FLASH_RANGE : Range < u32 > = 0x0000 ..0x4000 ;
1403
+
1404
+ // Add some data to flash
1405
+ for value in 0 ..10 {
1406
+ for key in 0 ..24 {
1407
+ store_item (
1408
+ & mut flash,
1409
+ FLASH_RANGE ,
1410
+ & mut cache:: NoCache :: new ( ) ,
1411
+ & mut data_buffer,
1412
+ key as u8 ,
1413
+ & vec ! [ key as u8 ; value + 2 ] . as_slice ( ) ,
1414
+ )
1415
+ . await
1416
+ . unwrap ( ) ;
1417
+ }
1418
+ }
1419
+
1420
+ // Sanity check that we can find all the keys we just added.
1421
+ for key in 0 ..24 {
1422
+ assert ! ( fetch_item:: <u8 , & [ u8 ] , _>(
1423
+ & mut flash,
1424
+ FLASH_RANGE ,
1425
+ & mut cache:: NoCache :: new( ) ,
1426
+ & mut data_buffer,
1427
+ key
1428
+ )
1429
+ . await
1430
+ . unwrap( )
1431
+ . is_some( ) ) ;
1432
+ }
1433
+
1434
+ // Remove all the items
1435
+ remove_all_items :: < u8 , _ > (
1436
+ & mut flash,
1437
+ FLASH_RANGE ,
1438
+ & mut cache:: NoCache :: new ( ) ,
1439
+ & mut data_buffer,
1440
+ )
1441
+ . await
1442
+ . unwrap ( ) ;
1443
+
1444
+ // Verify that none of the keys are present in flash.
1445
+ for key in 0 ..24 {
1446
+ assert ! ( fetch_item:: <u8 , & [ u8 ] , _>(
1447
+ & mut flash,
1448
+ FLASH_RANGE ,
1449
+ & mut cache:: NoCache :: new( ) ,
1450
+ & mut data_buffer,
1451
+ key
1452
+ )
1453
+ . await
1454
+ . unwrap( )
1455
+ . is_none( ) ) ;
1456
+ }
1457
+ }
1458
+
1360
1459
#[ test]
1361
1460
async fn store_too_big_item ( ) {
1362
1461
let mut flash = MockFlashBig :: new ( mock_flash:: WriteCountCheck :: Twice , None , true ) ;
0 commit comments