Skip to content

Commit c626c76

Browse files
committed
FEAT: Optimize map datatype creation
1 parent 19fcb89 commit c626c76

File tree

4 files changed

+26
-12
lines changed

4 files changed

+26
-12
lines changed

.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.21.3
1+
3.21.4

make/rebol3.nest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ temp: %make/tmp/
1818
stack-size: 4194304 ;= 4MB (4 * 1024 * 1024)
1919
optimize: 2
2020

21-
version: 3.21.3
21+
version: 3.21.4
2222

2323
;flags: "-ggdb3"
2424
;define: DEBUG

src/core/t-map.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
** REBOL [R3] Language Interpreter and Run-time Environment
44
**
55
** Copyright 2012 REBOL Technologies
6-
** Copyright 2012-2025 Rebol Open Source Contributors
6+
** Copyright 2012-2026 Rebol Open Source Contributors
77
** REBOL is a trademark of REBOL Technologies
88
**
99
** Licensed under the Apache License, Version 2.0 (the "License");
@@ -137,7 +137,7 @@
137137
/*
138138
** Makes a MAP block (that holds both keys and values).
139139
** Size is the number of key-value pairs.
140-
** Hash series is also created.
140+
** Hash series is not created yet.
141141
**
142142
***********************************************************************/
143143
{
@@ -147,7 +147,7 @@
147147
CLEAR_SERIES(blk);
148148

149149
// Use hashing only when there is more then MIN_DICT keys.
150-
if (size > MIN_DICT) ser = Make_Hash_Array(size);
150+
//if (size > MIN_DICT) ser = Make_Hash_Array(size);
151151

152152
blk->series = ser;
153153

@@ -450,16 +450,26 @@
450450
**
451451
*/ REBSER *Copy_Map(REBVAL *val, REBU64 types)
452452
/*
453-
** Copy given map.
453+
** Copy the given map's key/value pairs. Don't hash until necessary.
454454
**
455455
***********************************************************************/
456456
{
457457
REBSER *series;
458+
ASSERT1(IS_MAP(val) || IS_BLOCK(val) || IS_PAREN(val), RP_INTERNAL);
458459
series = Make_Map(VAL_BLK_LEN(val) / 2);
459-
//COPY_BLK_PART(series, VAL_BLK_DATA(data), n);
460-
Append_Map(series, val, UNKNOWN);
460+
if (IS_MAP(val)) {
461+
// There should be valid key/value pairs, so just copying is sufficient.
462+
COPY_BLK_PART(series, VAL_BLK(val), VAL_TAIL(val));
463+
// If existing series has a hashtable, reuse it.
464+
if (VAL_SERIES(val)->series)
465+
series->series = Copy_Series(VAL_SERIES(val)->series);
466+
}
467+
else {
468+
// There may be duplicates, so we must append each key/value pair.
469+
Append_Map(series, val, UNKNOWN);
470+
}
461471
if (types != 0) Copy_Deep_Values(series, 0, SERIES_TAIL(series), types);
462-
Rehash_Hash(series);
472+
//Rehash_Hash(series); // It will be rehashed only when needed.
463473
return series;
464474
}
465475

@@ -471,8 +481,8 @@
471481
{
472482
REBCNT n;
473483
// REBSER *series;
474-
475-
if (!IS_BLOCK(data) && !IS_MAP(data)) return FALSE;
484+
if (!(IS_BLOCK(data) || IS_MAP(data) || IS_PAREN(data)))
485+
return FALSE;
476486

477487
n = VAL_BLK_LEN(data);
478488
if (n & 1) return FALSE;

src/tests/units/map-test.r3

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,16 @@ Rebol [
1818
--assert 1 = m/a
1919
--assert empty? make map! []
2020

21+
--test-- "make map! paren!"
22+
--assert map? try [m: make map! to paren! [a: 1 b: 2]]
23+
--assert 1 = m/a
24+
2125
--test-- "#[map! []]"
2226
m: #(map! [a: 1 b: 2])
2327
--assert 2 = m/b
2428
--assert empty? #(map! [])
2529

26-
--test-- "#()"
30+
--test-- "#[]"
2731
m: #[a: 1 b: 2]
2832
--assert 2 = m/b
2933
--assert empty? #[]

0 commit comments

Comments
 (0)