Commit b8ced44a authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent c914b109
// Copyright (C) 2021 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
// option) any later version, as published by the Free Software Foundation.
//
// You can also Link and Combine this program with other software covered by
// the terms of any of the Free Software licenses or any of the Open Source
// Initiative approved licenses and Convey the resulting work. Corresponding
// source of such a combination shall include the source code for all other
// software used.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// See COPYING file for full licensing terms.
// See https://www.nexedi.com/licensing for rationale and options.
// Package xbtree complements package lab.nexedi.com/kirr/neo/go/zodb/btree. // Package xbtree complements package lab.nexedi.com/kirr/neo/go/zodb/btree.
// //
// It provides the following amendments: // It provides the following amendments:
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
package xbtree package xbtree
// ΔBtail // ΔBtail
// XXX ΔBtail organization
import ( import (
"context" "context"
"fmt" "fmt"
...@@ -56,7 +58,7 @@ const debugΔBtail = false ...@@ -56,7 +58,7 @@ const debugΔBtail = false
// //
// ΔBtail provides the following operations: // ΔBtail provides the following operations:
// //
// .Track(path) - start tracking tree nodes and keys; root=path[0], keys=path[-1].(lo,hi] // .Track(path) - start tracking tree nodes and keys; root=path[0], keys=path[-1].(lo,hi]
// //
// .Update(δZ) -> δB - update BTree δ tail given raw ZODB changes // .Update(δZ) -> δB - update BTree δ tail given raw ZODB changes
// .ForgetPast(revCut) - forget changes past revCut // .ForgetPast(revCut) - forget changes past revCut
...@@ -109,8 +111,8 @@ type _ΔTtail struct { ...@@ -109,8 +111,8 @@ type _ΔTtail struct {
trackNew blib.PPTreeSubSet trackNew blib.PPTreeSubSet
// XXX + trackNewKeys RangedKeySet // XXX + trackNewKeys RangedKeySet
// index for LastRevOf queries // index for GetAt queries
lastRevOf map[Key]zodb.Tid // {} key -> last lastRevOf map[Key]zodb.Tid // {} key -> last revision
} }
// _ΔBroots represents roots-only part of ΔB. // _ΔBroots represents roots-only part of ΔB.
...@@ -130,7 +132,7 @@ type ΔB struct { ...@@ -130,7 +132,7 @@ type ΔB struct {
// ΔTree describes changes to one BTree in one revision. // ΔTree describes changes to one BTree in one revision.
type ΔTree struct { type ΔTree struct {
Rev zodb.Tid Rev zodb.Tid
ΔKV map[Key]ΔValue // XXX -> KV ? KV map[Key]ΔValue
} }
...@@ -211,10 +213,10 @@ func vδTClone(orig []ΔTree) []ΔTree { ...@@ -211,10 +213,10 @@ func vδTClone(orig []ΔTree) []ΔTree {
for _, origδT := range orig { for _, origδT := range orig {
klonδT := ΔTree{ klonδT := ΔTree{
Rev: origδT.Rev, Rev: origδT.Rev,
ΔKV: make(map[Key]ΔValue, len(origδT.ΔKV)), KV: make(map[Key]ΔValue, len(origδT.KV)),
} }
for k, δv := range origδT.ΔKV { for k, δv := range origδT.KV {
klonδT.ΔKV[k] = δv klonδT.KV[k] = δv
} }
klon = append(klon, klonδT) klon = append(klon, klonδT)
} }
...@@ -525,7 +527,7 @@ func (δTtail *_ΔTtail) rebuild1(atPrev zodb.Tid, δZ zodb.ΔRevEntry, trackNew ...@@ -525,7 +527,7 @@ func (δTtail *_ΔTtail) rebuild1(atPrev zodb.Tid, δZ zodb.ΔRevEntry, trackNew
}) })
if j == l || δTtail.vδT[j].Rev != δZ.Rev { if j == l || δTtail.vδT[j].Rev != δZ.Rev {
newRevEntry = true newRevEntry = true
δTcurr := ΔTree{Rev: δZ.Rev, ΔKV: map[Key]ΔValue{}} δTcurr := ΔTree{Rev: δZ.Rev, KV: map[Key]ΔValue{}}
// insert(@j, δTcurr) // insert(@j, δTcurr)
δTtail.vδT = append(δTtail.vδT[:j], δTtail.vδT = append(δTtail.vδT[:j],
append([]ΔTree{δTcurr}, append([]ΔTree{δTcurr},
...@@ -537,13 +539,13 @@ func (δTtail *_ΔTtail) rebuild1(atPrev zodb.Tid, δZ zodb.ΔRevEntry, trackNew ...@@ -537,13 +539,13 @@ func (δTtail *_ΔTtail) rebuild1(atPrev zodb.Tid, δZ zodb.ΔRevEntry, trackNew
// the diff was backward; δTtail entries are with diff forward // the diff was backward; δTtail entries are with diff forward
δv.New, δv.Old = δv.Old, δv.New δv.New, δv.Old = δv.Old, δv.New
δv_, already := δTcurr.ΔKV[k] δv_, already := δTcurr.KV[k]
if already { if already {
if δv != δv_ { if δv != δv_ {
panicf("[%v] inconsistent δv:\nδTcurr: %v\nδT: %v", k, δTcurr, δT) panicf("[%v] inconsistent δv:\nδTcurr: %v\nδT: %v", k, δTcurr, δT)
} }
} else { } else {
δTcurr.ΔKV[k] = δv δTcurr.KV[k] = δv
} }
} }
...@@ -597,7 +599,7 @@ func (δBtail *ΔBtail) Update(δZ *zodb.EventCommit) (_ ΔB, err error) { ...@@ -597,7 +599,7 @@ func (δBtail *ΔBtail) Update(δZ *zodb.EventCommit) (_ ΔB, err error) {
if l > 0 { if l > 0 {
δT := δTtail.vδT[l-1] // δT head δT := δTtail.vδT[l-1] // δT head
if δT.Rev == δZ.Tid { if δT.Rev == δZ.Tid {
δB.ByRoot[root] = δT.ΔKV δB.ByRoot[root] = δT.KV
} }
} }
...@@ -677,7 +679,7 @@ func (δBtail *ΔBtail) _Update1(δZ *zodb.EventCommit) (δB1 _ΔBUpdate1, err e ...@@ -677,7 +679,7 @@ func (δBtail *ΔBtail) _Update1(δZ *zodb.EventCommit) (δB1 _ΔBUpdate1, err e
// XXX also needs vδT clone here? // XXX also needs vδT clone here?
δTtail := δBtail.vδTbyRoot[root] // must be there δTtail := δBtail.vδTbyRoot[root] // must be there
if len(δT) > 0 { // an object might be resaved without change if len(δT) > 0 { // an object might be resaved without change
δTtail.vδT = append(δTtail.vδT, ΔTree{Rev: δZ.Tid, ΔKV: δT}) δTtail.vδT = append(δTtail.vδT, ΔTree{Rev: δZ.Tid, KV: δT})
} }
δBtail.trackSet.ApplyΔ(δtrack) δBtail.trackSet.ApplyΔ(δtrack)
...@@ -808,10 +810,10 @@ func (δBtail *ΔBtail) GetAt(root zodb.Oid, key Key, at zodb.Tid) (value Value, ...@@ -808,10 +810,10 @@ func (δBtail *ΔBtail) GetAt(root zodb.Oid, key Key, at zodb.Tid) (value Value,
panicf("δBtail: root<%s> not tracked", root) panicf("δBtail: root<%s> not tracked", root)
} }
// XXX -> index lastXXXOf(key) | linear scan ↓ looking for change <= at // TODO -> index lastRevOf(key) | linear scan ↓ looking for change <= at
for i := len(δTtail.vδT)-1; i >= 0; i-- { for i := len(δTtail.vδT)-1; i >= 0; i-- {
δT := δTtail.vδT[i] δT := δTtail.vδT[i]
δvalue, ok_ := δT.ΔKV[key] δvalue, ok_ := δT.KV[key]
if ok_ { if ok_ {
valueExact = true valueExact = true
if δT.Rev > at { if δT.Rev > at {
......
...@@ -1186,12 +1186,12 @@ func TestΔBtailSliceByRootRev(t_ *testing.T) { ...@@ -1186,12 +1186,12 @@ func TestΔBtailSliceByRootRev(t_ *testing.T) {
t := xbtreetest.NewT(t_) t := xbtreetest.NewT(t_)
X := exc.Raiseif X := exc.Raiseif
// ΔT is similar to ΔTree but uses Δstring instead of ΔValue for ΔKV // ΔT is similar to ΔTree but uses Δstring instead of ΔValue for KV
type ΔT struct { type ΔT struct {
Rev zodb.Tid Rev zodb.Tid
ΔKV map[Key]Δstring KV map[Key]Δstring
} }
// δ is shorthand for ΔKV // δ is shorthand for ΔT.KV
type δ = map[Key]Δstring type δ = map[Key]Δstring
t0 := t.CommitTree("T2/B1:a-B2:f") t0 := t.CommitTree("T2/B1:a-B2:f")
...@@ -1219,7 +1219,7 @@ func TestΔBtailSliceByRootRev(t_ *testing.T) { ...@@ -1219,7 +1219,7 @@ func TestΔBtailSliceByRootRev(t_ *testing.T) {
var vδT_ []ΔT var vδT_ []ΔT
for _, δT := range vδT { for _, δT := range vδT {
tj := t.XGetCommit(δT.Rev) tj := t.XGetCommit(δT.Rev)
δt := ΔT{δT.Rev, xgetδKV(tj.Prev, tj, δT.ΔKV)} δt := ΔT{δT.Rev, xgetδKV(tj.Prev, tj, δT.KV)}
vδT_ = append(vδT_, δt) vδT_ = append(vδT_, δt)
} }
...@@ -1228,11 +1228,11 @@ func TestΔBtailSliceByRootRev(t_ *testing.T) { ...@@ -1228,11 +1228,11 @@ func TestΔBtailSliceByRootRev(t_ *testing.T) {
} }
have := []string{} have := []string{}
for _, δT := range vδT_ { for _, δT := range vδT_ {
have = append(have, fmt.Sprintf("@%s·%v", t.AtSymb(δT.Rev), δT.ΔKV)) have = append(have, fmt.Sprintf("@%s·%v", t.AtSymb(δT.Rev), δT.KV))
} }
want := []string{} want := []string{}
for _, δT := range vδTok { for _, δT := range vδTok {
want = append(want, fmt.Sprintf("@%s·%v", t.AtSymb(δT.Rev), δT.ΔKV)) want = append(want, fmt.Sprintf("@%s·%v", t.AtSymb(δT.Rev), δT.KV))
} }
t.Errorf("%s:\nhave: %s\nwant: %s", subj, have, want) t.Errorf("%s:\nhave: %s\nwant: %s", subj, have, want)
} }
...@@ -1254,16 +1254,16 @@ func TestΔBtailSliceByRootRev(t_ *testing.T) { ...@@ -1254,16 +1254,16 @@ func TestΔBtailSliceByRootRev(t_ *testing.T) {
// sXX should be all aliased to vδT // sXX should be all aliased to vδT
gg, _ := t0.XGetBlkByName("g") gg, _ := t0.XGetBlkByName("g")
hh, _ := t0.XGetBlkByName("h") hh, _ := t0.XGetBlkByName("h")
vδT[0].Rev = t0.At; δkv0 := vδT[0].ΔKV; vδT[0].ΔKV = map[Key]ΔValue{11:{gg,gg}} vδT[0].Rev = t0.At; δkv0 := vδT[0].KV; vδT[0].KV = map[Key]ΔValue{11:{gg,gg}}
vδT[1].Rev = t0.At; δkv1 := vδT[1].ΔKV; vδT[1].ΔKV = map[Key]ΔValue{12:{hh,hh}} vδT[1].Rev = t0.At; δkv1 := vδT[1].KV; vδT[1].KV = map[Key]ΔValue{12:{hh,hh}}
assertvδT("t2.vδT*", vδT, ΔT{t0.At, δ{11:{g,g}}}, ΔT{t0.At, δ{12:{h,h}}}) assertvδT("t2.vδT*", vδT, ΔT{t0.At, δ{11:{g,g}}}, ΔT{t0.At, δ{12:{h,h}}})
assertvδT("t2.s00*", s00) assertvδT("t2.s00*", s00)
assertvδT("t2.s01*", s01, ΔT{t0.At, δ{11:{g,g}}}) assertvδT("t2.s01*", s01, ΔT{t0.At, δ{11:{g,g}}})
assertvδT("t2.s02*", s02, ΔT{t0.At, δ{11:{g,g}}}, ΔT{t0.At, δ{12:{h,h}}}) assertvδT("t2.s02*", s02, ΔT{t0.At, δ{11:{g,g}}}, ΔT{t0.At, δ{12:{h,h}}})
assertvδT("t2.s12*", s12, ΔT{t0.At, δ{12:{h,h}}}) assertvδT("t2.s12*", s12, ΔT{t0.At, δ{12:{h,h}}})
assertvδT("2.s22*", s22) assertvδT("2.s22*", s22)
vδT[0].Rev = t1.At; vδT[0].ΔKV = δkv0 vδT[0].Rev = t1.At; vδT[0].KV = δkv0
vδT[1].Rev = t2.At; vδT[1].ΔKV = δkv1 vδT[1].Rev = t2.At; vδT[1].KV = δkv1
assertvδT("t2.vδT+", vδT, ΔT{t1.At, δ{2:{f,g}}}, ΔT{t2.At, δ{2:{g,h}}}) assertvδT("t2.vδT+", vδT, ΔT{t1.At, δ{2:{f,g}}}, ΔT{t2.At, δ{2:{g,h}}})
assertvδT("t2.s00+", s00) assertvδT("t2.s00+", s00)
assertvδT("t2.s01+", s01, ΔT{t1.At, δ{2:{f,g}}}) assertvδT("t2.s01+", s01, ΔT{t1.At, δ{2:{f,g}}})
...@@ -1299,8 +1299,8 @@ func TestΔBtailSliceByRootRev(t_ *testing.T) { ...@@ -1299,8 +1299,8 @@ func TestΔBtailSliceByRootRev(t_ *testing.T) {
// sXX_ should be all aliased to vδT, but not sXX // sXX_ should be all aliased to vδT, but not sXX
bb, _ := t0.XGetBlkByName("b") bb, _ := t0.XGetBlkByName("b")
cc, _ := t0.XGetBlkByName("c") cc, _ := t0.XGetBlkByName("c")
vδT[0].Rev = t0.At; δkv0 = vδT[0].ΔKV; vδT[0].ΔKV = map[Key]ΔValue{111:{bb,bb}} vδT[0].Rev = t0.At; δkv0 = vδT[0].KV; vδT[0].KV = map[Key]ΔValue{111:{bb,bb}}
vδT[1].Rev = t0.At; δkv1 = vδT[1].ΔKV; vδT[1].ΔKV = map[Key]ΔValue{112:{cc,cc}} vδT[1].Rev = t0.At; δkv1 = vδT[1].KV; vδT[1].KV = map[Key]ΔValue{112:{cc,cc}}
assertvδT("t12.vδT*", vδT, ΔT{t0.At, δ{111:{b,b}}}, ΔT{t0.At, δ{112:{c,c}}}) assertvδT("t12.vδT*", vδT, ΔT{t0.At, δ{111:{b,b}}}, ΔT{t0.At, δ{112:{c,c}}})
assertvδT("t12.s00*", s00) assertvδT("t12.s00*", s00)
assertvδT("t12.s00_*", s00_) assertvδT("t12.s00_*", s00_)
...@@ -1313,8 +1313,8 @@ func TestΔBtailSliceByRootRev(t_ *testing.T) { ...@@ -1313,8 +1313,8 @@ func TestΔBtailSliceByRootRev(t_ *testing.T) {
assertvδT("t12.s22*", s22) assertvδT("t12.s22*", s22)
assertvδT("t12.s22_*", s22_) assertvδT("t12.s22_*", s22_)
vδT[0].Rev = t1.At; vδT[0].ΔKV = δkv0 vδT[0].Rev = t1.At; vδT[0].KV = δkv0
vδT[1].Rev = t2.At; vδT[1].ΔKV = δkv1 vδT[1].Rev = t2.At; vδT[1].KV = δkv1
assertvδT("t12.vδT+", vδT, ΔT{t1.At, δ{1:{a,b},2:{f,g}}}, ΔT{t2.At, δ{1:{b,c},2:{g,h}}}) assertvδT("t12.vδT+", vδT, ΔT{t1.At, δ{1:{a,b},2:{f,g}}}, ΔT{t2.At, δ{1:{b,c},2:{g,h}}})
assertvδT("t12.s00+", s00) assertvδT("t12.s00+", s00)
assertvδT("t12.s00_+", s00_) assertvδT("t12.s00_+", s00_)
...@@ -1547,7 +1547,7 @@ func assertΔTtail(t *testing.T, subj string, δbtail *ΔBtail, tj *xbtreetest.C ...@@ -1547,7 +1547,7 @@ func assertΔTtail(t *testing.T, subj string, δbtail *ΔBtail, tj *xbtreetest.C
atPrev := t0.At atPrev := t0.At
for _, δToid := range vδToid { for _, δToid := range vδToid {
vat = append(vat, δToid.Rev) vat = append(vat, δToid.Rev)
δT := xgetδKV(T.XGetCommit(atPrev), T.XGetCommit(δToid.Rev), δToid.ΔKV) // {} k -> δ(ZBlk(oid).data) δT := xgetδKV(T.XGetCommit(atPrev), T.XGetCommit(δToid.Rev), δToid.KV) // {} k -> δ(ZBlk(oid).data)
vδT = append(vδT, δT) vδT = append(vδT, δT)
atPrev = δToid.Rev atPrev = δToid.Rev
} }
......
...@@ -707,7 +707,7 @@ func (δFtail *ΔFtail) SliceByFileRev(zfile *ZBigFile, lo, hi zodb.Tid) /*reado ...@@ -707,7 +707,7 @@ func (δFtail *ΔFtail) SliceByFileRev(zfile *ZBigFile, lo, hi zodb.Tid) /*reado
// changes to 2 should not be present at all. // changes to 2 should not be present at all.
ZinblkAdj := map[zodb.Oid]setI64{} ZinblkAdj := map[zodb.Oid]setI64{}
for _, δT := range vδT { for _, δT := range vδT {
for blk, δzblk := range δT.ΔKV { for blk, δzblk := range δT.KV {
if δzblk.Old != xbtree.VDEL { if δzblk.Old != xbtree.VDEL {
inblk, ok := ZinblkAdj[δzblk.Old] inblk, ok := ZinblkAdj[δzblk.Old]
if ok { if ok {
...@@ -756,8 +756,8 @@ func (δFtail *ΔFtail) SliceByFileRev(zfile *ZBigFile, lo, hi zodb.Tid) /*reado ...@@ -756,8 +756,8 @@ func (δFtail *ΔFtail) SliceByFileRev(zfile *ZBigFile, lo, hi zodb.Tid) /*reado
// δT -> adjust Zinblk + update δf // δT -> adjust Zinblk + update δf
if it >= 0 { if it >= 0 {
δT := vδT[it] δT := vδT[it]
//fmt.Printf("δT @%s %v\n", δT.Rev, δT.ΔKV) //fmt.Printf("δT @%s %v\n", δT.Rev, δT.KV)
for blk, δzblk := range δT.ΔKV { for blk, δzblk := range δT.KV {
// apply in reverse as we go ← // apply in reverse as we go ←
if δzblk.New != xbtree.VDEL { if δzblk.New != xbtree.VDEL {
inblk, ok := Zinblk[δzblk.New] inblk, ok := Zinblk[δzblk.New]
......
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