Commit a18daaa3 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 0af1ccce
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
// //
// See COPYING file for full licensing terms. // See COPYING file for full licensing terms.
// //
// XXX based on code from ZODB ? // XXX partly based on code from ZODB ?
// FileStorage v1. XXX text // FileStorage v1. XXX text
package fs1 package fs1
...@@ -33,6 +33,8 @@ type FileStorage struct { ...@@ -33,6 +33,8 @@ type FileStorage struct {
// IStorage // IStorage
var _ zodb.IStorage = (*FileStorage)(nil) var _ zodb.IStorage = (*FileStorage)(nil)
// XXX -> TxnHeader
type TxnRecHead struct { type TxnRecHead struct {
Tid zodb.Tid Tid zodb.Tid
RecLenm8 uint64 RecLenm8 uint64
...@@ -64,17 +66,15 @@ type DataHeader struct { ...@@ -64,17 +66,15 @@ type DataHeader struct {
const DataHeaderSize = 42 const DataHeaderSize = 42
// ErrDataRead is returned on data record read / decode errors // ErrData is returned on data record read / decode errors
type ErrDataRecord struct { type ErrDataRecord struct {
Pos int64 Pos int64 // position of data record
Err error Subj string // about what .Err is
Err error // actual error
} }
func (e *ErrDataRead) Error() string { func (e *ErrDataRecord) Error() string {
//return fmt.Sprintf("data read: record @%v: %v", e.Pos, e.Err) return fmr.Sprintf("data record @%v: %v: %v", e.Pos, e.Subj, e.Err)
// TODO read -> header | payload
return fmr.Sprintf("data record @%v: read: %v", e.Pos, e.Err)
// XXX -> data record @%v: %v ?
} }
// XXX -> zodb? // XXX -> zodb?
...@@ -82,15 +82,16 @@ var ErrVersionNonZero = errors.New("non-zero version") ...@@ -82,15 +82,16 @@ var ErrVersionNonZero = errors.New("non-zero version")
// decode reads and decodes data record header from a readerAt
// XXX io.ReaderAt -> *os.File (if iface conv costly) // XXX io.ReaderAt -> *os.File (if iface conv costly)
func (dh *DataHeader) decode(r io.ReaderAt, pos int64, tmpBuf *[DataHeaderSize]byte) error { func (dh *DataHeader) decode(r io.ReaderAt, pos int64, tmpBuf *[DataHeaderSize]byte) error {
n, err := r.ReadAt(tmpBuf[:], pos) n, err := r.ReadAt(tmpBuf[:], pos)
if n == DataHeaderSize { if n == DataHeaderSize {
err = nil // we don't mind if it was EOF after full header read XXX ok? err = nil // we don't mind if it was EOF after full header read
} }
if err != nil { if err != nil {
return &ErrDataRead{pos, err} return &ErrDataRecord{pos, "read", err}
} }
dh.Oid.Decode(tmpBuf[0:]) dh.Oid.Decode(tmpBuf[0:])
...@@ -101,8 +102,7 @@ func (dh *DataHeader) decode(r io.ReaderAt, pos int64, tmpBuf *[DataHeaderSize]b ...@@ -101,8 +102,7 @@ func (dh *DataHeader) decode(r io.ReaderAt, pos int64, tmpBuf *[DataHeaderSize]b
dh.DataLen = binary.BigEndian.Uint64(tmpBuf[34:]) dh.DataLen = binary.BigEndian.Uint64(tmpBuf[34:])
if verlen != 0 { if verlen != 0 {
// XXX -> ...: header invalid: non-zero version return &ErrDataRecord{pos, "invalid header", ErrVersionNonZero}
return &ErrDataRead{pos, ErrVersionNonZero}
} }
return nil return nil
...@@ -143,8 +143,8 @@ func (fs *FileStorage) LoadBefore(oid zodb.Oid, beforeTid zodb.Tid) (data []byte ...@@ -143,8 +143,8 @@ func (fs *FileStorage) LoadBefore(oid zodb.Oid, beforeTid zodb.Tid) (data []byte
// lookup in index position of oid data record within latest transaction who changed this oid // lookup in index position of oid data record within latest transaction who changed this oid
dataPos, ok := fs.index.Get(oid) dataPos, ok := fs.index.Get(oid)
if !ok { if !ok {
return nil, zodb.Tid(0), zodb.ErrOidMissing{Oid: oid} // XXX drop oid from ErrOidMissing ?
// XXX -> &ErrOidLoad{oid, zodb.ErrOidMissing} ? return nil, zodb.Tid(0), &ErrOidLoad{oid, zodb.ErrOidMissing{Oid: oid}}
} }
dh := DataHeader{Tid: zodb.TidMax} dh := DataHeader{Tid: zodb.TidMax}
...@@ -160,7 +160,7 @@ func (fs *FileStorage) LoadBefore(oid zodb.Oid, beforeTid zodb.Tid) (data []byte ...@@ -160,7 +160,7 @@ func (fs *FileStorage) LoadBefore(oid zodb.Oid, beforeTid zodb.Tid) (data []byte
// check data record consistency // check data record consistency
if dh.Oid != oid { if dh.Oid != oid {
// ... header invalid: // ... header invalid:
return nil, zodb.Tid(0), &ErrOidLoad{oid, &ErrDataRead{dataPos, "TODO unexpected oid")} return nil, zodb.Tid(0), &ErrOidLoad{oid, &ErrDataRecord{dataPos, "consistency check", "TODO unexpected oid")}
} }
if dh.Tid >= prevTid { ... } if dh.Tid >= prevTid { ... }
...@@ -175,7 +175,7 @@ func (fs *FileStorage) LoadBefore(oid zodb.Oid, beforeTid zodb.Tid) (data []byte ...@@ -175,7 +175,7 @@ func (fs *FileStorage) LoadBefore(oid zodb.Oid, beforeTid zodb.Tid) (data []byte
dataPos = dh.PrevDataRecPos dataPos = dh.PrevDataRecPos
dataPos == 0 { dataPos == 0 {
// no such oid revision // no such oid revision
return ...&ErrOidLoad{oid, zodb.ErrOidRevMissing} return nil, zodb.Tid(0), &ErrOidLoad{oid, zodb.ErrOidRevMissing{oid, "<", beforeTid}}
} }
} }
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
// //
// See COPYING file for full licensing terms. // See COPYING file for full licensing terms.
// //
// XXX based on code from ZODB ? // XXX partly based on code from ZODB ?
// FileStorage v1. Index // FileStorage v1. Index
package fs1 package fs1
......
...@@ -14,13 +14,18 @@ import ( ...@@ -14,13 +14,18 @@ import (
type Tid uint64 // transaction identifier type Tid uint64 // transaction identifier
type Oid uint64 // object identifier type Oid uint64 // object identifier
/* // XTid is "extended" transaction identifier. It defines a transaction for
// XXX "extended" oid - oid + serial, completely specifying object revision // oid lookup - either exactly by serial, or <beforeTid XXX
type Xid struct { type XTid struct {
Tid Tid
TidBefore bool // XXX merge into Tid itself (high bit) ?
}
// Xid is "extended" oid - oid + serial/beforeTid, completely specifying object revision XXX text
type Xid struct {
XTid
Oid Oid
} }
*/
const ( const (
Tid0 Tid = 0 // XXX or simply Tid(0) ? Tid0 Tid = 0 // XXX or simply Tid(0) ?
...@@ -41,16 +46,42 @@ func (oid Oid) String() string { ...@@ -41,16 +46,42 @@ func (oid Oid) String() string {
return fmt.Sprintf("%016x", uint64(oid)) return fmt.Sprintf("%016x", uint64(oid))
} }
func (xtid XTid) String() string {
// XXX also print "tid:" prefix ?
s := ""
if xtid.TidBefore {
s = "<"
} else {
s = "="
}
return s + xtid.Tid.String()
}
func (xid Xid) String() string {
return xid.XTid.String() + ":" + xid.Oid.String()
}
// ---------------------------------------- // ----------------------------------------
// ErrOidMissing is an error which tells that there is no such oid in the database at all
type ErrOidMissing struct { type ErrOidMissing struct {
Oid Oid Oid Oid
Serial Tid
Before bool // XXX
} }
func (e ErrOidMissing) Error() string { func (e ErrOidMissing) Error() string {
return "%v: no such oid" return "%v: no such oid"
} }
// ErrOidRevMissing is an error which tells that oid exists in the database,
// but there is no its revision satisfying serial/beforeTid criteria XXX
type ErrOidRevMissing struct {
Oid Oid
}
// ---------------------------------------- // ----------------------------------------
// TxnStatus represents status of a transaction // TxnStatus represents status of a transaction
...@@ -103,8 +134,12 @@ type IStorage interface { ...@@ -103,8 +134,12 @@ type IStorage interface {
LastTid() Tid // XXX -> Tid, ok ? LastTid() Tid // XXX -> Tid, ok ?
// TODO data []byte -> something allocated from slab ? // TODO data []byte -> something allocated from slab ?
Load(xoid XOid) (data []byte, tid Tid, err error)
/* generalized ^^^
LoadBefore(oid Oid, beforeTid Tid) (data []byte, tid Tid, err error) LoadBefore(oid Oid, beforeTid Tid) (data []byte, tid Tid, err error)
LoadSerial(oid Oid, serial Tid) (data []byte, err error) LoadSerial(oid Oid, serial Tid) (data []byte, err error)
*/
// PrefetchBefore(oidv []Oid, beforeTid Tid) error (?) // PrefetchBefore(oidv []Oid, beforeTid Tid) error (?)
// Store(oid Oid, serial Tid, data []byte, txn ITransaction) error // Store(oid Oid, serial Tid, data []byte, txn ITransaction) error
......
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