MIRROR: javascript for 馃悳's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 127 lines 3.4 kB view raw
1const std = @import("std"); 2 3pub const InternedString = struct { 4 ptr: [*]const u8, 5 len: u32, 6 7 pub fn slice(self: InternedString) []const u8 { 8 return self.ptr[0..self.len]; 9 } 10 11 pub fn eql(a: InternedString, b: InternedString) bool { 12 return a.ptr == b.ptr and a.len == b.len; 13 } 14 15 pub fn hash(self: InternedString) u64 { 16 return @intFromPtr(self.ptr); 17 } 18 19 pub const empty: InternedString = .{ .ptr = "", .len = 0 }; 20}; 21 22pub const StringPool = struct { 23 allocator: std.mem.Allocator, 24 strings: std.StringHashMap(InternedString), 25 storage: std.ArrayListUnmanaged([]const u8), 26 27 pub fn init(allocator: std.mem.Allocator) StringPool { 28 return .{ 29 .allocator = allocator, 30 .strings = std.StringHashMap(InternedString).init(allocator), 31 .storage = std.ArrayListUnmanaged([]const u8){}, 32 }; 33 } 34 35 pub fn deinit(self: *StringPool) void { 36 for (self.storage.items) |s| { 37 self.allocator.free(s); 38 } 39 self.storage.deinit(self.allocator); 40 self.strings.deinit(); 41 } 42 43 pub fn intern(self: *StringPool, str: []const u8) !InternedString { 44 if (str.len == 0) return InternedString.empty; 45 if (self.strings.get(str)) |interned| return interned; 46 47 const owned = try self.allocator.dupe(u8, str); 48 errdefer self.allocator.free(owned); 49 50 try self.storage.append(self.allocator, owned); 51 52 const interned = InternedString{ 53 .ptr = owned.ptr, 54 .len = @intCast(owned.len), 55 }; 56 57 try self.strings.put(owned, interned); 58 return interned; 59 } 60 61 pub fn internOwned(self: *StringPool, owned: []const u8) !InternedString { 62 if (owned.len == 0) return InternedString.empty; 63 64 if (self.strings.get(owned)) |interned| { 65 self.allocator.free(@constCast(owned)); 66 return interned; 67 } 68 69 try self.storage.append(self.allocator, owned); 70 71 const interned = InternedString{ 72 .ptr = owned.ptr, 73 .len = @intCast(owned.len), 74 }; 75 76 try self.strings.put(owned, interned); 77 return interned; 78 } 79 80 pub fn stats(self: *const StringPool) Stats { 81 var total_bytes: usize = 0; 82 for (self.storage.items) |s| { 83 total_bytes += s.len; 84 } 85 return .{ 86 .string_count = self.storage.items.len, 87 .total_bytes = total_bytes, 88 }; 89 } 90 91 pub const Stats = struct { 92 string_count: usize, 93 total_bytes: usize, 94 }; 95}; 96 97pub const CommonStrings = struct { 98 pool: *StringPool, 99 100 lodash: InternedString = InternedString.empty, 101 react: InternedString = InternedString.empty, 102 typescript: InternedString = InternedString.empty, 103 webpack: InternedString = InternedString.empty, 104 babel: InternedString = InternedString.empty, 105 eslint: InternedString = InternedString.empty, 106 jest: InternedString = InternedString.empty, 107 express: InternedString = InternedString.empty, 108 109 caret: InternedString = InternedString.empty, // ^ 110 tilde: InternedString = InternedString.empty, // ~ 111 112 pub fn init(pool: *StringPool) !CommonStrings { 113 return .{ 114 .pool = pool, 115 .lodash = try pool.intern("lodash"), 116 .react = try pool.intern("react"), 117 .typescript = try pool.intern("typescript"), 118 .webpack = try pool.intern("webpack"), 119 .babel = try pool.intern("@babel/core"), 120 .eslint = try pool.intern("eslint"), 121 .jest = try pool.intern("jest"), 122 .express = try pool.intern("express"), 123 .caret = try pool.intern("^"), 124 .tilde = try pool.intern("~"), 125 }; 126 } 127};