Make doc state building more abstract
This commit is contained in:
parent
ec05045246
commit
1a1883d79a
9
data/docstate.go
Normal file
9
data/docstate.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package data
|
||||||
|
|
||||||
|
type DocumentState interface {
|
||||||
|
ApplyChange(change []byte, id string) (DocumentState, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type InitialStateProvider interface {
|
||||||
|
ProvideFromInitialChange(change []byte, id string) (DocumentState, error)
|
||||||
|
}
|
||||||
@ -1,59 +1,51 @@
|
|||||||
package data
|
package data
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/core/block/editor/state"
|
"fmt"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type documentStateBuilder struct {
|
type documentStateBuilder struct {
|
||||||
tree *Tree
|
tree *Tree
|
||||||
aclState *ACLState // TODO: decide if this is needed or not
|
aclState *ACLState // TODO: decide if this is needed or not
|
||||||
|
stateProvider InitialStateProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDocumentStateBuilder(tree *Tree, state *ACLState) *documentStateBuilder {
|
func newDocumentStateBuilder(tree *Tree, state *ACLState, stateProvider InitialStateProvider) *documentStateBuilder {
|
||||||
return &documentStateBuilder{
|
return &documentStateBuilder{
|
||||||
tree: tree,
|
tree: tree,
|
||||||
aclState: state,
|
aclState: state,
|
||||||
|
stateProvider: stateProvider,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: we should probably merge the two builders into one
|
// TODO: we should probably merge the two builders into one
|
||||||
func (d *documentStateBuilder) build() (s *state.State, err error) {
|
func (d *documentStateBuilder) build() (s DocumentState, err error) {
|
||||||
var (
|
var (
|
||||||
startId string
|
startId string
|
||||||
applyRoot bool
|
count int
|
||||||
st = time.Now()
|
|
||||||
lastChange *Change
|
|
||||||
count int
|
|
||||||
)
|
)
|
||||||
rootChange := d.tree.Root()
|
rootChange := d.tree.Root()
|
||||||
root := state.NewDocFromSnapshot("root", rootChange.DecryptedDocumentChange.Snapshot).(*state.State)
|
|
||||||
root.SetChangeId(rootChange.Id)
|
if rootChange.DecryptedDocumentChange == nil {
|
||||||
|
err = fmt.Errorf("root doesn't have decrypted change")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err = d.stateProvider.ProvideFromInitialChange(rootChange.DecryptedDocumentChange, rootChange.Id)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
t := d.tree
|
t := d.tree
|
||||||
if startId = root.ChangeId(); startId == "" {
|
startId = rootChange.Id
|
||||||
startId = t.RootId()
|
|
||||||
applyRoot = true
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Iterate(startId, func(c *Change) (isContinue bool) {
|
t.Iterate(startId, func(c *Change) (isContinue bool) {
|
||||||
count++
|
count++
|
||||||
lastChange = c
|
|
||||||
if startId == c.Id {
|
if startId == c.Id {
|
||||||
s = root.NewState()
|
|
||||||
if applyRoot && c.DecryptedDocumentChange != nil {
|
|
||||||
s.ApplyChangeIgnoreErr(c.DecryptedDocumentChange.Content...)
|
|
||||||
s.SetChangeId(c.Id)
|
|
||||||
s.AddFileKeys(c.DecryptedDocumentChange.FileKeys...)
|
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if c.DecryptedDocumentChange != nil {
|
if c.DecryptedDocumentChange != nil {
|
||||||
ns := s.NewState()
|
_, err = s.ApplyChange(c.DecryptedDocumentChange, c.Id)
|
||||||
ns.ApplyChangeIgnoreErr(c.DecryptedDocumentChange.Content...)
|
|
||||||
ns.SetChangeId(c.Id)
|
|
||||||
ns.AddFileKeys(c.DecryptedDocumentChange.FileKeys...)
|
|
||||||
_, _, err = state.ApplyStateFastOne(ns)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -61,12 +53,7 @@ func (d *documentStateBuilder) build() (s *state.State, err error) {
|
|||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return
|
||||||
}
|
}
|
||||||
if lastChange != nil {
|
|
||||||
s.SetLastModified(lastChange.Content.Timestamp, lastChange.Content.Identity)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Infof("build state (crdt): changes: %d; dur: %v;", count, time.Since(st))
|
|
||||||
return s, err
|
return s, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,14 +1,13 @@
|
|||||||
package data
|
package data
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/core/block/editor/state"
|
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/threadmodels"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/data/threadmodels"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ACLContext struct {
|
type ACLContext struct {
|
||||||
Tree *Tree
|
Tree *Tree
|
||||||
ACLState *ACLState
|
ACLState *ACLState
|
||||||
DocState *state.State
|
DocState DocumentState
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTreeFromThread(t threadmodels.Thread, fromStart bool) (*Tree, error) {
|
func createTreeFromThread(t threadmodels.Thread, fromStart bool) (*Tree, error) {
|
||||||
@ -21,6 +20,7 @@ func createACLStateFromThread(
|
|||||||
identity string,
|
identity string,
|
||||||
key threadmodels.EncryptionPrivKey,
|
key threadmodels.EncryptionPrivKey,
|
||||||
decoder threadmodels.SigningPubKeyDecoder,
|
decoder threadmodels.SigningPubKeyDecoder,
|
||||||
|
provider InitialStateProvider,
|
||||||
fromStart bool) (*ACLContext, error) {
|
fromStart bool) (*ACLContext, error) {
|
||||||
tree, err := createTreeFromThread(t, fromStart)
|
tree, err := createTreeFromThread(t, fromStart)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -41,7 +41,7 @@ func createACLStateFromThread(
|
|||||||
}
|
}
|
||||||
if !valid {
|
if !valid {
|
||||||
// TODO: think about what to do if the snapshot is invalid - should we rebuild the tree without it
|
// TODO: think about what to do if the snapshot is invalid - should we rebuild the tree without it
|
||||||
return createACLStateFromThread(t, identity, key, decoder, true)
|
return createACLStateFromThread(t, identity, key, decoder, provider, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,13 +64,14 @@ func createDocumentStateFromThread(
|
|||||||
t threadmodels.Thread,
|
t threadmodels.Thread,
|
||||||
identity string,
|
identity string,
|
||||||
key threadmodels.EncryptionPrivKey,
|
key threadmodels.EncryptionPrivKey,
|
||||||
|
provider InitialStateProvider,
|
||||||
decoder threadmodels.SigningPubKeyDecoder) (*ACLContext, error) {
|
decoder threadmodels.SigningPubKeyDecoder) (*ACLContext, error) {
|
||||||
context, err := createACLStateFromThread(t, identity, key, decoder, false)
|
context, err := createACLStateFromThread(t, identity, key, decoder, provider, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
docStateBuilder := newDocumentStateBuilder(context.Tree, context.ACLState)
|
docStateBuilder := newDocumentStateBuilder(context.Tree, context.ACLState, provider)
|
||||||
docState, err := docStateBuilder.build()
|
docState, err := docStateBuilder.build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
49
go.mod
49
go.mod
@ -3,10 +3,53 @@ module github.com/anytypeio/go-anytype-infrastructure-experiments
|
|||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/awalterschulze/gographviz v0.0.0-20190522210029-fa59802746ab
|
||||||
|
github.com/goccy/go-graphviz v0.0.9
|
||||||
|
github.com/gogo/protobuf v1.3.2
|
||||||
|
github.com/libp2p/go-libp2p-core v0.8.5
|
||||||
|
github.com/mr-tron/base58 v1.2.0
|
||||||
|
github.com/prometheus/common v0.18.0
|
||||||
|
github.com/stretchr/testify v1.7.0
|
||||||
github.com/textileio/go-threads v1.0.2-0.20210304072541-d0f91da84404
|
github.com/textileio/go-threads v1.0.2-0.20210304072541-d0f91da84404
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
|
)
|
||||||
github.com/goccy/go-graphviz v0.0.9
|
|
||||||
|
require (
|
||||||
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
|
||||||
|
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
|
||||||
|
github.com/btcsuite/btcd v0.21.0-beta // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
|
||||||
|
github.com/fogleman/gg v1.3.0 // indirect
|
||||||
|
github.com/gogo/googleapis v1.3.1 // indirect
|
||||||
|
github.com/gogo/status v1.1.0 // indirect
|
||||||
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||||
|
github.com/golang/protobuf v1.4.3 // indirect
|
||||||
|
github.com/grpc-ecosystem/go-grpc-middleware v1.2.1 // indirect
|
||||||
|
github.com/ipfs/go-cid v0.0.7 // indirect
|
||||||
|
github.com/klauspost/cpuid/v2 v2.0.4 // indirect
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect
|
||||||
|
github.com/libp2p/go-buffer-pool v0.0.2 // indirect
|
||||||
|
github.com/libp2p/go-openssl v0.0.7 // indirect
|
||||||
|
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect
|
||||||
|
github.com/minio/sha256-simd v1.0.0 // indirect
|
||||||
|
github.com/multiformats/go-base32 v0.0.3 // indirect
|
||||||
|
github.com/multiformats/go-base36 v0.1.0 // indirect
|
||||||
|
github.com/multiformats/go-multiaddr v0.3.3 // indirect
|
||||||
|
github.com/multiformats/go-multibase v0.0.3 // indirect
|
||||||
|
github.com/multiformats/go-multihash v0.0.15 // indirect
|
||||||
|
github.com/multiformats/go-varint v0.0.6 // indirect
|
||||||
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/sirupsen/logrus v1.6.0 // indirect
|
||||||
|
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
|
||||||
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect
|
||||||
|
golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20210426080607-c94f62235c83 // indirect
|
||||||
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect
|
||||||
|
google.golang.org/grpc v1.33.2 // indirect
|
||||||
|
google.golang.org/protobuf v1.25.0 // indirect
|
||||||
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/textileio/go-threads => github.com/anytypeio/go-threads v1.1.0-rc1.0.20220223104843-a67245cee80e
|
replace github.com/textileio/go-threads => github.com/anytypeio/go-threads v1.1.0-rc1.0.20220223104843-a67245cee80e
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user