src/storage/blobfs/test/unit/allocator-test.cc
// Create a highly fragmented allocation pool, by allocating every other block,
// and observe that even in the presence of fragmentation we may still acquire
// 100% space utilization.
Create a highly fragmented allocation pool, by allocating every other block,
and observe that even in the presence of fragmentation we may still acquire
100% space utilization.
Create a highly fragmented allocation pool by allocating every other block and observe that even in the presence of fragmentation we may still acquire 100% space utilization .
void RunFragmentationTest(bool keep_even) {
  MockSpaceManager space_manager;
  std::unique_ptr<Allocator> allocator;
  constexpr uint64_t kBlockCount = 16;
  InitializeAllocator(kBlockCount, 4, &space_manager, &allocator);
  fbl::Vector<ReservedExtent> fragmentation_extents[kBlockCount];
  for (uint64_t i = 0; i < kBlockCount; i++) {
    ASSERT_EQ(allocator->ReserveBlocks(1, &fragmentation_extents[i]), ZX_OK);
  }
  fbl::Vector<ReservedExtent> failed_extents;
  ASSERT_EQ(ZX_ERR_NO_SPACE, allocator->ReserveBlocks(1, &failed_extents));
  fbl::Vector<ReservedExtent> big_extent;
  static_assert(kBlockCount % 2 == 0, "Test assumes an even-sized allocation pool");
  for (uint64_t i = keep_even ? 1 : 0; i < kBlockCount; i += 2) {
    fragmentation_extents[i].reset();
  }
  ASSERT_EQ(allocator->ReserveBlocks(kBlockCount / 2, &big_extent), ZX_OK);
  big_extent.reset();
  for (uint64_t i = keep_even ? 0 : 1; i < kBlockCount; i += 2) {
    ASSERT_EQ(1ul, fragmentation_extents[i].size());
    allocator->MarkBlocksAllocated(fragmentation_extents[i][0]);
    fragmentation_extents[i].reset();
  }
  ASSERT_EQ(allocator->ReserveBlocks(kBlockCount / 2, &big_extent), ZX_OK);
  ASSERT_EQ(kBlockCount / 2, big_extent.size());
  ASSERT_EQ(ZX_ERR_NO_SPACE, allocator->ReserveBlocks(1, &failed_extents));
  for (uint64_t i = 0; i < big_extent.size(); i++) {
    allocator->MarkBlocksAllocated(big_extent[i]);
  }
  big_extent.reset();
  ASSERT_EQ(ZX_ERR_NO_SPACE, allocator->ReserveBlocks(1, &failed_extents));
}
void RunFragmentationTest ( bool keep_even ) { MockSpaceManager space_manager ; std :: unique_ptr < Allocator > allocator ; constexpr uint64_t kBlockCount = 16 ; InitializeAllocator ( kBlockCount , 4 , & space_manager , & allocator ) ; fbl :: Vector < ReservedExtent > fragmentation_extents [ kBlockCount ] ; for ( uint64_t i = 0 ; i < kBlockCount ; i ++ ) { ASSERT_EQ ( allocator -> ReserveBlocks ( 1 , & fragmentation_extents [ i ] ) , ZX_OK ) ; } fbl :: Vector < ReservedExtent > failed_extents ; ASSERT_EQ ( ZX_ERR_NO_SPACE , allocator -> ReserveBlocks ( 1 , & failed_extents ) ) ; fbl :: Vector < ReservedExtent > big_extent ; static_assert ( kBlockCount % 2 == 0 , " " ) ; for ( uint64_t i = keep_even ? 1 : 0 ; i < kBlockCount ; i += 2 ) { fragmentation_extents [ i ] . reset ( ) ; } ASSERT_EQ ( allocator -> ReserveBlocks ( kBlockCount / 2 , & big_extent ) , ZX_OK ) ; big_extent . reset ( ) ; for ( uint64_t i = keep_even ? 0 : 1 ; i < kBlockCount ; i += 2 ) { ASSERT_EQ ( 1ul , fragmentation_extents [ i ] . size ( ) ) ; allocator -> MarkBlocksAllocated ( fragmentation_extents [ i ] [ 0 ] ) ; fragmentation_extents [ i ] . reset ( ) ; } ASSERT_EQ ( allocator -> ReserveBlocks ( kBlockCount / 2 , & big_extent ) , ZX_OK ) ; ASSERT_EQ ( kBlockCount / 2 , big_extent . size ( ) ) ; ASSERT_EQ ( ZX_ERR_NO_SPACE , allocator -> ReserveBlocks ( 1 , & failed_extents ) ) ; for ( uint64_t i = 0 ; i < big_extent . size ( ) ; i ++ ) { allocator -> MarkBlocksAllocated ( big_extent [ i ] ) ; } big_extent . reset ( ) ; ASSERT_EQ ( ZX_ERR_NO_SPACE , allocator -> ReserveBlocks ( 1 , & failed_extents ) ) ; }
Create a highly fragmented allocation pool, by allocating every other block,
and observe that even in the presence of fragmentation we may still acquire
100% space utilization.
Create a highly fragmented allocation pool by allocating every other block and observe that even in the presence of fragmentation we may still acquire 100% space utilization .
// Allocate kBlockCount extents of length one. // At this point, there shouldn't be a single block of space left. // Free half of the extents, and demonstrate that we can use all the // remaining fragmented space. // Commit the reserved extents, and observe that our ability to allocate // fragmented extents still persists. // After the big extent is reserved (or committed), however, we cannot reserve // anything more.