From 28e6433b7397d428e4e7667c6204eebfce189676 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Wed, 23 Mar 2022 21:49:26 -0500 Subject: [PATCH] theoretically made Map and Set faster; bug fixes --- core/container/map.onyx | 9 +++++++-- core/container/set.onyx | 9 +++++++-- core/io/stream.onyx | 2 ++ core/io/writer.onyx | 4 ++++ modules/http/http.onyx | 6 ++++++ tests/implicit_initialize_locals | 2 ++ 6 files changed, 28 insertions(+), 4 deletions(-) diff --git a/core/container/map.onyx b/core/container/map.onyx index 621817dd..8c82553e 100644 --- a/core/container/map.onyx +++ b/core/container/map.onyx @@ -34,6 +34,7 @@ Map :: struct (Key_Type: type_expr, Value_Type: type_expr) where ValidKey(Key_Ty Entry :: struct (K: type_expr, V: type_expr) { next : i32; + hash : u32; key : K; value : V; } @@ -80,7 +81,7 @@ put :: (use map: ^Map, key: map.Key_Type, value: map.Value_Type) { return; } - entries << .{ hashes[lr.hash_index], key, value }; + entries << .{ hashes[lr.hash_index], lr.hash, key, value }; hashes[lr.hash_index] = entries.count - 1; if full(map) do grow(map); @@ -164,6 +165,7 @@ format_map :: (output: ^conv.Format_Output, format: ^conv.Format, x: ^Map($K, $V hash_index : i32 = -1; entry_index : i32 = -1; entry_prev : i32 = -1; + hash : u32 = 0; } lookup :: (use map: ^Map, key: map.Key_Type) -> MapLookupResult { @@ -171,12 +173,15 @@ format_map :: (output: ^conv.Format_Output, format: ^conv.Format, x: ^Map($K, $V lr := MapLookupResult.{}; hash_value: u32 = hash.to_u32(key); // You cannot use this type for the key, unless you add an overload. + lr.hash = hash_value; lr.hash_index = hash_value % hashes.count; lr.entry_index = hashes[lr.hash_index]; while lr.entry_index >= 0 { - if entries[lr.entry_index].key == key do return lr; + if entries[lr.entry_index].hash == hash_value { + if entries[lr.entry_index].key == key do return lr; + } lr.entry_prev = lr.entry_index; lr.entry_index = entries[lr.entry_index].next; diff --git a/core/container/set.onyx b/core/container/set.onyx index 76b3ec77..b3a57d7a 100644 --- a/core/container/set.onyx +++ b/core/container/set.onyx @@ -23,6 +23,7 @@ Set :: struct (Elem_Type: type_expr) where SetValue(Elem_Type) { Entry :: struct (T: type_expr) { next : i32; + hash : u32; value : T; } @@ -64,7 +65,7 @@ insert :: (use set: ^Set, value: set.Elem_Type) { if lr.entry_index >= 0 do return; - entries << .{ hashes[lr.hash_index], value }; + entries << .{ hashes[lr.hash_index], lr.hash, value }; hashes[lr.hash_index] = entries.count - 1; if full(set) do grow(set); @@ -146,18 +147,22 @@ iterator :: (set: ^Set($T)) -> Iterator(T) { hash_index : i32 = -1; entry_index : i32 = -1; entry_prev : i32 = -1; + hash : u32 = 0; } lookup :: (use set: ^Set, value: set.Elem_Type) -> SetLookupResult { lr := SetLookupResult.{}; hash_value: u32 = hash.to_u32(value); // You cannot have a set of this type without defining a to_u32 hash. + lr.hash = hash_value; lr.hash_index = hash_value % hashes.count; lr.entry_index = hashes[lr.hash_index]; while lr.entry_index >= 0 { - if entries[lr.entry_index].value == value do return lr; + if entries[lr.entry_index].hash == hash_value { + if entries[lr.entry_index].value == value do return lr; + } lr.entry_prev = lr.entry_index; lr.entry_index = entries[lr.entry_index].next; diff --git a/core/io/stream.onyx b/core/io/stream.onyx index cc926621..f88ab13e 100644 --- a/core/io/stream.onyx +++ b/core/io/stream.onyx @@ -219,6 +219,8 @@ DynamicStringStream :: struct { curr_pos : i32; data : [..] u8; + + to_str :: dynamic_string_stream_to_str; } dynamic_string_stream_make :: (init_size := 128, a := context.allocator) -> DynamicStringStream { diff --git a/core/io/writer.onyx b/core/io/writer.onyx index c80a5953..53ea8897 100644 --- a/core/io/writer.onyx +++ b/core/io/writer.onyx @@ -12,6 +12,10 @@ writer_make :: (s: ^Stream) -> Writer { return Writer.{ s }; } +// +// Future-proofing the API +writer_free :: (w: ^Writer) {} + string_builder :: (allocator := context.allocator) -> (Writer, ^DynamicStringStream) { new_stream := new(DynamicStringStream, allocator=allocator); *new_stream = dynamic_string_stream_make(); diff --git a/modules/http/http.onyx b/modules/http/http.onyx index 1b73de3f..76f06112 100644 --- a/modules/http/http.onyx +++ b/modules/http/http.onyx @@ -139,6 +139,12 @@ Connection :: struct { r: io.Reader; w: io.Writer; + close :: (this: ^Connection) { + this.socket->close(); + io.reader_free(^this.r); + io.writer_free(^this.w); + } + get :: (this: ^Connection, resource: str, params: [] Key_Value_Pair, headers: [] Key_Value_Pair = .[]) -> Response { req := Request.get(resource, params, headers); return send_request(this, ^req); diff --git a/tests/implicit_initialize_locals b/tests/implicit_initialize_locals index 93ac0daa..bf590d8f 100644 --- a/tests/implicit_initialize_locals +++ b/tests/implicit_initialize_locals @@ -12,11 +12,13 @@ Untyped_Array { [ Map.Entry([] u8, i32) { next = -1, + hash = 193461347, key = "Joe", value = 12 }, Map.Entry([] u8, i32) { next = 0, + hash = 2089242307, key = "Jane", value = 34 } -- 2.25.1