DOM diff problem: hashing
This commit is contained in:
parent
ff8bbf1676
commit
c065b8f709
3 changed files with 79 additions and 13 deletions
|
|
@ -176,6 +176,3 @@ proc onload(session: cstring) {.exportc.} =
|
||||||
t += dtReset
|
t += dtReset
|
||||||
|
|
||||||
timeout = setTimeout(test7, t)
|
timeout = setTimeout(test7, t)
|
||||||
t += dtTest
|
|
||||||
timeout = setTimeout(reset, t)
|
|
||||||
t += dtReset
|
|
||||||
|
|
|
||||||
67
karax.nim
67
karax.nim
|
|
@ -109,16 +109,65 @@ proc equals(a, b: VNode): bool =
|
||||||
a.class = b.class
|
a.class = b.class
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
proc getStringHash(s: string): uint64 =
|
||||||
|
result = 0
|
||||||
|
for c in s:
|
||||||
|
result = (result * 257 + uint64(c)) mod 1000000007
|
||||||
|
|
||||||
|
proc calcHash(a : VNode) =
|
||||||
|
if a.validHash:
|
||||||
|
return
|
||||||
|
var result : uint64 = 0
|
||||||
|
for i in a:
|
||||||
|
i.calcHash()
|
||||||
|
result = result + i.hash
|
||||||
|
a.validHash = true
|
||||||
|
a.hash = (getStringHash(getVNodeData(a)) * 71 + result) mod 1000000007
|
||||||
|
|
||||||
proc equalsTree(a, b : VNode): bool =
|
proc equalsTree(a, b : VNode): bool =
|
||||||
if not equals(a, b):
|
if not a.validHash:
|
||||||
return false
|
a.calcHash()
|
||||||
else:
|
if not b.validHash:
|
||||||
if len(a) != len(b):
|
b.calcHash()
|
||||||
return false
|
|
||||||
for i in 0..len(a)-1:
|
return a.hash == b.hash
|
||||||
if not equalsTree(a[i], b[i]):
|
|
||||||
return false
|
# if not equals(a, b):
|
||||||
return true
|
# return false
|
||||||
|
# else:
|
||||||
|
# if len(a) != len(b):
|
||||||
|
# return false
|
||||||
|
# for i in 0..len(a)-1:
|
||||||
|
# if not equalsTree(a[i], b[i]):
|
||||||
|
# return false
|
||||||
|
# return true
|
||||||
|
|
||||||
|
# kout cstring("a " & $int64(a.hash) & " " & "b " & $int64(b.hash))
|
||||||
|
|
||||||
|
# if not equals(a, b):
|
||||||
|
# if a.hash == b.hash:
|
||||||
|
# kout cstring("false " & getVNodeData(a) & " " & $int64(a.hash) & " " & getVNodeData(b) & " " & $int64(b.hash))
|
||||||
|
# kout cstring($int64(getStringHash(getVNodeData(a))) & " " & $int64(getStringHash(getVNodeData(b))))
|
||||||
|
# for c in getVNodeData(a):
|
||||||
|
# kout cstring($int64(uint64(c)))
|
||||||
|
# kout "-------"
|
||||||
|
# for c in getVNodeData(b):
|
||||||
|
# kout cstring($int64(uint64(c)))
|
||||||
|
|
||||||
|
# return false
|
||||||
|
# else:
|
||||||
|
# if len(a) != len(b):
|
||||||
|
# if a.hash == b.hash:
|
||||||
|
# kout cstring("false " & getVNodeData(a) & " " & $int64(a.hash) & " " & getVNodeData(b) & " " & $int64(b.hash))
|
||||||
|
# return false
|
||||||
|
# for i in 0..len(a)-1:
|
||||||
|
# if not equalsTree(a[i], b[i]):
|
||||||
|
# if a.hash == b.hash:
|
||||||
|
# kout cstring("false " & getVNodeData(a) & " " & $int64(a.hash) & " " & getVNodeData(b) & " " & $int64(b.hash))
|
||||||
|
# return false
|
||||||
|
# if a.hash != b.hash:
|
||||||
|
# kout cstring("true " & getVNodeData(a) & " " & getVNodeData(b))
|
||||||
|
# return true
|
||||||
|
|
||||||
proc updateElement(parent, current: Node, newNode, oldNode: VNode) =
|
proc updateElement(parent, current: Node, newNode, oldNode: VNode) =
|
||||||
if not equals(newNode, oldNode):
|
if not equals(newNode, oldNode):
|
||||||
|
|
|
||||||
20
vdom.nim
20
vdom.nim
|
|
@ -38,6 +38,8 @@ type
|
||||||
# even index: key, odd index: value; done this way for memory efficiency:
|
# even index: key, odd index: value; done this way for memory efficiency:
|
||||||
attrs: seq[cstring]
|
attrs: seq[cstring]
|
||||||
events*: seq[(EventKind, EventHandler)]
|
events*: seq[(EventKind, EventHandler)]
|
||||||
|
hash*: uint64
|
||||||
|
validHash*: bool
|
||||||
|
|
||||||
proc value*(n: VNode): cstring = n.text
|
proc value*(n: VNode): cstring = n.text
|
||||||
proc `value=`*(n: VNode; v: cstring) = n.text = v
|
proc `value=`*(n: VNode; v: cstring) = n.text = v
|
||||||
|
|
@ -129,6 +131,24 @@ proc toString*(n: VNode; result: var string; indent: int) =
|
||||||
for i in 1..indent: result.add ' '
|
for i in 1..indent: result.add ' '
|
||||||
result.add "\L</" & $n.kind & ">"
|
result.add "\L</" & $n.kind & ">"
|
||||||
|
|
||||||
|
proc getVNodeData*(n: VNode): string =
|
||||||
|
result.add "<" & $n.kind
|
||||||
|
toStringAttr(id)
|
||||||
|
toStringAttr(class)
|
||||||
|
|
||||||
|
#for k, v in attrs(n):
|
||||||
|
# result.add " " & $k & " = " & $v
|
||||||
|
|
||||||
|
result.add ">"
|
||||||
|
if n.kind == VNodeKind.text:
|
||||||
|
result.add n.text
|
||||||
|
else:
|
||||||
|
if n.text != nil:
|
||||||
|
result.add " value = "
|
||||||
|
result.add n.text
|
||||||
|
result.add "</" & $n.kind & ">"
|
||||||
|
|
||||||
|
|
||||||
proc `$`*(n: VNode): cstring =
|
proc `$`*(n: VNode): cstring =
|
||||||
var res = ""
|
var res = ""
|
||||||
toString(n, res, 0)
|
toString(n, res, 0)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue