Commit 8685b742 authored by Kirill Smelkov's avatar Kirill Smelkov

go/zodb: Tweak documentation a bit so it renders more well in godoc

While at it add draft overview of data model & friends to package
documentation.
parent 0e28fbb8
......@@ -56,7 +56,7 @@ type Cache struct {
sizeMax int // cache is allowed to occupy not more than this
}
// oidCacheEntry maintains cached revisions for 1 oid
// oidCacheEntry maintains cached revisions for 1 oid.
type oidCacheEntry struct {
oid Oid
......@@ -70,7 +70,7 @@ type oidCacheEntry struct {
rcev []*revCacheEntry
}
// revCacheEntry is information about 1 cached oid revision
// revCacheEntry is information about 1 cached oid revision.
type revCacheEntry struct {
parent *oidCacheEntry // oidCacheEntry holding us
inLRU lruHead // in Cache.lru; protected by Cache.gcMu
......@@ -409,7 +409,7 @@ func (c *Cache) loadRCE(ctx context.Context, rce *revCacheEntry) {
c.gcMu.Unlock()
}
// tryMerge tries to merge rce prev into next
// tryMerge tries to merge rce prev into next.
//
// both prev and next must be already loaded.
// prev and next must come adjacent to each other in parent.rcev with
......@@ -561,7 +561,7 @@ func (oce *oidCacheEntry) release() {
// ----------------------------------------
// isErrNoData returns whether an error is due to "there is no such data in
// database", not e.g. some IO loading error
// database", not e.g. some IO loading error.
func isErrNoData(err error) bool {
switch err.(type) {
default:
......@@ -631,7 +631,7 @@ func (oce *oidCacheEntry) del(rce *revCacheEntry) {
}
// loaded reports whether rce was already loaded
// loaded reports whether rce was already loaded.
//
// must be called with rce.parent locked.
func (rce *revCacheEntry) loaded() bool {
......@@ -653,7 +653,7 @@ func (h *lruHead) rceFromInLRU() (rce *revCacheEntry) {
return (*revCacheEntry)(urce)
}
// errDB returns error about database being inconsistent
// errDB returns error about database being inconsistent.
func errDB(oid Oid, format string, argv ...interface{}) error {
// XXX -> separate type?
return fmt.Errorf("cache: database inconsistency: oid: %v: "+format,
......
......@@ -35,13 +35,13 @@ import (
"github.com/kylelemons/godebug/pretty"
)
// tStorage implements read-only storage for cache testing
// tStorage implements read-only storage for cache testing.
type tStorage struct {
// oid -> [](.serial↑, .data)
dataMap map[Oid][]tOidData
}
// data for oid for 1 revision
// data for oid for 1 revision.
type tOidData struct {
serial Tid
data []byte
......
......@@ -29,19 +29,19 @@ import (
"lab.nexedi.com/kirr/go123/mem"
)
// OpenOptions describes options for OpenStorage
// OpenOptions describes options for OpenStorage.
type OpenOptions struct {
ReadOnly bool // whether to open storage as read-only
NoCache bool // don't use cache for read/write operations
}
// DriverOpener is a function to open a storage driver
// DriverOpener is a function to open a storage driver.
type DriverOpener func (ctx context.Context, u *url.URL, opt *OpenOptions) (IStorageDriver, error)
// {} scheme -> DriverOpener
var driverRegistry = map[string]DriverOpener{}
// RegisterDriver registers opener to be used for URLs with scheme
// RegisterDriver registers opener to be used for URLs with scheme.
func RegisterDriver(scheme string, opener DriverOpener) {
if _, already := driverRegistry[scheme]; already {
panic(fmt.Errorf("ZODB URL scheme %q was already registered", scheme))
......@@ -107,7 +107,7 @@ type storage struct {
}
// loading always goes through cache - this way prefetching can work
// loading goes through cache - this way prefetching can work
func (s *storage) Load(ctx context.Context, xid Xid) (*mem.Buf, Tid, error) {
// XXX here: offload xid validation from cache and driver ?
......
// Copyright (C) 2016-2017 Nexedi SA and Contributors.
// Copyright (C) 2016-2018 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
......@@ -27,10 +27,10 @@ import (
pickle "github.com/kisielk/og-rek"
)
// PyData represents data stored into ZODB by Python applications.
// PyData represents raw data stored into ZODB by Python applications.
//
// The format is based on python pickles. Basically every serialized object has
// two parts: class description and object state. See
// two parts: pickle with class description and pickle with object state. See
//
// https://github.com/zopefoundation/ZODB/blob/a89485c1/src/ZODB/serialize.py
//
......
......@@ -83,7 +83,7 @@ func (xid Xid) XFmtString(b xfmt.Buffer) xfmt.Buffer {
*/
// parseHex64 decodes 16-character-wide hex-encoded string into uint64
// parseHex64 decodes 16-character-wide hex-encoded string into uint64.
func parseHex64(subj, s string) (uint64, error) {
// XXX -> xfmt ?
// XXX like scanf("%016x") but scanf implicitly skips spaces without giving control to caller and is slower
......
......@@ -41,7 +41,7 @@ func (t TimeStamp) XFmtString(b []byte) []byte {
}
// Time converts tid to time
// Time converts tid to time.
func (tid Tid) Time() TimeStamp {
// the same as _parseRaw in TimeStamp/py
// https://github.com/zopefoundation/persistent/blob/aba23595/persistent/timestamp.py#L75
......
// Copyright (C) 2016-2017 Nexedi SA and Contributors.
// Copyright (C) 2016-2018 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
......@@ -23,6 +23,42 @@
// Data model this package provides is partly based on ZODB/py
// (https://github.com/zopefoundation/ZODB) to maintain compatibility in
// between Python and Go implementations.
//
// Data model
//
// A ZODB database is conceptually modeled as transactional log of changes to objects.
// Oid identifies an object and Tid - a transaction. A transaction can change
// several objects and also has metadata, like user and description, associated
// with it. If an object is changed by transaction, it is said that there is
// revision of the object with particular object state committed by that transaction.
// Object revision is the same as tid of transaction that modified the object.
// The combination of object identifier and particular revision (serial)
// uniquely addresses corresponding data record.
//
// Tids of consecutive database transactions are monotonically increasing and
// are connected with time when transaction in question was committed.
// This way, besides identifying a transaction with changes, Tid can also be
// used to specify whole database state constructed by all cumulated
// transaction changes from database beginning up to, and including,
// transaction specified by it. Xid is "extended" oid that specifies particular
// object state: it is (oid, at) pair that is mapped to object's latest
// revision with serial ≤ at.
//
// Object state data is generally opaque, but is traditionally based on Python
// pickles in ZODB/py world.
//
//
// Operations
//
// A ZODB database can be opened with OpenStorage. Once opened IStorage
// interface is returned that represents access to the database. Please see
// documentation of IStorage, and other interfaces it embeds, for details.
//
//
// --------
//
// See also package lab.nexedi.com/kirr/neo/go/zodb/zodbtools and associated
// zodb command that provide tools for managing ZODB databases.
package zodb
import (
......@@ -64,7 +100,7 @@ type Oid uint64
//
// At specifies whole database state at which object identified with Oid should
// be looked up. The object revision is taken from latest transaction modifying
// the object with tid <= At.
// the object with tid At.
//
// Note that Xids are not unique - the same object revision can be addressed
// with several xids.
......@@ -106,7 +142,7 @@ type DataInfo struct {
DataTidHint Tid
}
// TxnStatus represents status of a transaction
// TxnStatus represents status of a transaction.
type TxnStatus byte
const (
......@@ -118,7 +154,7 @@ const (
// ---- interfaces ----
// NoObjectError is the error which tells that there is no such object in the database at all
// NoObjectError is the error which tells that there is no such object in the database at all.
type NoObjectError struct {
Oid Oid
}
......@@ -282,7 +318,7 @@ type IDataIterator interface {
// ---- misc ----
// Valid returns whether tid is in valid transaction identifiers range
// Valid returns whether tid is in valid transaction identifiers range.
func (tid Tid) Valid() bool {
// NOTE 0 is invalid tid
if 0 < tid && tid <= TidMax {
......@@ -292,7 +328,7 @@ func (tid Tid) Valid() bool {
}
}
// Valid returns true if transaction status value is well-known and valid
// Valid returns true if transaction status value is well-known and valid.
func (ts TxnStatus) Valid() bool {
switch ts {
case TxnComplete, TxnPacked, TxnInprogress:
......
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