Help us shape the future of Go! Take the 2026 Go Developer Survey

skyobject

package
v1.3.104 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 31, 2026 License: AGPL-3.0 Imports: 18 Imported by: 0

README

skyobject

GoDoc

Skyobject represents CX objects tree.

See wiki

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

View Source
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

View Source
var (
	ErrObjectIsTooLarge = errors.New("object is too large (see MaxObjectSize)")
	ErrTerminated       = errors.New("terminated")
	ErrBlankRegistryRef = errors.New("blank registry reference")
)

common errors

Functions

func DataDir

func DataDir() string

DataDir returns path to default data directory

func UserHome

func UserHome() string

UserHome returns the current user home path

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

func (c *Cache) AddRegistryToCache(r *registry.Registry)

AddRegistryToCache adds given registry to Cache

func (*Cache) CachedKeys

func (c *Cache) CachedKeys() map[cipher.SHA256]struct{}

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) Close

func (c *Cache) Close() (err error)

Clsoe the Cache returning DB error or nil

func (*Cache) Finc

func (c *Cache) Finc(
	key cipher.SHA256,
	inc int,
) (
	err error,
)

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

func (c *Cache) Get(
	key cipher.SHA256,
	inc int,
) (
	val []byte,
	rc int,
	err error,
)

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) Inc

func (c *Cache) Inc(
	key cipher.SHA256,
	inc int,
) (
	rc int,
	err error,
)

Inc used to change rc of an existing value

func (*Cache) IsCached

func (c *Cache) IsCached(key cipher.SHA256) (yep bool)

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

func (c *Cache) Registry(
	rr registry.RegistryRef,
) (
	r *registry.Registry,
	err error,
)

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

func (c *Cache) Set(
	key cipher.SHA256,
	val []byte,
	inc int,
) (
	rc int,
	err error,
)

Set adds value to DB and to the Cache if it's enabled. The inc argument must be greater then zero

func (*Cache) SetWanted

func (c *Cache) SetWanted(
	key cipher.SHA256,
	val []byte,
) (
	rc int,
	err error,
)

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

func (c *Cache) Unwant(
	key cipher.SHA256,
	gc chan<- Object,
)

Unwant used to unsibscribe after the Want, if, by some reasons, the object is not wanted anymore

func (*Cache) Want

func (c *Cache) Want(
	key cipher.SHA256,
	gc chan<- Object,
	inc int,
) (
	err error,
)

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

func (c *Cache) WantArriving(
	key cipher.SHA256,
	gc chan<- Object,
) (
	ok bool,
	err error,
)

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

func (c *Cache) WithBatch(fn func() error) error

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:

  1. 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.
  2. 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.
  3. 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

func (*Config) FromFlags

func (c *Config) FromFlags()

FromFlags associates config fields with command line flags.

func (*Config) Validate

func (c *Config) Validate() error

Validate the Config

type Container

type Container struct {
	Cache // cache of the Container
	Index // memory mapped IdxDB
	// contains filtered or unexported fields
}

A Container represents

func NewContainer

func NewContainer(conf *Config) (c *Container, err error)

NewContainer creates Container instance using provided Config. If the Config is nil, then default config is used (see NewConfig function)

func (*Container) Close

func (c *Container) Close() (err error)

Close the Container and related DB. The DB will be closed, even if the Container created with user-provided DB.

func (*Container) Config

func (c *Container) Config() (conf *Config)

Config returns configs of the Container. The Config must not be modified

func (*Container) DB

func (c *Container) DB() (db *data.DB)

DB of the Container.

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

func (c *Container) HumanCXDSPath() string

HumanCXDSPath returns human readable path to CXDS. It used by the node package for dbug logs

func (*Container) HumanIdxDBPath

func (c *Container) HumanIdxDBPath() string

HumanIdxDBPath returns human readable path to IdxDB. It used by the node package for dbug logs

func (*Container) Pack

func (c *Container) Pack(
	r *registry.Root,
	reg *registry.Registry,
) (
	p *Pack,
	err error,
)

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

func (c *Container) Preview(
	r *registry.Root,
	g Getter,
) (
	pack *Preview,
	err error,
)

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

func (c *Container) RootByHash(
	hash cipher.SHA256,
) (
	r *registry.Root,
	err error,
)

RootByHash returns Root by its hash, that is obvious. Errors the method can returns are data.ErrNotfound or decoding error

func (*Container) Save

func (c *Container) Save(up *Unpack, r *registry.Root) (err error)

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) Stat

func (c *Container) Stat() (s *Stat)

Stat retusn statistic of the Container

func (*Container) Unpack

func (c *Container) Unpack(
	sk cipher.SecKey,
	reg *registry.Registry,
) (
	up *Unpack,
	err error,
)

Unpack creates Unpack using given registry. Use the Unapck to modify a Root object and to save cahnges after.

func (*Container) Walk

func (c *Container) Walk(
	r *registry.Root,
	walkFunc registry.WalkFunc,
) (
	err error,
)

Walk walks throug given Root calling given walkFunc for every object of the Root including hash of the Root and Registry (depending on the deepper reply of the WalkFunc).

The Walk obtains objects of the Root from DB

type FeedStat

type FeedStat struct {
	// Hads contains statistic of heads
	Heads map[uint64]HeadStat
}

A FeedStat represents statistic of a feed

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) Fail

func (f *Filler) Fail(err error)

Fail used to terminate the Filler with provided error

func (*Filler) Get

func (f *Filler) Get(key cipher.SHA256) (val []byte, rc int, err error)

Get object from DB or request it usung provided channel. The Get increments references counter of value

func (*Filler) Go

func (f *Filler) Go(fn func())

Go performs some task dependig on parallelism.

func (*Filler) Pre

func (f *Filler) Pre(key cipher.SHA256) (rc int, err error)

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

func (*Filler) Registry

func (f *Filler) Registry() (reg *registry.Registry)

Registry of the Filler

func (*Filler) Run

func (f *Filler) Run() (err error)

Run the Filler. The Run method blocks until finish or first error

type Getter

type Getter interface {
	Get(key cipher.SHA256) (val []byte, err error)
}

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

func (i *Index) ActiveHead(pk cipher.PubKey) (nonce uint64)

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) AddFeed

func (i *Index) AddFeed(pk cipher.PubKey) (err error)

AddFeed adds feed

func (*Index) AddHead

func (i *Index) AddHead(pk cipher.PubKey, nonce uint64) (err error)

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

func (i *Index) AddRoot(r *registry.Root) (alreadyHave bool, err error)

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

func (i *Index) Close() (err error)

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) DelFeed

func (i *Index) DelFeed(pk cipher.PubKey) (err error)

DelFeed deletes feed with all heads and Root objects

func (*Index) DelHead

func (i *Index) DelHead(pk cipher.PubKey, nonce uint64) (err error)

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

func (i *Index) DelRoot(pk cipher.PubKey, nonce, seq uint64) (err error)

DelRoot deletes Root. The method returns data.ErrNotFound if Root doesn't exist

func (*Index) Feeds

func (i *Index) Feeds() (feeds []cipher.PubKey)

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) HasFeed

func (i *Index) HasFeed(pk cipher.PubKey) (yep bool)

HasFeed returns true if feed exists

func (*Index) HasHead

func (i *Index) HasHead(pk cipher.PubKey, nonce uint64) (yep bool)

HasHead returns true if head exists. It returns false if given feed doesn't exist

func (*Index) Heads

func (i *Index) Heads(pk cipher.PubKey) (heads []uint64, err error)

Heads returns list of heads of given feed. The list is list of nonces. One possible error is data.ErrNoSuchFeed

func (*Index) LastRoot

func (i *Index) LastRoot(
	pk cipher.PubKey,
	nonce uint64,
) (
	r *registry.Root,
	err error,
)

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

func (i *Index) LastRootSeq(
	pk cipher.PubKey,
	nonce uint64,
) (
	seq uint64,
	err error,
)

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

func (*Index) RootSeqs added in v1.3.98

func (i *Index) RootSeqs(
	pk cipher.PubKey,
	nonce uint64,
) (
	seqs []uint64,
	err error,
)

RootSeqs returns the seq numbers of the Roots stored for given head of given feed, ascending. It lists what is there, so a caller pruning old Roots touches only those rather than probing every seq down to zero.

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

Hash of the large object

type ObjectsStat

type ObjectsStat struct {
	Amount statutil.Amount
	Volume statutil.Volume
}

An ObjectsStat represents statistics of objects

type Pack

type Pack struct {
	// contains filtered or unexported fields
}

A Pack implements registry.Pack interface

func (*Pack) Add

func (p *Pack) Add(val []byte) (key cipher.SHA256, err error)

Add is Set that calculates hash inside

func (*Pack) AddFlags

func (p *Pack) AddFlags(flags registry.Flags)

AddFlags adds given flags to flags of the Pack (|)

func (*Pack) ClearFlags

func (p *Pack) ClearFlags(flags registry.Flags)

ClearFlags isclears given flags from flags of the Pack (&^)

func (*Pack) Degree

func (p *Pack) Degree() registry.Degree

Degree of the Pack

func (*Pack) Flags

func (p *Pack) Flags() registry.Flags

Flags of the Pack

func (*Pack) Get

func (p *Pack) Get(key cipher.SHA256) (val []byte, err error)

Get value by hash

func (*Pack) Registry

func (p *Pack) Registry() (reg *registry.Registry)

Registry returns related registry

func (*Pack) Set

func (p *Pack) Set(key cipher.SHA256, val []byte) (err error)

Set key-value pair

func (*Pack) SetDegree

func (p *Pack) SetDegree(degree registry.Degree) (err error)

SetDegree to 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

func (*Preview) Get

func (p *Preview) Get(key cipher.SHA256) (val []byte, err error)

Get from DB or from remote peer

func (*Preview) Root

func (p *Preview) Root() (r *registry.Root)

Root of the Preview

type ReadWriteStat

type ReadWriteStat struct {
	RPS float64 // reads per second
	WPS float64 // writes per second
}

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

type Unpack

type Unpack struct {
	*Pack // other methods
	// contains filtered or unexported fields
}

An Unpack implements registry.Pack and used to change or cerate a Root

func (*Unpack) Add

func (u *Unpack) Add(val []byte) (key cipher.SHA256, err error)

Add value

func (*Unpack) Close

func (u *Unpack) Close() (err error)

Close the Unpack, rejecting all saved objects that will not be used

func (*Unpack) Set

func (u *Unpack) Set(key cipher.SHA256, val []byte) (err error)

Set value

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

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL