aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2014-01-16 23:03:33 +0100
committerBjörn-Egil Dahlberg <[email protected]>2014-01-29 11:08:43 +0100
commitf1003b26524c2321b1eef36fb2d3997aaf0b9e10 (patch)
tree2b6a9eb9dbd312427b7471a41189b3a35b6da7ea
parent0422247a9d8259ef1a28704500f07caf827f42f6 (diff)
downloadotp-f1003b26524c2321b1eef36fb2d3997aaf0b9e10.tar.gz
otp-f1003b26524c2321b1eef36fb2d3997aaf0b9e10.tar.bz2
otp-f1003b26524c2321b1eef36fb2d3997aaf0b9e10.zip
erts: Optimize erts_map_update/remove
to not continue comparing keys once it has been found.
-rw-r--r--erts/emulator/beam/erl_map.c42
1 files changed, 20 insertions, 22 deletions
diff --git a/erts/emulator/beam/erl_map.c b/erts/emulator/beam/erl_map.c
index e68482be58..57f156509c 100644
--- a/erts/emulator/beam/erl_map.c
+++ b/erts/emulator/beam/erl_map.c
@@ -612,7 +612,6 @@ BIF_RETTYPE maps_put_3(BIF_ALIST_3) {
int erts_maps_remove(Process *p, Eterm key, Eterm map, Eterm *res) {
Sint n;
- Sint found = 0;
Uint need;
Eterm *hp_start;
Eterm *thp, *mhp;
@@ -650,9 +649,7 @@ int erts_maps_remove(Process *p, Eterm key, Eterm map, Eterm *res) {
if (is_immed(key)) {
while(n--) {
if (*ks == key) {
- ks++;
- vs++;
- found = 1;
+ goto found_key;
} else {
*mhp++ = *vs++;
*thp++ = *ks++;
@@ -661,9 +658,7 @@ int erts_maps_remove(Process *p, Eterm key, Eterm map, Eterm *res) {
} else {
while(n--) {
if (EQ(*ks, key)) {
- ks++;
- vs++;
- found = 1;
+ goto found_key;
} else {
*mhp++ = *vs++;
*thp++ = *ks++;
@@ -671,10 +666,6 @@ int erts_maps_remove(Process *p, Eterm key, Eterm map, Eterm *res) {
}
}
- if (found) {
- return 1;
- }
-
/* Not found, remove allocated memory
* and return previous map.
*/
@@ -682,6 +673,14 @@ int erts_maps_remove(Process *p, Eterm key, Eterm map, Eterm *res) {
*res = map;
return 1;
+
+found_key:
+ /* Copy rest of keys and values */
+ if (n) {
+ sys_memcpy(mhp, vs+1, n*sizeof(Eterm));
+ sys_memcpy(thp, ks+1, n*sizeof(Eterm));
+ }
+ return 1;
}
BIF_RETTYPE maps_remove_2(BIF_ALIST_2) {
@@ -699,7 +698,6 @@ BIF_RETTYPE maps_remove_2(BIF_ALIST_2) {
int erts_maps_update(Process *p, Eterm key, Eterm value, Eterm map, Eterm *res) {
Sint n,i;
- Sint found = 0;
Eterm* hp,*shp;
Eterm *ks,*vs;
map_t *mp = (map_t*)map_val(map);
@@ -717,7 +715,6 @@ int erts_maps_update(Process *p, Eterm key, Eterm value, Eterm map, Eterm *res)
hp = HAlloc(p, MAP_HEADER_SIZE + n);
shp = hp;
- *res = make_map(hp);
*hp++ = MAP_HEADER;
*hp++ = n;
*hp++ = mp->keys;
@@ -725,9 +722,7 @@ int erts_maps_update(Process *p, Eterm key, Eterm value, Eterm map, Eterm *res)
if (is_immed(key)) {
for( i = 0; i < n; i ++) {
if (ks[i] == key) {
- *hp++ = value;
- vs++;
- found = 1;
+ goto found_key;
} else {
*hp++ = *vs++;
}
@@ -735,20 +730,23 @@ int erts_maps_update(Process *p, Eterm key, Eterm value, Eterm map, Eterm *res)
} else {
for( i = 0; i < n; i ++) {
if (EQ(ks[i], key)) {
- *hp++ = value;
- vs++;
- found = 1;
+ goto found_key;
} else {
*hp++ = *vs++;
}
}
}
- if (found) {
- return 1;
- }
HRelease(p, shp + MAP_HEADER_SIZE + n, shp);
return 0;
+
+found_key:
+ *hp++ = value;
+ vs++;
+ if (++i < n)
+ sys_memcpy(hp, vs, (n - i)*sizeof(Eterm));
+ *res = make_map(shp);
+ return 1;
}
BIF_RETTYPE maps_update_3(BIF_ALIST_3) {