theoretically made Map and Set faster; bug fixes
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 24 Mar 2022 02:49:26 +0000 (21:49 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 24 Mar 2022 02:49:26 +0000 (21:49 -0500)
core/container/map.onyx
core/container/set.onyx
core/io/stream.onyx
core/io/writer.onyx
modules/http/http.onyx
tests/implicit_initialize_locals

index 621817dd219b1d71223e4e720a31d608a16112bc..8c82553eac4ec0c72fd7021291c7c1fd651e3695 100644 (file)
@@ -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;
index 76b3ec77eb6aff1c90138c8dc3f4440c28478ee2..b3a57d7a824b0c984f514ee16c54f145462a1c8b 100644 (file)
@@ -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;
index cc926621f1006dd2e97a711d8f3d74eacbeb76da..f88ab13e61a9a3c0bdcba53861813e6fb1c147c4 100644 (file)
@@ -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 {
index c80a5953364392be0468c7cc5114e2a77a55df17..53ea88975df13e70e3429ff58c9cfcbefd98ef0b 100644 (file)
@@ -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();
index 1b73de3f7b9d6b92aedc7246ff43c009463eb4b4..76f06112a3adf297c13a014160a4fa83c145d65f 100644 (file)
@@ -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);
index 93ac0daab9c92e91e56bb7bbb2e56ea4c3e1c74b..bf590d8fcc0583451c9eece9acb751f739e779ed 100644 (file)
@@ -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
     }