Commit f2dde045 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 464a0c61
...@@ -28,6 +28,7 @@ package main ...@@ -28,6 +28,7 @@ package main
import ( import (
"context" "context"
"fmt" "fmt"
"math"
"lab.nexedi.com/kirr/go123/xerr" "lab.nexedi.com/kirr/go123/xerr"
"lab.nexedi.com/kirr/neo/go/transaction" "lab.nexedi.com/kirr/neo/go/transaction"
...@@ -40,8 +41,11 @@ type Bucket = btree.LOBucket ...@@ -40,8 +41,11 @@ type Bucket = btree.LOBucket
type Node = btree.LONode type Node = btree.LONode
type Key = int64 type Key = int64
const KeyMax Key = math.MaxInt64
type Value = zodb.Oid // assumes key points to IPersistent type Value = zodb.Oid // assumes key points to IPersistent
// deletion is represented as InvalidOid // deletion is represented as VDEL
const VDEL = zodb.InvalidOid
type Oid = zodb.Oid type Oid = zodb.Oid
type SetKey = SetI64 type SetKey = SetI64
...@@ -310,13 +314,79 @@ func (δBtail *ΔBtail) Update(δZ *zodb.EventCommit) (_ ΔB, err error) { ...@@ -310,13 +314,79 @@ func (δBtail *ΔBtail) Update(δZ *zodb.EventCommit) (_ ΔB, err error) {
// treediff computes δT for tree specified by root in between old..new. // treediff computes δT for tree specified by root in between old..new.
// //
// XXX only for tracked // XXX only for tracked
// δZT is δZ/T - subset of δZ touching tracked nodes of T. // δZT is δZ/T - subset of δZ(old..new) that touches tracked nodes of T.
func (δBtail *ΔBtail) treediff(ctx context.Context, root zodb.Oid, δZT SetOid, zconnOld, zconnNew *zodb.Connection) (δT map[Key]Value, err error) { func (δBtail *ΔBtail) treediff(ctx context.Context, root zodb.Oid, δZT SetOid, zconnOld, zconnNew *zodb.Connection) (δT map[Key]Value, err error) {
defer xerr.Contextf(&err, "treediff %s", root) defer xerr.Contextf(&err, "treediff %s..%s %s", zconnOld.At(), zconnNew.At(), root)
// XXX zconnX -> a, b ?
// XXX stub
for oid := range δZT {
xa, err1 := zconnOld.Get(ctx, oid)
xb, err2 := zconnNew.Get(ctx, oid)
err := xerr.Merge(err1, err2)
if err != nil {
return nil, err
}
ta := zodb.ClassOf(xa)
tb := zodb.ClassOf(xb)
if ta != tb {
return nil, fmt.Errorf("object %s: type mutated: %s -> %s", oid, ta, tb)
}
// XXX activate/deactivate
switch a := xa.(type) {
default:
return nil, fmt.Errorf("object %s: type unexpected: %s", oid, ta)
case *Bucket:
b := xb.(*Bucket) // must not fail
diffB(a, b)
case *Tree:
b := xb.(*Tree) // must not fail
// TODO handle
}
}
return nil, nil // XXX stub return nil, nil // XXX stub
} }
// diffB computes difference in between two buckets.
// the buckets must be already activated
func diffB(a, b *Bucket) map[Key]Value {
av := a.Entryv()
bv := b.Entryv()
δ := map[Key]Value{}
for len(av) > 0 || len(bv) > 0 {
ka, va := KeyMax, VDEL
kb, vb := KeyMax, VDEL
if len(av) > 0 {
ka, va = av[0].Key(), av[0].Value()
}
if len(bv) > 0 {
kb, vb = bv[0].Key(), bv[0].Value()
}
switch {
case ka < kb: // -a[0]
av = av[1:]
δ[ka] = VDEL
case ka > kb: // +b[0]
// ka == kb // va->vb
default:
av = av[1:]
bv = bv[1:]
δ[ka] = vb
}
}
}
func (δBtail *ΔBtail) ForgetPast(revCut zodb.Tid) { func (δBtail *ΔBtail) ForgetPast(revCut zodb.Tid) {
......
...@@ -402,7 +402,7 @@ func XGetKV(db *zodb.DB, at zodb.Tid, kvOid map[Key]Value) map[Key]string { ...@@ -402,7 +402,7 @@ func XGetKV(db *zodb.DB, at zodb.Tid, kvOid map[Key]Value) map[Key]string {
kv := map[Key]string{} kv := map[Key]string{}
for k, vOid := range kvOid { for k, vOid := range kvOid {
if vOid == zodb.InvalidOid { if vOid == VDEL {
kv[k] = DEL kv[k] = DEL
continue continue
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment