codex-storage / nim-codex

Decentralized Durability Engine
https://codex.storage
Apache License 2.0
69 stars 25 forks source link

Copy all fields when [un]protect Manifest #224

Open Bulat-Ziganshin opened 2 years ago

Bulat-Ziganshin commented 2 years ago

Now we have a bug (blockSize and other fields aren't preserved) in https://github.com/status-im/nim-codex/blob/7ec039f822d4133255334ff3be9d79f91f1c3545/codex/erasure/erasure.nim#L265

And in opposite conversion, all fields are copied manually. And there is no Nim function for shallow copying all fields: https://forum.nim-lang.org/t/5539#34522

But we can use code from https://nim-lang.github.io/Nim/iterators.html :

for name, v1, v2 in fieldPairs(a1, a2):
  when name != "blocks": 
    v2 = v1

EDIT: Error: parallel 'fields' iterator does not work for 'case' objects. So we can use deepcopy, but it will involve extra realloc.

Or we need to write something like that:

for name, v1 in fieldPairs(a1):
  when name != "blocks": 
    v2[name] = v1
Bulat-Ziganshin commented 2 years ago

Experiments by Dmitry:

type
  Obj = object
    a: int
    b: seq[int]
    case opt: bool
    of true:
      additional: bool
    else:
      discard

  ObjRef = ref Obj

var
  obj1 = Obj(a: 1, b: @[5, 6])
  obj2 = obj1

# doAssert obj1 == obj2 # Error: parallel 'fields' iterator does not work for 'case' objects
doAssert obj1.a == obj2.a
doAssert obj1.b == obj2.b

obj2.b &= @[19] # grow the array

doAssert obj1.a == obj2.a
doAssert obj1.b != obj2.b

# assignment
var
  obj1ref = ObjRef(a: 1, b: @[5, 6])
  obj2ref = obj1ref

echo "Print reference right after \"=\": \n"
echo "obj1ref: ", repr obj1ref
echo "obj2ref: ", repr obj2ref

doAssert obj1ref == obj2ref

# deep copy
obj2ref = deepCopy(obj1ref)

echo "Print reference right after deepCopy: \n"
echo "obj1ref: ", repr obj1ref
echo "obj2ref: ", repr obj2ref

doAssert obj1ref != obj2ref
doAssert obj1ref.a == obj2ref.a
doAssert obj1ref.b == obj2ref.b

obj2ref.b &= @[19] # grow the array

doAssert obj1ref.a == obj2ref.a
doAssert obj1ref.b != obj2ref.b
dryajov commented 2 years ago

Now we have a bug (blockSize and other fields aren't preserved) in

https://github.com/status-im/nim-codex/blob/7ec039f822d4133255334ff3be9d79f91f1c3545/codex/erasure/erasure.nim#L265

And in opposite conversion, all fields are copied manually. And there is no Nim function for shallow copying all fields: https://forum.nim-lang.org/t/5539#34522

But we can use code from https://nim-lang.github.io/Nim/iterators.html :

for name, v1, v2 in fieldPairs(a1, a2):
  when name != "blocks": 
    v2 = v1

EDIT: Error: parallel 'fields' iterator does not work for 'case' objects. So we can use deepcopy, but it will involve extra realloc.

Or we need to write something like that:

for name, v1 in fieldPairs(a1):
  when name != "blocks": 
    v2[name] = v1

I don't think we need to overcomplicate it, lets just copy the missing fields manually, which is the expected/accepted way of doing this in nim either way :)

Bulat-Ziganshin commented 2 years ago

I don't think we need to overcomplicate it, lets just copy the missing fields manually, which is the expected/accepted way of doing this in nim either way :)

yeah, I will do it manually unless a better way will be found