Application Context Implementation #4
| @ -23,7 +23,7 @@ pub const Entry = extern struct { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// |     /// | ||||||
|     /// |     /// [FindError.EntryNotFound] happens when an entry could not be found. | ||||||
|     /// |     /// | ||||||
|     pub const FindError = sys.FileAccess.Error || error { |     pub const FindError = sys.FileAccess.Error || error { | ||||||
|         EntryNotFound, |         EntryNotFound, | ||||||
|  | |||||||
							
								
								
									
										26
									
								
								src/sys.zig
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								src/sys.zig
									
									
									
									
									
								
							| @ -8,6 +8,7 @@ const meta = @import("./meta.zig"); | |||||||
| const oar = @import("./oar.zig"); | const oar = @import("./oar.zig"); | ||||||
| const stack = @import("./stack.zig"); | const stack = @import("./stack.zig"); | ||||||
| const std = @import("std"); | const std = @import("std"); | ||||||
|  | const table = @import("./table.zig"); | ||||||
| 
 | 
 | ||||||
| /// | /// | ||||||
| /// A thread-safe platform abstraction over multiplexing system I/O processing and event handling. | /// A thread-safe platform abstraction over multiplexing system I/O processing and event handling. | ||||||
| @ -211,7 +212,9 @@ pub const AppContext = opaque { | |||||||
|     /// |     /// | ||||||
|     /// |     /// | ||||||
|     /// |     /// | ||||||
|     pub fn schedule(app_context: *AppContext, procedure: anytype, arguments: anytype) meta.FnReturn(@TypeOf(procedure)) { |     pub fn schedule(app_context: *AppContext, procedure: anytype, | ||||||
|  |         arguments: anytype) meta.FnReturn(@TypeOf(procedure)) { | ||||||
|  | 
 | ||||||
|         const Task = struct { |         const Task = struct { | ||||||
|             procedure: @TypeOf(procedure), |             procedure: @TypeOf(procedure), | ||||||
|             arguments: *@TypeOf(arguments), |             arguments: *@TypeOf(arguments), | ||||||
| @ -348,6 +351,7 @@ pub const FileSystem = union(enum) { | |||||||
| 
 | 
 | ||||||
|     archive: struct { |     archive: struct { | ||||||
|         file_access: FileAccess, |         file_access: FileAccess, | ||||||
|  |         index_cache: *table.Dynamic([]const u8, ArchiveEntry, table.string_context), | ||||||
| 
 | 
 | ||||||
|         entry_table: [max_open_entries]ArchiveEntry = |         entry_table: [max_open_entries]ArchiveEntry = | ||||||
|             std.mem.zeroes([max_open_entries]ArchiveEntry), |             std.mem.zeroes([max_open_entries]ArchiveEntry), | ||||||
| @ -445,10 +449,21 @@ pub const FileSystem = union(enum) { | |||||||
| 
 | 
 | ||||||
|                     for (archive.entry_table) |_, index| { |                     for (archive.entry_table) |_, index| { | ||||||
|                         if (archive.entry_table[index].using == null) { |                         if (archive.entry_table[index].using == null) { | ||||||
|                             archive.entry_table[index] = .{ |                             const archive_path = path.buffer[0 .. path.length]; | ||||||
|                                 .header = oar.Entry.find(archive.file_access, path. |  | ||||||
|                                     buffer[0 .. path.length]) catch return error.FileNotFound, |  | ||||||
| 
 | 
 | ||||||
|  |                             const entry_header = archive.index_cache.lookup(archive_path) orelse { | ||||||
|  |                                 const header = oar.Entry.find(archive.file_access, | ||||||
|  |                                     archive_path) catch return error.FileNotFound; | ||||||
|  | 
 | ||||||
|  |                                 archive.index_cache.insert(archive_path, header) catch { | ||||||
|  |                                     // If caching fails... oh well... | ||||||
|  |                                 }; | ||||||
|  | 
 | ||||||
|  |                                 break header; | ||||||
|  |                             }; | ||||||
|  | 
 | ||||||
|  |                             archive.entry_table[index] = .{ | ||||||
|  |                                 .header = entry_header, | ||||||
|                                 .using = &archive.file_access, |                                 .using = &archive.file_access, | ||||||
|                                 .cursor = 0, |                                 .cursor = 0, | ||||||
|                             }; |                             }; | ||||||
| @ -533,7 +548,6 @@ pub const FileSystem = union(enum) { | |||||||
|                     if (native.path_prefix.len == 0) return error.FileNotFound; |                     if (native.path_prefix.len == 0) return error.FileNotFound; | ||||||
| 
 | 
 | ||||||
|                     var path_buffer = std.mem.zeroes([4096]u8); |                     var path_buffer = std.mem.zeroes([4096]u8); | ||||||
|                     const seperator = '/'; |  | ||||||
| 
 | 
 | ||||||
|                     const seperator_length = @boolToInt(native.path_prefix[ |                     const seperator_length = @boolToInt(native.path_prefix[ | ||||||
|                         native.path_prefix.len - 1] != seperator); |                         native.path_prefix.len - 1] != seperator); | ||||||
| @ -640,6 +654,8 @@ pub const FileSystem = union(enum) { | |||||||
|                 }, |                 }, | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         pub const seperator = '/'; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     /// |     /// | ||||||
|  | |||||||
							
								
								
									
										78
									
								
								src/table.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								src/table.zig
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,78 @@ | |||||||
|  | const std = @import("std"); | ||||||
|  | 
 | ||||||
|  | pub fn Dynamic(comptime Key: type, comptime Value: type, comptime key_context: KeyContext(Key)) type { | ||||||
|  |     return struct { | ||||||
|  |         buckets_used: usize, | ||||||
|  |         bucket_map: []?Bucket, | ||||||
|  | 
 | ||||||
|  |         /// | ||||||
|  |         /// | ||||||
|  |         /// | ||||||
|  |         const Bucket = struct { | ||||||
|  |             key: Key, | ||||||
|  |             value: Value, | ||||||
|  |             next: ?usize, | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         /// | ||||||
|  |         /// | ||||||
|  |         /// | ||||||
|  |         pub const InsertError = error { | ||||||
|  | 
 | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         /// | ||||||
|  |         /// | ||||||
|  |         /// | ||||||
|  |         const Self = @This(); | ||||||
|  | 
 | ||||||
|  |         /// | ||||||
|  |         /// | ||||||
|  |         /// | ||||||
|  |         pub fn insert(self: Self, key: Key, value: Value) InsertError!void { | ||||||
|  |             _ = value; | ||||||
|  |             _ = key; | ||||||
|  |             _ = self; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /// | ||||||
|  |         /// | ||||||
|  |         /// | ||||||
|  |         pub fn lookup(self: Self, key: Key) ?*Value { | ||||||
|  |             var bucket = &(self.bucket_map[@mod(key_context.hash( | ||||||
|  |                 key), self.bucket_map.len)] orelse return null); | ||||||
|  | 
 | ||||||
|  |             while (bucket) { | ||||||
|  |                 if (key_context.equals(bucket.key, key)) return &bucket.value; | ||||||
|  | 
 | ||||||
|  |                 bucket = bucket.next; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn KeyContext(comptime Key: type) type { | ||||||
|  |     return struct { | ||||||
|  |         hash: fn (Key) usize, | ||||||
|  |         equals: fn (Key, Key) bool, | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn equalsString(this_string: []const u8, that_string: []const u8) bool { | ||||||
|  |     return std.mem.eql(u8, this_string, that_string); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn hashString(string: []const u8) usize { | ||||||
|  |     var hash = @as(usize, 5381); | ||||||
|  | 
 | ||||||
|  |     for (string) |byte| hash = ((hash << 5) + hash) + byte; | ||||||
|  | 
 | ||||||
|  |     return hash; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub const string_context = KeyContext([]const u8){ | ||||||
|  |     .hash = hashString, | ||||||
|  |     .equals = equalsString, | ||||||
|  | }; | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user