Ich habe folgende mapping(uint => Foo[])
Datenstruktur. Ich habe 10 eindeutige IDs mit 10 Foo-Strukturen zugeordnet, wobei jedes Foo eine Arraylist mit 10 Elementen ist.
Schritt 1:
for(int i = 0; i < 10; i++)
for(int j = 0; j < 10; j++)
add(i, j);
Schritt 2: Ich lösche die zuvor gepushten Elemente. Ich bin mir nicht sicher, welcher der richtige Ansatz unter a) und b) unten ist. Ansatz b) hinterlässt Lücken, indem nur die Mitglieder in der Struktur zurückgesetzt werden
a) for(int i = 0; i < 10; i++) | b) for(int i = 0; i < 10; i++)
delete(i); | for(int j = 0; j < 10; j++)
| delete_items(i, j)
Schritt 3: Ich pushe neue Elemente mit unterschiedlicher Mapping-Uint-ID.
for(int i = 20; i < 30; i++)
for(int j = 20; j < 30; j++)
add(i, y);
[F] Würde delete mapping_array[id]
tatsächlich der Speicher freigegeben, der von der Array-Liste innerhalb der mapping
? Oder würde es nur den Speicher auf Null setzen, als ob delete
er in der Array-Liste verwendet wurde, und das Element bleibt mapping
so leer, nimmt aber immer noch Speicherplatz in Anspruch?
[F] Insgesamt habe ich 10 eindeutige IDs mit 10 Foo-Strukturen zugeordnet, wobei jedes Foo eine Arrayliste mit 10 Elementen ist. Später lösche ich die Elemente in meiner mapping
Datenstruktur und füge dann neue Elemente ein. Würde den neu eingefügten Elementen also neuer Speicher zugewiesen oder würden sie im Speicher kürzlich gelöschter Elemente überschrieben?
Diese sind wichtig, da ich eine sehr große Mapping-Datenstruktur verwende und Elemente häufig eingefügt und entfernt werden. Ich weiß, dass Löschen keinen Speicher auf einem Array freigibt, bin mir aber nicht sicher, ob es beim Mapping dasselbe ist.
Ich verwende das folgende Codestück aus der Antwort auf diese Frage: https://ethereum.stackexchange.com/a/1458/4575
struct Foo{
uint x;
}
mapping(uint => Foo[]) mapping_array;
function add(uint id, uint _x) public {
mapping_array[id].push(Foo(_x));
}
function get(uint id, uint index) public returns(uint){
return mapping_array[id][index].x;
}
function delete_(uint id) public {
delete mapping_array[id];
}
function delete_items(uint id, uint index) public {
delete mapping_array[id][index];
}
Löschen:
a löschen weist a den Anfangswert für den Typ zu. Dh für Integer ist es äquivalent zu a = 0, Für Structs weist es ein Struct zu, bei dem alle Mitglieder zurückgesetzt sind.
delete hat keine Auswirkung auf ganze Mappings (da die Schlüssel von Mappings willkürlich sein können und im Allgemeinen unbekannt sind). Wenn Sie also eine Struktur löschen, werden alle Elemente zurückgesetzt, die keine Zuordnungen sind, und auch in die Elemente rekursiv, es sei denn, es handelt sich um Zuordnungen. Einzelne Tasten und ihre Zuordnung können jedoch gelöscht werden.
Wichtig ist, dass sich das Löschen von a wirklich wie eine Zuweisung zu a verhält, dh es speichert ein neues Objekt in a.
Link: http://solidity.readthedocs.io/en/develop/types.html
Vielen Dank für Ihre wertvolle Zeit und Hilfe.
Basierend auf meiner Debug-Beobachtung:
Ich habe das getestet:
Dieses Debug-Ergebnis: führt mich zu dem Schluss, dass Speicher freigegeben wird oder die Adresse keine gültigen Informationen enthält.
Testcode:
set_txn_hash = my_contract.transact().map_insert();
contract_address = unmigrated_chain.wait.for_receipt(set_txn_hash)
for x in range(0, 9):
for y in range(0, 9):
output = my_contract.call().get_(x, y);
print(output); //returns correct value.
set_txn_hash = my_contract.transact().map_remove_map();
contract_address = unmigrated_chain.wait.for_receipt(set_txn_hash)
set_txn_hash = my_contract.transact().get_map_address(0);
contract_address = unmigrated_chain.wait.for_receipt(set_txn_hash)
output = my_contract.call().get_map();
print(output);
output = my_contract.call().try_();
print(output); //Solidity gives error if delete map_remove_map() is called
Zusätzliche Funktionen in meinem Vertrag:
function map_insert(){
for(uint i = 0; i < 10; i++)
for(uint j = 0; j < 10; j++)
add(i, i*10 + j);
}
function map_remove_map(){
for(uint i = 0; i < 10; i++)
delete_(i);
}
function map_remove_map_item(){
for(uint i = 0; i < 10; i++)
for(uint j = 0; j < 10; j++)
delete_items(i, j);
}
function get_map_address(uint id) {
uint addr;
Foo[] a = foo[id];
assembly{
addr := a
}
map_address = addr;
}
function get_map() constant returns (uint){
return map_address;
}
function try_() constant returns (uint ){
uint addr = map_address;
Foo[] a;
assembly{
a := addr
}
return a[1].x;
}
Badr Bellaj
Alper
Alper
Alper