aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2025-01-05 13:33:16 +0000
committergingerBill <bill@gingerbill.org>2025-01-05 13:33:16 +0000
commit52d3497eda2f267802f460df3c87a56f5b8edaf8 (patch)
tree0d0d2edd87897b5e94da80706e0ad0e7d3560393
parentbca08d3b85f59c35f4eb43731099bc96730b12cd (diff)
parentbf77036cb044aafbd0eaab21879d9f867a53d76e (diff)
Merge branch 'master' of https://github.com/odin-lang/Odin
-rw-r--r--base/runtime/dynamic_map_internal.odin22
-rwxr-xr-xbuild_odin.sh4
-rw-r--r--core/image/general.odin2
-rw-r--r--tests/core/runtime/test_core_runtime.odin99
4 files changed, 112 insertions, 15 deletions
diff --git a/base/runtime/dynamic_map_internal.odin b/base/runtime/dynamic_map_internal.odin
index 3dded7716..4e22aa25c 100644
--- a/base/runtime/dynamic_map_internal.odin
+++ b/base/runtime/dynamic_map_internal.odin
@@ -158,21 +158,21 @@ map_cell_index_static :: #force_inline proc "contextless" (cells: [^]Map_Cell($T
} else when (N & (N - 1)) == 0 && N <= 8*size_of(uintptr) {
// Likely case, N is a power of two because T is a power of two.
+ // Unique case, no need to index data here since only one element.
+ when N == 1 {
+ return &cells[index].data[0]
+ }
+
// Compute the integer log 2 of N, this is the shift amount to index the
// correct cell. Odin's intrinsics.count_leading_zeros does not produce a
// constant, hence this approach. We only need to check up to N = 64.
- SHIFT :: 1 when N < 2 else
- 2 when N < 4 else
- 3 when N < 8 else
- 4 when N < 16 else
- 5 when N < 32 else 6
+ SHIFT :: 1 when N == 2 else
+ 2 when N == 4 else
+ 3 when N == 8 else
+ 4 when N == 16 else
+ 5 when N == 32 else 6
#assert(SHIFT <= MAP_CACHE_LINE_LOG2)
- // Unique case, no need to index data here since only one element.
- when N == 1 {
- return &cells[index >> SHIFT].data[0]
- } else {
- return &cells[index >> SHIFT].data[index & (N - 1)]
- }
+ return &cells[index >> SHIFT].data[index & (N - 1)]
} else {
// Least likely (and worst case), we pay for a division operation but we
// assume the compiler does not actually generate a division. N will be in the
diff --git a/build_odin.sh b/build_odin.sh
index 3547689d5..d909de5c8 100755
--- a/build_odin.sh
+++ b/build_odin.sh
@@ -110,8 +110,8 @@ Linux)
LDFLAGS="$LDFLAGS -Wl,-rpath=\$ORIGIN"
;;
OpenBSD)
- CXXFLAGS="$CXXFLAGS $($LLVM_CONFIG --cxxflags --ldflags)"
- LDFLAGS="$LDFLAGS -liconv"
+ CXXFLAGS="$CXXFLAGS -I/usr/local/include $($LLVM_CONFIG --cxxflags --ldflags)"
+ LDFLAGS="$LDFLAGS -L/usr/local/lib -liconv"
LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)"
;;
Haiku)
diff --git a/core/image/general.odin b/core/image/general.odin
index c4a884071..e92b54f18 100644
--- a/core/image/general.odin
+++ b/core/image/general.odin
@@ -146,7 +146,7 @@ which_bytes :: proc(data: []byte) -> Which_File_Type {
case s[6:10] == "JFIF", s[6:10] == "Exif":
return .JPEG
case s[:3] == "\xff\xd8\xff":
- switch s[4] {
+ switch s[3] {
case 0xdb, 0xee, 0xe1, 0xe0:
return .JPEG
}
diff --git a/tests/core/runtime/test_core_runtime.odin b/tests/core/runtime/test_core_runtime.odin
index 84fd044cf..c1a3ed718 100644
--- a/tests/core/runtime/test_core_runtime.odin
+++ b/tests/core/runtime/test_core_runtime.odin
@@ -63,4 +63,101 @@ test_init_cap_map_dynarray :: proc(t: ^testing.T) {
defer delete(d2)
testing.expect(t, cap(d2) == 0)
testing.expect(t, d2.allocator.procedure == ally.procedure)
-} \ No newline at end of file
+}
+
+@(test)
+test_map_get :: proc(t: ^testing.T) {
+ check :: proc(t: ^testing.T, m: map[$K]$V, loc := #caller_location) {
+ for k, v in m {
+ got_key, got_val, ok := runtime.map_get(m, k)
+ testing.expect_value(t, got_key, k, loc = loc)
+ testing.expect_value(t, got_val, v, loc = loc)
+ testing.expect(t, ok, loc = loc)
+ }
+ }
+
+ // small keys & values
+ {
+ m := map[int]int{
+ 1 = 10,
+ 2 = 20,
+ 3 = 30,
+ }
+ defer delete(m)
+ check(t, m)
+ }
+
+ // small keys; 2 values per cell
+ {
+ m := map[int][3]int{
+ 1 = [3]int{10, 100, 1000},
+ 2 = [3]int{20, 200, 2000},
+ 3 = [3]int{30, 300, 3000},
+ }
+ defer delete(m)
+ check(t, m)
+ }
+
+ // 2 keys per cell; small values
+ {
+ m := map[[3]int]int{
+ [3]int{10, 100, 1000} = 1,
+ [3]int{20, 200, 2000} = 2,
+ [3]int{30, 300, 3000} = 3,
+ }
+ defer delete(m)
+ check(t, m)
+ }
+
+
+ // small keys; 3 values per cell
+ {
+ val :: struct #packed {
+ a, b: int,
+ c: i32,
+ }
+ m := map[int]val{
+ 1 = val{10, 100, 1000},
+ 2 = val{20, 200, 2000},
+ 3 = val{30, 300, 3000},
+ }
+ defer delete(m)
+ check(t, m)
+ }
+
+ // 3 keys per cell; small values
+ {
+ key :: struct #packed {
+ a, b: int,
+ c: i32,
+ }
+ m := map[key]int{
+ key{10, 100, 1000} = 1,
+ key{20, 200, 2000} = 2,
+ key{30, 300, 3000} = 3,
+ }
+ defer delete(m)
+ check(t, m)
+ }
+
+ // small keys; value bigger than a chacheline
+ {
+ m := map[int][9]int{
+ 1 = [9]int{10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000},
+ 2 = [9]int{20, 200, 2000, 20000, 200000, 2000000, 20000000, 200000000, 2000000000},
+ 3 = [9]int{30, 300, 3000, 30000, 300000, 3000000, 30000000, 300000000, 3000000000},
+ }
+ defer delete(m)
+ check(t, m)
+ }
+ // keys bigger than a chacheline; small values
+ {
+ m := map[[9]int]int{
+ [9]int{10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000} = 1,
+ [9]int{20, 200, 2000, 20000, 200000, 2000000, 20000000, 200000000, 2000000000} = 2,
+ [9]int{30, 300, 3000, 30000, 300000, 3000000, 30000000, 300000000, 3000000000} = 3,
+ }
+ defer delete(m)
+ check(t, m)
+ }
+}