Almacenar la misma estructura en dos asignaciones

Tengo una construcción como esta:

var s = SomeStruct(a, b);
map1[addr1] = s;
map2[addr2] = s;

... y quiere que ambos mapas apunten a los mismos datos.
Ahora si después hago

map1[addr1].field1 = x;

... luego map2[addr2].field1aún devuelve el valor inicial en lugar de x, lo que sugiere que se crearon 2 copias de los datos cuando se asignaron inicialmente a los mapas.

Pregunta: ¿Cómo puedo evitar esta duplicación?

Respuestas (1)

No hay una manera simple de hacer esto directamente. De los documentos de solidez :

El mapeo o el arreglo dinámico en sí ocupa un espacio (vacío) en el almacenamiento en alguna posición p de acuerdo con la regla anterior (o al aplicar recursivamente esta regla para mapeos a mapeos o arreglos de arreglos). Para una matriz dinámica, esta ranura almacena la cantidad de elementos en la matriz (las matrices de bytes y las cadenas son una excepción aquí, consulte a continuación). Para una asignación, la ranura no se usa (pero es necesaria para que dos asignaciones iguales una después de la otra usen una distribución de hash diferente). Los datos de la matriz se encuentran en keccak256(p) y el valor correspondiente a una clave de mapeo k se encuentra en keccak256(k . p) donde . es concatenación. Si el valor es nuevamente un tipo no elemental, las posiciones se encuentran agregando un desplazamiento de keccak256(k . p).

Es decir, las asignaciones no contienen punteros a valores. Las asignaciones son formas de convertir claves arbitrarias en punteros a valores. Sería astronómicamente improbable que dos claves de mapeo diferentes apunten a la misma ubicación en la memoria y, por lo tanto, compartan un valor.

Pero hay una solución.

Let map1y map2be asignaciones de direcciones a uints. Luego, use una matriz dinámica de someStructs o una asignación de uints a someStructs. Almacene las estructuras reales en esta última matriz o asignación. Usa los uints de map1y map2como una especie de puntero casero a dichas estructuras. Esto no debería usar mucho más gas al final.

Suena como una buena idea, lo intentaré de inmediato. ¿Tiene una opinión acerca de que la matriz o el mapeo son la mejor solución para las estructuras reales? ¿Hace alguna diferencia que la mayoría de los elementos se eliminen después de un tiempo?
Si va a realizar la eliminación, le sugiero asignaciones. Es posible, pero complicado, eliminar desde el medio de una matriz, mientras que eliminar de las asignaciones es trivial. El único inconveniente real es que no puede iterar a través de un mapeo.
@Matthew Schmidt, solo para que quede claro, si tengo una estructura gruesa con una gran cantidad de datos, almacenar la misma estructura en dos asignaciones diferentes no consumirá una memoria 2x, solo la sobrecarga de dos punteros en lugar de uno a la estructura ¿memoria?