| ... | ... | @@ -309,7 +309,6 @@ pub const ExportSymbol = struct { |
| 309 | 309 | /// This operation may change the layout of the trie by splicing edges in |
| 310 | 310 | /// certain circumstances. |
| 311 | 311 | pub fn put(self: *Trie, allocator: Allocator, symbol: ExportSymbol) !void { |
| 312 | | try self.createRoot(allocator); |
| 313 | 312 | const node = try self.root.?.put(allocator, symbol.name); |
| 314 | 313 | node.terminal_info = .{ |
| 315 | 314 | .vmaddr_offset = symbol.vmaddr_offset, |
| ... | ... | @@ -362,7 +361,6 @@ const ReadError = error{ |
| 362 | 361 | |
| 363 | 362 | /// Parse the trie from a byte stream. |
| 364 | 363 | pub fn read(self: *Trie, allocator: Allocator, reader: anytype) ReadError!usize { |
| 365 | | try self.createRoot(allocator); |
| 366 | 364 | return self.root.?.read(allocator, reader); |
| 367 | 365 | } |
| 368 | 366 | |
| ... | ... | @@ -377,6 +375,14 @@ pub fn write(self: Trie, writer: anytype) !u64 { |
| 377 | 375 | return counting_writer.bytes_written; |
| 378 | 376 | } |
| 379 | 377 | |
| 378 | pub fn init(self: *Trie, allocator: Allocator) !void { |
| 379 | assert(self.root == null); |
| 380 | const root = try allocator.create(Node); |
| 381 | root.* = .{ .base = self }; |
| 382 | self.root = root; |
| 383 | self.node_count += 1; |
| 384 | } |
| 385 | |
| 380 | 386 | pub fn deinit(self: *Trie, allocator: Allocator) void { |
| 381 | 387 | if (self.root) |root| { |
| 382 | 388 | root.deinit(allocator); |
| ... | ... | @@ -385,19 +391,11 @@ pub fn deinit(self: *Trie, allocator: Allocator) void { |
| 385 | 391 | self.ordered_nodes.deinit(allocator); |
| 386 | 392 | } |
| 387 | 393 | |
| 388 | | fn createRoot(self: *Trie, allocator: Allocator) !void { |
| 389 | | if (self.root == null) { |
| 390 | | const root = try allocator.create(Node); |
| 391 | | root.* = .{ .base = self }; |
| 392 | | self.root = root; |
| 393 | | self.node_count += 1; |
| 394 | | } |
| 395 | | } |
| 396 | | |
| 397 | 394 | test "Trie node count" { |
| 398 | 395 | var gpa = testing.allocator; |
| 399 | 396 | var trie: Trie = .{}; |
| 400 | 397 | defer trie.deinit(gpa); |
| 398 | try trie.init(gpa); |
| 401 | 399 | |
| 402 | 400 | try testing.expectEqual(trie.node_count, 0); |
| 403 | 401 | try testing.expect(trie.root == null); |
| ... | ... | @@ -443,6 +441,7 @@ test "Trie basic" { |
| 443 | 441 | var gpa = testing.allocator; |
| 444 | 442 | var trie: Trie = .{}; |
| 445 | 443 | defer trie.deinit(gpa); |
| 444 | try trie.init(gpa); |
| 446 | 445 | |
| 447 | 446 | // root --- _st ---> node |
| 448 | 447 | try trie.put(gpa, .{ |
| ... | ... | @@ -508,6 +507,7 @@ test "write Trie to a byte stream" { |
| 508 | 507 | var gpa = testing.allocator; |
| 509 | 508 | var trie: Trie = .{}; |
| 510 | 509 | defer trie.deinit(gpa); |
| 510 | try trie.init(gpa); |
| 511 | 511 | |
| 512 | 512 | try trie.put(gpa, .{ |
| 513 | 513 | .name = "__mh_execute_header", |
| ... | ... | @@ -566,6 +566,7 @@ test "parse Trie from byte stream" { |
| 566 | 566 | var in_stream = std.io.fixedBufferStream(&in_buffer); |
| 567 | 567 | var trie: Trie = .{}; |
| 568 | 568 | defer trie.deinit(gpa); |
| 569 | try trie.init(gpa); |
| 569 | 570 | const nread = try trie.read(gpa, in_stream.reader()); |
| 570 | 571 | |
| 571 | 572 | try testing.expect(nread == in_buffer.len); |
| ... | ... | @@ -583,6 +584,7 @@ test "ordering bug" { |
| 583 | 584 | var gpa = testing.allocator; |
| 584 | 585 | var trie: Trie = .{}; |
| 585 | 586 | defer trie.deinit(gpa); |
| 587 | try trie.init(gpa); |
| 586 | 588 | |
| 587 | 589 | try trie.put(gpa, .{ |
| 588 | 590 | .name = "_asStr", |