Avoid unnecessary copy of document text when opening new imports
This commit is contained in:
parent
60ffc5f551
commit
76e9a079a3
@ -60,6 +60,31 @@ pub fn init(self: *DocumentStore, allocator: *std.mem.Allocator, zig_lib_path: ?
|
||||
}
|
||||
}
|
||||
|
||||
/// This function assersts the document is not open yet and takes owneship
|
||||
/// of the uri and text passed in.
|
||||
fn newDocument(self: *DocumentStore, uri: []const u8, text: []u8) !*Handle {
|
||||
std.debug.warn("Opened document: {}\n", .{uri});
|
||||
|
||||
errdefer {
|
||||
self.allocator.free(uri);
|
||||
self.allocator.free(text);
|
||||
}
|
||||
|
||||
var handle = Handle{
|
||||
.count = 1,
|
||||
.import_uris = std.ArrayList([]const u8).init(self.allocator),
|
||||
.document = .{
|
||||
.uri = uri,
|
||||
.text = text,
|
||||
.mem = text,
|
||||
.sane_text = null,
|
||||
},
|
||||
};
|
||||
try self.checkSanity(&handle);
|
||||
try self.handles.putNoClobber(uri, handle);
|
||||
return &(self.handles.get(uri) orelse unreachable).value;
|
||||
}
|
||||
|
||||
pub fn openDocument(self: *DocumentStore, uri: []const u8, text: []const u8) !*Handle {
|
||||
if (self.handles.get(uri)) |entry| {
|
||||
std.debug.warn("Document already open: {}, incrementing count\n", .{uri});
|
||||
@ -68,25 +93,12 @@ pub fn openDocument(self: *DocumentStore, uri: []const u8, text: []const u8) !*H
|
||||
return &entry.value;
|
||||
}
|
||||
|
||||
std.debug.warn("Opened document: {}\n", .{uri});
|
||||
const duped_text = try std.mem.dupe(self.allocator, u8, text);
|
||||
errdefer self.allocator.free(duped_text);
|
||||
const duped_uri = try std.mem.dupe(self.allocator, u8, uri);
|
||||
errdefer self.allocator.free(duped_uri);
|
||||
|
||||
var handle = Handle{
|
||||
.count = 1,
|
||||
.import_uris = std.ArrayList([]const u8).init(self.allocator),
|
||||
.document = .{
|
||||
.uri = duped_uri,
|
||||
.text = duped_text,
|
||||
.mem = duped_text,
|
||||
.sane_text = null,
|
||||
},
|
||||
};
|
||||
try self.checkSanity(&handle);
|
||||
try self.handles.putNoClobber(duped_uri, handle);
|
||||
return &(self.handles.get(duped_uri) orelse unreachable).value;
|
||||
return self.newDocument(duped_uri, duped_text);
|
||||
}
|
||||
|
||||
fn decrementCount(self: *DocumentStore, uri: []const u8) void {
|
||||
@ -243,8 +255,6 @@ pub const ImportContext = struct {
|
||||
var consumed_final_uri = false;
|
||||
defer if (!consumed_final_uri) allocator.free(final_uri);
|
||||
|
||||
// @TODO Clean up code, lots of repetition
|
||||
{
|
||||
// Check if we already imported this.
|
||||
for (self.handle.import_uris.items) |uri| {
|
||||
// If we did, set our new handle and return the parsed tree root node.
|
||||
@ -257,7 +267,6 @@ pub const ImportContext = struct {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// New import.
|
||||
// Check if the import is already opened by others.
|
||||
@ -284,9 +293,9 @@ pub const ImportContext = struct {
|
||||
defer file.close();
|
||||
const size = std.math.cast(usize, try file.getEndPos()) catch std.math.maxInt(usize);
|
||||
|
||||
// TODO: This is wasteful, we know we don't need to copy the text on this openDocument call
|
||||
{
|
||||
const file_contents = try allocator.alloc(u8, size);
|
||||
defer allocator.free(file_contents);
|
||||
errdefer allocator.free(file_contents);
|
||||
|
||||
file.inStream().readNoEof(file_contents) catch {
|
||||
std.debug.warn("Could not read from file {}\n", .{file_path});
|
||||
@ -296,8 +305,11 @@ pub const ImportContext = struct {
|
||||
// Add to import table of current handle.
|
||||
try self.handle.import_uris.append(final_uri);
|
||||
consumed_final_uri = true;
|
||||
|
||||
// Swap handles and get new tree.
|
||||
self.handle = try openDocument(self.store, final_uri, file_contents);
|
||||
// This takes ownership of the passed uri and text.
|
||||
self.handle = try newDocument(self.store, try std.mem.dupe(allocator, u8, final_uri), file_contents);
|
||||
}
|
||||
|
||||
if (try self.handle.saneTree(allocator)) |tree| {
|
||||
try self.trees.append(tree);
|
||||
|
Loading…
Reference in New Issue
Block a user