Documentation
¶
Overview ¶
Package skyobject pkg/cxo/skyobject/cache.go c2-net-cxo
Package skyobject pkg/cxo/skyobject/config.go c2-net-cxo
Package skyobject pkg/cxo/skyobject/container.go c2-net-cxo
Package skyobject pkg/cxo/skyobject/cxds_stat.go c2-net-cxo
Package skyobject pkg/cxo/skyobject/del_pack.go c2-net-cxo
Package skyobject pkg/cxo/skyobject/errors.go c2-net-cxo
Package skyobject pkg/cxo/skyobject/fill.go c2-net-cxo
Package skyobject pkg/cxo/skyobject/index.go c2-net-cxo
Package skyobject pkg/cxo/skyobject/index_stat.go c2-net-cxo
Package skyobject pkg/cxo/skyobject/pack.go c2-net-cxo
Package skyobject pkg/cxo/skyobject/preview.go c2-net-cxo
Package skyobject pkg/cxo/skyobject/stat.go c2-net-cxo
Package skyobject pkg/cxo/skyobject/unpack.go c2-net-cxo
Index ¶
- Constants
- Variables
- func DataDir() string
- func UserHome() string
- type Cache
- func (c *Cache) AddRegistryToCache(r *registry.Registry)
- func (c *Cache) CachedKeys() map[cipher.SHA256]struct{}
- func (c *Cache) Close() (err error)
- func (c *Cache) Finc(key cipher.SHA256, inc int) (err error)
- func (c *Cache) Get(key cipher.SHA256, inc int) (val []byte, rc int, err error)
- func (c *Cache) Inc(key cipher.SHA256, inc int) (rc int, err error)
- func (c *Cache) IsCached(key cipher.SHA256) (yep bool)
- func (c *Cache) Registry(rr registry.RegistryRef) (r *registry.Registry, err error)
- func (c *Cache) Set(key cipher.SHA256, val []byte, inc int) (rc int, err error)
- func (c *Cache) SetWanted(key cipher.SHA256, val []byte) (rc int, err error)
- func (c *Cache) Unwant(key cipher.SHA256, gc chan<- Object)
- func (c *Cache) Want(key cipher.SHA256, gc chan<- Object, inc int) (err error)
- func (c *Cache) WantArriving(key cipher.SHA256, gc chan<- Object) (ok bool, err error)
- func (c *Cache) WithBatch(fn func() error) error
- type CachePolicy
- type Config
- type Container
- func (c *Container) Close() (err error)
- func (c *Container) Config() (conf *Config)
- func (c *Container) DB() (db *data.DB)
- func (c *Container) Fill(r *registry.Root, rq chan<- cipher.SHA256, maxParall int) (f *Filler)
- func (c *Container) HumanCXDSPath() string
- func (c *Container) HumanIdxDBPath() string
- func (c *Container) Pack(r *registry.Root, reg *registry.Registry) (p *Pack, err error)
- func (c *Container) Preview(r *registry.Root, g Getter) (pack *Preview, err error)
- func (c *Container) RootByHash(hash cipher.SHA256) (r *registry.Root, err error)
- func (c *Container) Save(up *Unpack, r *registry.Root) (err error)
- func (c *Container) Stat() (s *Stat)
- func (c *Container) Unpack(sk cipher.SecKey, reg *registry.Registry) (up *Unpack, err error)
- func (c *Container) Walk(r *registry.Root, walkFunc registry.WalkFunc) (err error)
- type FeedStat
- type Filler
- func (f *Filler) Close()
- func (f *Filler) Fail(err error)
- func (f *Filler) Get(key cipher.SHA256) (val []byte, rc int, err error)
- func (f *Filler) Go(fn func())
- func (f *Filler) Pre(key cipher.SHA256) (rc int, err error)
- func (f *Filler) Registry() (reg *registry.Registry)
- func (f *Filler) Run() (err error)
- type Getter
- type HeadStat
- type Index
- func (i *Index) ActiveHead(pk cipher.PubKey) (nonce uint64)
- func (i *Index) AddFeed(pk cipher.PubKey) (err error)
- func (i *Index) AddHead(pk cipher.PubKey, nonce uint64) (err error)
- func (i *Index) AddRoot(r *registry.Root) (alreadyHave bool, err error)
- func (i *Index) Close() (err error)
- func (i *Index) DelFeed(pk cipher.PubKey) (err error)
- func (i *Index) DelHead(pk cipher.PubKey, nonce uint64) (err error)
- func (i *Index) DelRoot(pk cipher.PubKey, nonce, seq uint64) (err error)
- func (i *Index) Feeds() (feeds []cipher.PubKey)
- func (i *Index) HasFeed(pk cipher.PubKey) (yep bool)
- func (i *Index) HasHead(pk cipher.PubKey, nonce uint64) (yep bool)
- func (i *Index) Heads(pk cipher.PubKey) (heads []uint64, err error)
- func (i *Index) LastRoot(pk cipher.PubKey, nonce uint64) (r *registry.Root, err error)
- func (i *Index) LastRootSeq(pk cipher.PubKey, nonce uint64) (seq uint64, err error)
- func (i *Index) PreviewRoot(pk cipher.PubKey, sig cipher.Sig, val []byte) (r *registry.Root, err error)
- func (i *Index) ReceivedRoot(pk cipher.PubKey, sig cipher.Sig, val []byte) (r *registry.Root, err error)
- func (i *Index) Root(feed cipher.PubKey, nonce uint64, seq uint64) (r *registry.Root, err error)
- func (i *Index) RootSeqs(pk cipher.PubKey, nonce uint64) (seqs []uint64, err error)
- type Object
- type ObjectIsTooLargeError
- type ObjectsStat
- type Pack
- func (p *Pack) Add(val []byte) (key cipher.SHA256, err error)
- func (p *Pack) AddFlags(flags registry.Flags)
- func (p *Pack) ClearFlags(flags registry.Flags)
- func (p *Pack) Degree() registry.Degree
- func (p *Pack) Flags() registry.Flags
- func (p *Pack) Get(key cipher.SHA256) (val []byte, err error)
- func (p *Pack) Registry() (reg *registry.Registry)
- func (p *Pack) Set(key cipher.SHA256, val []byte) (err error)
- func (p *Pack) SetDegree(degree registry.Degree) (err error)
- type Preview
- type ReadWriteStat
- type RootStat
- type Stat
- type Unpack
Constants ¶
const ( Prefix string = "[skyobject] " // default log prefix RollAvgSamples int = 5 // rolling average samples Degree registry.Degree = 16 // default dgree of registry.Refs CacheMaxAmount int = 4096 // 4K CacheMaxVolume int = 8192 * 1024 // 8M CacheRegistries int = 5 // 5 CacheCleaning float64 = 0.8 // down to 80% // CacheMaxItemSize is 1M (CacheMaxVolume*(1.0-CacheCleaning) / 2) CacheMaxItemSize int = 1024 * 1024 MaxObjectSize int = 16 * 1024 * 1024 // default is 16M MaxFillingParallel int = 10 // ten parallel subtrees // DB related constants CXDS string = "cxds.db" // default CXDS file name IdxDB string = "idx.db" // default IdxDB file name PackSavePin log.Pin = 1 << iota // show time of (*Pack).Save in logs CleanUpVerbosePin // show collecting and removing times FillVerbosePin // show filling debug logs FillPin // show filling time VerbosePin // too many logs to show )
config related constants and defaults
Variables ¶
var ( ErrObjectIsTooLarge = errors.New("object is too large (see MaxObjectSize)") ErrTerminated = errors.New("terminated") ErrBlankRegistryRef = errors.New("blank registry reference") )
common errors
Functions ¶
Types ¶
type Cache ¶
type Cache struct {
// contains filtered or unexported fields
}
A Cache is internal and used by Container. The Cache can't be created and used outside
func (*Cache) AddRegistryToCache ¶
AddRegistryToCache adds given registry to Cache
func (*Cache) CachedKeys ¶
CachedKeys returns a fresh snapshot of every key currently tracked by the cache. The returned set has no ties to the live map — once the lock is released the cache can mutate freely, and callers can hold the set while doing IO (e.g. bbolt iteration) without risking the IsCached lock-ordering deadlock.
The snapshot can race with Set: a key that's about to enter the cache may be missing, and a key that just left may still appear. Callers (DB cleanup) accept that — the goal is "don't delete an object the cache might still resurrect", and a slightly stale snapshot strictly favors safety: a key that races out of the cache after the snapshot was taken is still kept on disk for one extra sweep, never deleted while live.
func (*Cache) Finc ¶
Finc is like the Inc, but it used by fillers to apply incs of filler or reject them. See the Want for details. The method does nothing is item with given key is not a filling item. If the inc argument greater then zero, then it is the apply. Otherwise, it is the reject. The Finc must be called after the moment when item received through gc channell passed to the Want method. The Finc must not be called if the received item is erroneous
func (*Cache) Get ¶
Get from cache or DB, increasing, leaving as is, or reducing references counter. For most reading cases the inc argument should be zero. If value doesn't exist the Get returns data.ErrNotFound. It's possible to get and remove value using the inc argument. The Get returns value and new references counter. The Get can returns an error that doesn't relate to given element. Putting element to the Cache the Get can clean up cache to free space, syncing with DB. In this case if the synching fails, the Get can returns valid value and rc and some error. Anyway, any DB failure should be fatal. E.g. all errors except data.ErrNotFound and ObjectIsTooLargeError means that data in the DB can be lost
func (*Cache) IsCached ¶
IsCached returns true if items with given key is cached. The item is not value and a cached item may not exist in the cache and in DB too. If an item is cached, then it should not be removed from DB. Because of write-behind caching. Also, in some rare cases, a value can be "resurrected" if it's cached (e.g. its rc will be increased from zero).
Use this method cleaning up DB.
CAUTION: callers must not be holding any lock that Cache.Set's critical section can transitively reach. In particular, never call IsCached from inside a bbolt.DB.Update callback — Cache.Set takes c.mx then opens a bbolt RWTx, so calling IsCached from within a bbolt RWTx inverts that ordering and deadlocks. For iteration patterns, use CachedKeys to snapshot once up front.
func (*Cache) Registry ¶
Registry returns Registry by reference. The Registry looks the Cache first. If it gets Registry from DB, then it put the Registry to the Cache
func (*Cache) Set ¶
Set adds value to DB and to the Cache if it's enabled. The inc argument must be greater then zero
func (*Cache) SetWanted ¶
SetWanted is like the Set, but is set value only if the value is wanted. The SetWanted never returns "not wanted" error.
func (*Cache) Unwant ¶
Unwant used to unsibscribe after the Want, if, by some reasons, the object is not wanted anymore
func (*Cache) Want ¶
Want subscribes to object. If object already exists then it will be sent through given channel. If the Want called many times with the same channel, then requested object will be received once. The Want used for filling and have very specific pitfalls. The inc is inc of fillers and after the Want, a filler have to call Unwant and Finc to notify the cache that this object now is part of a full Root objects. Or to notify the cache that filling breaks and inc of the object decrements. The cache never blocks sending to channels, thus, the channel should be buffered.
func (*Cache) WantArriving ¶
WantArriving is Want with inc 0 for serving a peer. It sends the object if it is stored, or waits for it only if a filler already wants it. Otherwise it returns false and registers nothing.
func (*Cache) WithBatch ¶
WithBatch runs fn with the Cache's underlying CXDS pinned to a single transaction-scoped handle. Every Cache.Set / Cache.Get / Cache.Inc invoked from fn (directly or transitively, including the recursive walks inside Container.Save) runs its bbolt work inside that one tx — replacing N per-leaf commits with a single one. fn returning nil commits the tx; a non-nil return rolls it back.
LOCK ORDER — the reason this function is shaped the way it is.
Two locks are in play: c.mx and bbolt's writer lock (held for the whole of DB.Update / DB.Batch). Everywhere else in the Cache the order is c.mx → writer: Cache.Get(key, inc != 0) and Cache.Set on a miss take c.mx and then reach bbolt, which needs the writer for the refcount bump. This function is the one place that would take them the other way round — RunBatch opens the tx (writer) and fn then calls back into Cache.Set (c.mx) — and that inversion deadlocked:
G1 fill: holds c.mx → waits for the writer (DB.Batch) G2 publish: holds the writer → waits for c.mx (Cache.Set in fn)
It wedged the node permanently: the publisher never cleared dirty, every later send was silently lost, and teardown hung because the cleanup sweep also wants c.mx. Windows CI hit it as a 25-minute package timeout in cmd/apps/skychat/pairing, which publishes and subscribes on one node by design.
The fix is to make c.mx → writer hold here too, WITHOUT holding c.mx across fn (fn's own Cache.Set needs it, and the mutex isn't reentrant). Three windows, in order:
- Take c.mx BEFORE opening the tx. Anyone already inside the Cache — possibly blocked in bbolt — finishes first, so we never open the writer underneath a c.mx holder that still needs it.
- Store the pin, then release c.mx. From here every arriving Cache op sees the pin and joins our tx, so none of them touches the writer while we own it. fn runs in this window.
- Re-take c.mx BEFORE clearing the pin. Taking it is safe (by (2) no c.mx holder is waiting on the writer) and it drains anyone mid-call on the scoped handle; clearing the pin only afterwards means no goroutine can pick the unpinned store up while the tx is still open. c.mx is released after RunBatch returns, i.e. after the commit.
The cost of step (1) is that Cache operations now also queue behind however long the writer takes to become free — including a long RemoveObjects sweep. Before, an inc==0 read (bbolt View, no writer) could slip past. That is latency, not a cycle: nothing that holds the writer ever asks for c.mx (RemoveObjects deliberately snapshots CachedKeys up front for this reason), so the wait always ends.
fn must not retain the pinned handle past its return — the tx is gone afterward. WithBatch is not reentrant (step 1 would deadlock against itself); it has a single caller, treestore.publishRoot.
type CachePolicy ¶
type CachePolicy int
A CachePolicy represents cache policy that is obvious
const ( LRU CachePolicy = iota // LRU cache LFU // LFU cache )
cache policies
func (CachePolicy) String ¶
func (c CachePolicy) String() string
String implements fmt.Stringer interface
type Config ¶
type Config struct {
// Degree of registry.Refs' Merkle-trees.
// The option affects new trees only and not
// changes existsing registry.Refs
Degree registry.Degree
// RollAvgSamples is number of samples used
// for rolling (moving) average values for
// statistic
RollAvgSamples int
// TrackRollingAverages runs the per-second goroutines that roll the
// statistics above into moving averages. Default true.
//
// Those averages are readable only through Container.Stat() -> Node.Stat()
// -> the node RPC, so a node started without an RPC listener has no way to
// observe them and the goroutines tick once a second for nobody. The node
// clears this for itself when conf.RPC is empty (see node.NewNode), which
// is every in-visor CXO construction — treestore publisher and subscriber,
// cxoaggregate and cxopreview — seven nodes per visor, each running two of
// these loops. Costly out of proportion on the single-threaded js/wasm
// visor, where every wakeup is a full scheduler cycle.
//
// Counters and totals are unaffected; only the derived per-second averages
// stop advancing, and only where nothing could read them.
TrackRollingAverages bool
// CacheMaxAmount is maximum number of items the cache can
// fit. See also, CacheCleaning field
CacheMaxAmount int
// CacheMaxVolume is maximum total length of all elements of
// the caceh. See also CacheCleaning field
CacheMaxVolume int
// CachePolicy is policy of the Cache. By default it's LRU,
// but it's possible to choose LFU if you want
CachePolicy CachePolicy
// CacheRegistries is number of Registries the Cache
// will keep unpacked. A Registry is fast for access
// but decoding is slow. And to increase performance
// the Cache keeps some Registries unpacked. Set this
// field to zero to turn off caching of Registries.
// This number should not be too big. Becuse the
// CacheCleaning field and strategy doesn't affect
// the Registries. If the caceh of the Registries is
// full then one removed and one appended
CacheRegistries int
// CacheCleaning is a flaot point number from 0.5 to 0.9.
// The number is percent. If the Cache is full, then the
// will be cleaned down to this percent of fullness. E.g.
// the cache never exceeds the CacheMaxAmount and the
// CacheMaxVolume boundaries. Reaching them, the Cache
// cleans itself down to the percent using given
// CachePolicy
CacheCleaning float64
// CacheMaxItemSize is max size of an item the cache will
// keep inside. All items bigger will be put to DB directly.
// This required to don't keep very big items in the cache.
// This items can will break caching algorithms. The
// CacheMaxItemSize can't be bigger then
// CacheMaxVolume*(1.0 - CacheCleaning)
CacheMaxItemSize int
// MaxObjectSize is max size of object the CXO can
// manipulate. The size is size of encoded vlaue. The
// limit is required to protect against intentional
// DoS attacks. Because, CXO manipulate with objects
// in RAM a very big object can break a node.
//
// So, reducing this size be sure that database doesn't
// contain object large then this limit. Otherwise CXO
// falls. To check DB after reducing set the CheckSizes
// config to true. If DB contains objects large then
// this limit the NewContiner returns error. And this
// error can't be solved by CXO, e.g. you should
// resolve it yourself. But DB doesn't have any limits
// and it will wroks (separetly) fine.
//
// The MaxObjectSize can't be less then 1024
MaxObjectSize int
// MaxFillingParallel is limit of subtrees that used
// by Filler at the same time. The Filler can walk
// all possible subtress sumultaneously, creating
// goroutines. The MaxFillingParallel should be closer
// to number of connections that used to fill a Root.
MaxFillingParallel int
// CheckSizes force Container to check sizes of objects
// in database. The option can be useful if MaxObjectSize
// was reduced after last start and you not sure that
// DB contains valid objects. If this option is true then
// Container check DB and returns an error if there are
// objects alrge then MaxObjectSize limit. But, the
// checking stops on first error.
CheckSizes bool
// InMemoryDB uses database in memory. The option is
// usability trick for test. If DB field (see blow) is
// nil and this field is treu, then default database in
// memory will be created and used
InMemoryDB bool
// DBPath is path to database file. Because DB consist of
// two files, the DBPath will be concated with extensions
// ".cxds" and ".idx". See also DB field. E.g. for path
// "~/.skycoin/cxo/db" Container creates or opens files
// "~/.skycoin/cxo/db.cxds" and "~/.skycoin/cxo/db.idxdb".
// The DBpath doesn't create directories. Use DataDir to
// be sure that path created. The DBPath used for tests
// and examples. But it can be used for other
DBPath string
// DataDir will be created if it's not empty. If DB field
// of the config is nil, InMemoryDB is false and DBPath
// is empty, then database will be created under the
// DataDir (even if it's empty). In this case, names of
// the files will be "db.cxds" and "db.idxdb"
DataDir string
// DB is *data.DB you can provide. If the field is not nil
// nil, then DPPath and InMemoryDB fields ignored.
DB *data.DB
// NoSyncCXDS opens the on-disk CXDS + IdxDB with NoSync=true,
// skipping fdatasync at each transaction commit. Trades crash
// durability for an order-of-magnitude reduction in write
// traffic (see cxds.DriveOptions / idxdb.DriveOptions for the
// full rationale). Set this when the underlying CXO data is
// content-addressed AND the publisher's in-memory tree is the
// source of truth — losing a torn write at crash time is fine
// because the next BatchWindow tick republishes everything.
//
// Has no effect when InMemoryDB is true or DB is non-nil
// (those paths don't open files at all).
NoSyncCXDS bool
}
A Config represents configurations and options of Container
func NewConfig ¶
func NewConfig() (conf *Config)
NewConfig returns pointer to Config with default values
type Container ¶
type Container struct {
Cache // cache of the Container
Index // memory mapped IdxDB
// contains filtered or unexported fields
}
A Container represents
func NewContainer ¶
NewContainer creates Container instance using provided Config. If the Config is nil, then default config is used (see NewConfig function)
func (*Container) Close ¶
Close the Container and related DB. The DB will be closed, even if the Container created with user-provided DB.
func (*Container) Fill ¶
func (c *Container) Fill( r *registry.Root, rq chan<- cipher.SHA256, maxParall int, ) ( f *Filler, )
Fill given Root returns Filler that fills given Root object. To request objects, the DB doesn't have, given rq channel used. The Fill used by the node package to fill Root objects. The filler must be closed after using
func (*Container) HumanCXDSPath ¶
HumanCXDSPath returns human readable path to CXDS. It used by the node package for dbug logs
func (*Container) HumanIdxDBPath ¶
HumanIdxDBPath returns human readable path to IdxDB. It used by the node package for dbug logs
func (*Container) Pack ¶
Pack returns Pack that obtains values from DB. The Pack implements Add and Set method, but using of the methods creates objects in DB that never be removed.
Use the Pack as read-only to avoid ownerless objects in DB.
To create objects updating (or creating) a Root see Unpack and Save methods of the Container.
The Pack can be used for Root.Tree and similar methods that doesn't change anything in DB.
If given Registry is nil, then the Pack method obtains registry from DB
func (*Container) Preview ¶
Preview creates Preview using given Getter and registry.Root. It returns error if the Preview method can't obtain related Registry using Container or Getter. The Preview method can blocks calling Get from given Getter. The Preview method used by node package for feeds preview
func (*Container) RootByHash ¶
RootByHash returns Root by its hash, that is obvious. Errors the method can returns are data.ErrNotfound or decoding error
func (*Container) Save ¶
Save cahnges of given Root updating seq number and timestamp of the Root. The Root should have correct Pub, and Nonce fields. The Seq field will be set to next inside the Save. The Save also set Hash and Prev fields of the Root, and signs the Root
func (*Container) Unpack ¶
Unpack creates Unpack using given registry. Use the Unapck to modify a Root object and to save cahnges after.
type Filler ¶
type Filler struct {
// contains filtered or unexported fields
}
A Filler implements registry.Splitter interface and used for filling.
func (*Filler) Close ¶
func (f *Filler) Close()
Close terminates the Split walking and waits for goroutines the split creates
func (*Filler) Get ¶
Get object from DB or request it usung provided channel. The Get increments references counter of value
func (*Filler) Pre ¶
Pre used to prerequest an item to get it late. The Get increments filling rc in the Cache. And to not increment the rc twice for an item this method used. The method doesn't return value, because nobobdy need it. The Pre used to obtain "hard rc" of an item
type Getter ¶
A Getter represents interface used to get an object if it doesn't exist in DB. The Getter used by the Preview. The Getter _must_ care about hash-value compliance
type HeadStat ¶
type HeadStat struct {
// Len is total amount of Root
// objects of this head
Len int
// First Root of the head
First RootStat
// Last is Root of the head
Last RootStat
}
A HeadStat represents statistic of a head
type Index ¶
type Index struct {
// contains filtered or unexported fields
}
Index is internal and used by Container. The Index can't be creaed and used outside. The Index keeps information about last Root objects for fast access
func (*Index) ActiveHead ¶
ActiveHead returns nonce of head that contains newest Root object of given feed. If the feed doesn't have Root objects, then reply will be zero. The ActiveHead method looks for timestamps of last Root objects only. E.g. the newest is the newest of last. For example if there are three heads with 100 Root oebjcts, then only timestamps of three last Root objects will be compared. If given feed doesn't exist in DB then reply will be zero too.
Every new Root object can change the ActiveHead value if its head is different. And it's impossible to change the ActiveHead value other ways neither than inserting Root
func (*Index) AddHead ¶
AddHead adds head. A head will be added automatically if AddRoot called and head of the Root doesn't exist. But it's possible to add an empty head to save it in DB. It has no practical value. The head will be saved in DB and the Heads method will return it even if it empty
func (*Index) AddRoot ¶
AddRoot to DB. The method doesn't create feed of the root but if head of the root doesn't exist, then the method creates the head. The method never return already have error, it returns alreadyHave reply instead. E.g. if the Container already have this Root, then the alreadyHave reply will be true. The method never save the Root inside CXDS. E.g. the method adds the Root to index (that is necessary)
func (*Index) Close ¶
Close Index syncing it with DB. Access time of Root objects is not saved in DB and should be synchronized with the Index
func (*Index) DelHead ¶
DelHead deletes given head. It can't remove head if at least one Root of the head is held, returning ErrRootIsHeld error
func (*Index) DelRoot ¶
DelRoot deletes Root. The method returns data.ErrNotFound if Root doesn't exist
func (*Index) Feeds ¶
Feeds returns list of feeds. For performance the list built once until changes (add/remove feed), thus it's unsafe to modify the list. Copy the list if you want to modify it
func (*Index) HasHead ¶
HasHead returns true if head exists. It returns false if given feed doesn't exist
func (*Index) Heads ¶
Heads returns list of heads of given feed. The list is list of nonces. One possible error is data.ErrNoSuchFeed
func (*Index) LastRoot ¶
LastRoot returns last Root of given head of given feed. The last Root is Root with the greatest seq number. If given head of the feed is blank, then the LastRoot returns data.ErrNotFound. If the head does not exist then the LastRoot returns data.ErrNoSuchFeed.
See also ActiveHead method. To get really last Root of a feed combine the methods
r, err = c.LastRoot(pk, c.ActiveHead())
The LastRoot returns Root with signature
func (*Index) LastRootSeq ¶
LastRootSeq returns seq of last Root of given head of given feed. The last Root is Root with the greatest seq number.
func (*Index) PreviewRoot ¶
func (i *Index) PreviewRoot( pk cipher.PubKey, sig cipher.Sig, val []byte, ) ( r *registry.Root, err error, )
PreviewRoot method used by node package to check a root recevied for preview-request. The method doesn't check feed, e.g. the ReceviedRoot method can returns data.ErrNoSuchFeed error. This method never return this error. And this method never set IsFull fields to true, if this Container already have this Root
func (*Index) ReceivedRoot ¶
func (i *Index) ReceivedRoot( pk cipher.PubKey, sig cipher.Sig, val []byte, ) ( r *registry.Root, err error, )
ReceivedRoot called by the node package to check a received root. The method verify hash and signature of the Root. The method also check database, may be DB already has this root. The method changes nothing in DB, it only checks the Root. The method set IsFull field of the Root to true if DB already have this Root
func (*Index) Root ¶
func (i *Index) Root( feed cipher.PubKey, nonce uint64, seq uint64, ) ( r *registry.Root, err error, )
Root of feed-head by seq number
type Object ¶
type Object struct {
Key cipher.SHA256 // hash of the Val
Val []byte // vlaue
RC int // references count (hard)
Err error // max object size error
}
An Object represents DB object that is []byte, its hash and references counter
type ObjectIsTooLargeError ¶
type ObjectIsTooLargeError struct {
// contains filtered or unexported fields
}
ObjectIsTooLargeError represents error that occurs when an object exceed max object size limit. The error contains hash of the object
func (*ObjectIsTooLargeError) Error ¶
func (o *ObjectIsTooLargeError) Error() string
Error implements error interface
func (*ObjectIsTooLargeError) Hash ¶
func (o *ObjectIsTooLargeError) Hash() cipher.SHA256
Hash of the large object
type ObjectsStat ¶
An ObjectsStat represents statistics of objects
type Pack ¶
type Pack struct {
// contains filtered or unexported fields
}
A Pack implements registry.Pack interface
func (*Pack) ClearFlags ¶
ClearFlags isclears given flags from flags of the Pack (&^)
type Preview ¶
type Preview struct {
*Pack // with Registry
// contains filtered or unexported fields
}
A Preview implements registry.Pack for feeds preview. The Preview get object of a Root from database if possible, otherwise it request this objects using provided getter. The Preview used by the node package for feeds preview
type ReadWriteStat ¶
A ReadWriteStat represents read-write statistic
type RootStat ¶
type RootStat struct {
Time time.Time // timestamp
Seq uint64 // seq number
Hash cipher.SHA256 // hash of the Root
}
A RootStat represetns brief informaion about a Root
type Stat ¶
type Stat struct {
// CXDS is statistic of CXDS key-value store.
CXDS ReadWriteStat
// Cache contains read-write statistic of the
// Cache. The Cache statistic collect only
// effective reads and writes (where data
// requested of changed in the Cache without
// DB access).
Cache ReadWriteStat
// CacheCleaning is average pause of Cache
// for cleaning
CacheCleaning time.Duration
CacheObjects ObjectsStat // cached objects
AllObjects ObjectsStat // all objects
UsedObjects ObjectsStat // used objects
// RootsPerSecond is average vlaue of new
// Root objects per second.
RootsPerSecond float64
// Feeds contains statistic of feeds
Feeds map[cipher.PubKey]FeedStat
}
A Stat represents statistic of the Container
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package registry pkg/cxo/skyobject/registry/dynamic.go c2-net-cxo
|
Package registry pkg/cxo/skyobject/registry/dynamic.go c2-net-cxo |
|
Package statutil pkg/cxo/skyobject/statutil/average.go c2-net-cxo
|
Package statutil pkg/cxo/skyobject/statutil/average.go c2-net-cxo |