@@ -15,7 +15,24 @@ pub const IndexRef = struct {
15
15
lock : std.Thread.Mutex = .{},
16
16
allocator : std.mem.Allocator ,
17
17
dir : std.fs.Dir ,
18
- indexes : std .AutoHashMap (u8 , IndexRef ),
18
+ indexes : std .StringHashMap (IndexRef ),
19
+
20
+ fn isValidName (name : []const u8 ) bool {
21
+ for (name , 0 ) | c , i | {
22
+ if (i == 0 ) {
23
+ switch (c ) {
24
+ '0' ... '9' , 'A' ... 'Z' , 'a' ... 'z' = > {},
25
+ else = > return false ,
26
+ }
27
+ } else {
28
+ switch (c ) {
29
+ '0' ... '9' , 'A' ... 'Z' , 'a' ... 'z' , '_' , '-' = > {},
30
+ else = > return false ,
31
+ }
32
+ }
33
+ }
34
+ return true ;
35
+ }
19
36
20
37
const max_sub_dir_name_size = 10 ;
21
38
const sub_dir_name_fmt = "{x:0>2}" ;
@@ -24,7 +41,7 @@ pub fn init(allocator: std.mem.Allocator, dir: std.fs.Dir) Self {
24
41
return .{
25
42
.allocator = allocator ,
26
43
.dir = dir ,
27
- .indexes = std .AutoHashMap ( u8 , IndexRef ).init (allocator ),
44
+ .indexes = std .StringHashMap ( IndexRef ).init (allocator ),
28
45
};
29
46
}
30
47
@@ -45,11 +62,15 @@ pub fn releaseIndex(self: *Self, index_data: *IndexRef) void {
45
62
index_data .last_used_at = std .time .timestamp ();
46
63
}
47
64
48
- pub fn acquireIndex (self : * Self , id : u8 , create : bool ) ! * IndexRef {
65
+ pub fn acquireIndex (self : * Self , name : []const u8 , create : bool ) ! * IndexRef {
66
+ if (! isValidName (name )) {
67
+ return error .InvalidIndexName ;
68
+ }
69
+
49
70
self .lock .lock ();
50
71
defer self .lock .unlock ();
51
72
52
- var result = try self .indexes .getOrPut ( id );
73
+ var result = try self .indexes .getOrPutAdapted ( name , self . indexes . ctx );
53
74
if (result .found_existing ) {
54
75
result .value_ptr .references += 1 ;
55
76
result .value_ptr .last_used_at = std .time .timestamp ();
@@ -58,10 +79,10 @@ pub fn acquireIndex(self: *Self, id: u8, create: bool) !*IndexRef {
58
79
59
80
errdefer self .indexes .removeByPtr (result .key_ptr );
60
81
61
- var sub_dir_name_buf : [ max_sub_dir_name_size ] u8 = undefined ;
62
- const sub_dir_name = try std . fmt . bufPrint ( & sub_dir_name_buf , sub_dir_name_fmt , .{ id } );
82
+ result . key_ptr .* = try self . allocator . dupe ( u8 , name ) ;
83
+ errdefer self . allocator . free ( result . key_ptr .* );
63
84
64
- result .value_ptr .index = try Index .init (self .allocator , self .dir , sub_dir_name , .{ .create = create });
85
+ result .value_ptr .index = try Index .init (self .allocator , self .dir , name , .{ .create = create });
65
86
errdefer result .value_ptr .index .deinit ();
66
87
67
88
try result .value_ptr .index .open ();
@@ -71,26 +92,36 @@ pub fn acquireIndex(self: *Self, id: u8, create: bool) !*IndexRef {
71
92
return result .value_ptr ;
72
93
}
73
94
74
- pub fn getIndex (self : * Self , id : u8 ) ! * IndexRef {
75
- return try self .acquireIndex (id , false );
95
+ pub fn getIndex (self : * Self , name : []const u8 ) ! * IndexRef {
96
+ if (! isValidName (name )) {
97
+ return error .InvalidIndexName ;
98
+ }
99
+
100
+ return try self .acquireIndex (name , false );
76
101
}
77
102
78
- pub fn createIndex (self : * Self , id : u8 ) ! void {
79
- const index_ref = try self .acquireIndex (id , true );
103
+ pub fn createIndex (self : * Self , name : []const u8 ) ! void {
104
+ if (! isValidName (name )) {
105
+ return error .InvalidIndexName ;
106
+ }
107
+
108
+ const index_ref = try self .acquireIndex (name , true );
80
109
defer self .releaseIndex (index_ref );
81
110
}
82
111
83
- pub fn deleteIndex (self : * Self , id : u8 ) ! void {
112
+ pub fn deleteIndex (self : * Self , name : []const u8 ) ! void {
113
+ if (! isValidName (name )) {
114
+ return error .InvalidIndexName ;
115
+ }
116
+
84
117
self .lock .lock ();
85
118
defer self .lock .unlock ();
86
119
87
- if (self .indexes .getEntry (id )) | entry | {
120
+ if (self .indexes .getEntry (name )) | entry | {
121
+ self .allocator .free (entry .key_ptr .* );
88
122
entry .value_ptr .index .deinit ();
89
123
self .indexes .removeByPtr (entry .key_ptr );
90
124
}
91
125
92
- var sub_dir_name_buf : [max_sub_dir_name_size ]u8 = undefined ;
93
- const sub_dir_name = try std .fmt .bufPrint (& sub_dir_name_buf , sub_dir_name_fmt , .{id });
94
-
95
- try self .dir .deleteTree (sub_dir_name );
126
+ try self .dir .deleteTree (name );
96
127
}
0 commit comments