La respuesta de Sebastian es precisa, pero quería saber por qué era segura, así que investigé el código fuente del mapa . Parece que en una llamada a delete(k, v)
, básicamente solo establece un indicador (además de cambiar el valor de conteo) en lugar de eliminar el valor:
b->tophash[i] = Empty;
(Vacío es una constante para el valor 0
)
Lo que el mapa parece estar haciendo realmente es asignar un número establecido de cubetas dependiendo del tamaño del mapa, que crece a medida que realiza inserciones a la velocidad de 2^B
(a partir de este código fuente ):
byte *buckets; // array of 2^B Buckets. may be nil if count==0.
Por lo tanto, casi siempre hay más depósitos asignados de los que está utilizando, y cuando hace un range
sobre el mapa, verifica el tophash
valor de cada depósito 2^B
para ver si puede omitirlo.
Para resumir, delete
dentro de a range
es seguro porque los datos técnicamente todavía están allí, pero cuando lo comprueba tophash
, ve que puede omitirlo y no incluirlo en cualquier range
operación que esté realizando. El código fuente incluso incluye un TODO
:
// TODO: consolidate buckets if they are mostly empty
// can only consolidate if there are no live iterators at this size.
Esto explica por qué el uso de la delete(k,v)
función en realidad no libera memoria, solo la elimina de la lista de cubos a los que tiene acceso. Si desea liberar la memoria real, deberá hacer que todo el mapa sea inalcanzable para que intervenga la recolección de basura. Puede hacerlo usando una línea como
map = nil