Skip to content

Commit

Permalink
improve(allocators): improve DiskMemoryAllocator (#259)
Browse files Browse the repository at this point in the history
* Improve DiskMemoryAllocator

* Remove outdated comment

* Move `Metadata` and use `u32` for file count

* `fullMmapSize` => `alignedFileSize` & reformatting

* Fix resize bug from invalid assumptions

* Init `DiskMemoryAllocator` directly

* Improve `resize`

* Make `resize` more intelligent & add `mmap_ratio`
Also add test using the `std.heap.testAllocator*` functions.

* Add mmap_size to Metadata, avoid resize:munmap

* Document `mmap_size` metadata, make cross-platform

* Move tests to bottom of file

* Simplify and fix mmap_ratio

* Amend & elaborate DMA docs
  • Loading branch information
InKryption committed Sep 26, 2024
1 parent bee9622 commit 9ccbaa9
Show file tree
Hide file tree
Showing 5 changed files with 292 additions and 183 deletions.
62 changes: 27 additions & 35 deletions src/accountsdb/db.zig
Original file line number Diff line number Diff line change
Expand Up @@ -216,15 +216,16 @@ pub const AccountsDB = struct {
const reference_allocator: std.mem.Allocator //
= blk: {
if (config.use_disk_index) {
var index_bin_dir = try snapshot_dir.makeOpenPath("index/bin", .{});
defer index_bin_dir.close();
var index_bin_dir = try snapshot_dir.makeOpenPath("index", .{});
errdefer index_bin_dir.close();

const disk_file_suffix = try index_bin_dir.realpathAlloc(allocator, ".");
errdefer allocator.free(disk_file_suffix);
logger.infof("using disk index in {s}", .{disk_file_suffix});
logger.infof("using disk index in {s}", .{sig.utils.fmt.tryRealPath(index_bin_dir, ".")});

const ptr = try allocator.create(DiskMemoryAllocator);
ptr.* = DiskMemoryAllocator.init(disk_file_suffix);
ptr.* = .{
.dir = index_bin_dir,
.logger = logger,
};

break :blk .{ ptr, ptr.allocator() };
} else {
Expand All @@ -233,7 +234,7 @@ pub const AccountsDB = struct {
}
};
errdefer if (maybe_disk_allocator_ptr) |ptr| {
ptr.deinit(allocator);
ptr.dir.close();
allocator.destroy(ptr);
};

Expand Down Expand Up @@ -266,19 +267,10 @@ pub const AccountsDB = struct {
};
}

pub fn deinit(
self: *Self,
delete_index_files: bool,
) void {
pub fn deinit(self: *Self) void {
self.account_index.deinit(true);
if (self.disk_allocator_ptr) |ptr| {
// note: we dont always deinit the allocator so we keep the index files
// because they are expensive to generate
if (delete_index_files) {
ptr.deinit(self.allocator);
} else {
self.allocator.free(ptr.filepath);
}
ptr.dir.close();
self.allocator.destroy(ptr);
}

Expand Down Expand Up @@ -3229,7 +3221,7 @@ test "testWriteSnapshot" {
.number_of_index_bins = ACCOUNT_INDEX_BINS,
.use_disk_index = false,
}, null);
defer accounts_db.deinit(true);
defer accounts_db.deinit();

try testWriteSnapshotFull(&accounts_db, snap_files.full_snapshot.slot, snap_files.full_snapshot.hash);
try testWriteSnapshotIncremental(&accounts_db, snap_files.incremental_snapshot.?.slot, snap_files.incremental_snapshot.?.hash);
Expand Down Expand Up @@ -3288,7 +3280,7 @@ fn loadTestAccountsDB(allocator: std.mem.Allocator, use_disk: bool, n_threads: u
.number_of_index_bins = 4,
.use_disk_index = use_disk,
}, null);
errdefer accounts_db.deinit(true);
errdefer accounts_db.deinit();

_ = try accounts_db.loadFromSnapshot(snapshot.accounts_db_fields, n_threads, allocator, 1_500);

Expand Down Expand Up @@ -3358,7 +3350,7 @@ test "geyser stream on load" {
geyser_writer,
);
defer {
accounts_db.deinit(true);
accounts_db.deinit();
snapshots.deinit(allocator);
}

Expand All @@ -3378,7 +3370,7 @@ test "write and read an account" {

var accounts_db, var snapshots = try loadTestAccountsDB(std.testing.allocator, false, 1);
defer {
accounts_db.deinit(true);
accounts_db.deinit();
snapshots.deinit(allocator);
}

Expand Down Expand Up @@ -3415,7 +3407,7 @@ test "load and validate from test snapshot using disk index" {

var accounts_db, var snapshots = try loadTestAccountsDB(std.testing.allocator, false, 1);
defer {
accounts_db.deinit(true);
accounts_db.deinit();
snapshots.deinit(allocator);
}

Expand All @@ -3432,7 +3424,7 @@ test "load and validate from test snapshot parallel" {

var accounts_db, var snapshots = try loadTestAccountsDB(std.testing.allocator, false, 2);
defer {
accounts_db.deinit(true);
accounts_db.deinit();
snapshots.deinit(allocator);
}

Expand All @@ -3449,7 +3441,7 @@ test "load and validate from test snapshot" {

var accounts_db, var snapshots = try loadTestAccountsDB(std.testing.allocator, false, 1);
defer {
accounts_db.deinit(true);
accounts_db.deinit();
snapshots.deinit(allocator);
}

Expand All @@ -3466,7 +3458,7 @@ test "load clock sysvar" {

var accounts_db, var snapshots = try loadTestAccountsDB(std.testing.allocator, false, 1);
defer {
accounts_db.deinit(true);
accounts_db.deinit();
snapshots.deinit(allocator);
}

Expand All @@ -3486,7 +3478,7 @@ test "load other sysvars" {

var accounts_db, var snapshots = try loadTestAccountsDB(std.testing.allocator, false, 1);
defer {
accounts_db.deinit(true);
accounts_db.deinit();
snapshots.deinit(allocator);
}

Expand All @@ -3513,7 +3505,7 @@ test "flushing slots works" {
.number_of_index_bins = 4,
.use_disk_index = false,
}, null);
defer accounts_db.deinit(true);
defer accounts_db.deinit();

var random = std.rand.DefaultPrng.init(19);
const rng = random.random();
Expand Down Expand Up @@ -3564,7 +3556,7 @@ test "purge accounts in cache works" {
.number_of_index_bins = 4,
.use_disk_index = false,
}, null);
defer accounts_db.deinit(true);
defer accounts_db.deinit();

var random = std.rand.DefaultPrng.init(19);
const rng = random.random();
Expand Down Expand Up @@ -3621,7 +3613,7 @@ test "clean to shrink account file works with zero-lamports" {
.number_of_index_bins = 4,
.use_disk_index = false,
}, null);
defer accounts_db.deinit(true);
defer accounts_db.deinit();

var random = std.rand.DefaultPrng.init(19);
const rng = random.random();
Expand Down Expand Up @@ -3697,7 +3689,7 @@ test "clean to shrink account file works" {
.number_of_index_bins = 4,
.use_disk_index = false,
}, null);
defer accounts_db.deinit(true);
defer accounts_db.deinit();

var random = std.rand.DefaultPrng.init(19);
const rng = random.random();
Expand Down Expand Up @@ -3765,7 +3757,7 @@ test "full clean account file works" {
.number_of_index_bins = 4,
.use_disk_index = false,
}, null);
defer accounts_db.deinit(true);
defer accounts_db.deinit();

var random = std.rand.DefaultPrng.init(19);
const rng = random.random();
Expand Down Expand Up @@ -3850,7 +3842,7 @@ test "shrink account file works" {
.number_of_index_bins = 4,
.use_disk_index = false,
}, null);
defer accounts_db.deinit(true);
defer accounts_db.deinit();

var random = std.rand.DefaultPrng.init(19);
const rng = random.random();
Expand Down Expand Up @@ -4051,7 +4043,7 @@ pub const BenchmarkAccountsDBSnapshotLoad = struct {
.number_of_index_bins = 32,
.use_disk_index = bench_args.use_disk,
}, null);
defer accounts_db.deinit(false);
defer accounts_db.deinit();

var accounts_dir = try std.fs.cwd().openDir(accounts_path, .{ .iterate = true });
defer accounts_dir.close();
Expand Down Expand Up @@ -4235,7 +4227,7 @@ pub const BenchmarkAccountsDB = struct {
.number_of_index_bins = ACCOUNT_INDEX_BINS,
.use_disk_index = bench_args.index == .disk,
}, null);
defer accounts_db.deinit(true);
defer accounts_db.deinit();

var random = std.Random.DefaultPrng.init(19);
const rng = random.random();
Expand Down
4 changes: 2 additions & 2 deletions src/accountsdb/fuzz.zig
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ pub fn run(seed: u64, args: *std.process.ArgIterator) !void {
},
null,
);
defer accounts_db.deinit(true);
defer accounts_db.deinit();

const exit = try gpa.create(std.atomic.Value(bool));
defer gpa.destroy(exit);
Expand Down Expand Up @@ -326,7 +326,7 @@ pub fn run(seed: u64, args: *std.process.ArgIterator) !void {
defer snapshot_fields.deinit(allocator);

var alt_accounts_db = try AccountsDB.init(std.heap.page_allocator, .noop, alternative_snapshot_dir, accounts_db.config, null);
defer alt_accounts_db.deinit(true);
defer alt_accounts_db.deinit();

_ = try alt_accounts_db.loadWithDefaults(&snapshot_fields, 1, true, 1_500);
const maybe_inc_slot = if (snapshot_files.incremental_snapshot) |inc| inc.slot else null;
Expand Down
13 changes: 9 additions & 4 deletions src/accountsdb/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,17 @@ to support disk-based account references, we created a general purpose
disk allocator which creates memory from mmap-ing files stored on disk.

```zig
// files are created using `data/test-data/tmp_{i}` format where `i` is
// incremented by one for each alloc call.
var allocator = try DiskMemoryAllocator.init("data/test-data/tmp");
defer allocator.deinit(null);
// files are created using `data/test-data/bin_{i}` format where `i` is
// incremented by one for each new allocation.
var dma_dir = try std.fs.cwd().makeOpenPath("data/test-data");
defer dma_dir.close();
var dma_state: DiskMemoryAllocator = .{};
const dma = dma_state.allocator();
```

Unlike a simpler page allocator, it stores certain metadata after the user-facing
buffer which tracks the associated file, and the true mmap'd size to allow for resizes.

### background-threads

we also run background threads in the `runManagerLoop` method which does the following:
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/cmd.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1346,7 +1346,7 @@ const LoadedSnapshot = struct {
self.genesis_config.deinit(self.allocator);
self.status_cache.deinit(self.allocator);
self.snapshot_fields.deinit(self.allocator);
self.accounts_db.deinit(false); // keep index files on disk
self.accounts_db.deinit();
self.allocator.destroy(self);
}
};
Expand Down Expand Up @@ -1409,7 +1409,7 @@ fn loadSnapshot(
},
geyser_writer,
);
errdefer result.accounts_db.deinit(false);
errdefer result.accounts_db.deinit();

var snapshot_fields = try result.accounts_db.loadWithDefaults(
&all_snapshot_fields,
Expand Down
Loading

0 comments on commit 9ccbaa9

Please sign in to comment.