Commit 39fbb668 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 19c56736
......@@ -74,7 +74,7 @@ type ErrDataRecord struct {
}
func (e *ErrDataRecord) Error() string {
return fmr.Sprintf("data record @%v: %v: %v", e.Pos, e.Subj, e.Err)
return fmt.Sprintf("data record @%v: %v: %v", e.Pos, e.Subj, e.Err)
}
// XXX -> zodb?
......@@ -128,58 +128,67 @@ func NewFileStorage(path string) (*FileStorage, error) {
// TODO read/recreate index
}
// ErrOidLoad is returned when there is an error while loading oid
type ErrOidLoad struct {
Oid zodb.Oid
// ErrXidLoad is returned when there is an error while loading xid
type ErrXidLoad struct {
Xid zodb.Xid
Err error
}
func (e *ErrOidLoad) Error() string {
// TODO include whole (=|<)tid:oid ?
return fmt.Sprintf("loading oid %v: %v", e.Oid, e.Err)
func (e *ErrXidLoad) Error() string {
return fmt.Sprintf("loading %v: %v", e.Xid, e.Err)
}
func (fs *FileStorage) Load(xid zodb.Xid) (data []byte, tid zodb.Tid, err error) {
// 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(xid.Oid)
if !ok {
// XXX drop oid from ErrOidMissing ?
return nil, zodb.Tid(0), &ErrOidLoad{oid, zodb.ErrOidMissing{Oid: oid}}
return nil, zodb.Tid(0), &ErrXidLoad{xid, zodb.ErrOidMissing{Oid: xid.Oid}}
}
dh := DataHeader{Tid: zodb.TidMax}
tidBefore := xid.XTid.Tid
if !xid.XTid.TidBefore {
tidBefore++ // XXX recheck this is ok wrt overflow
}
// search backwards for when we first have data record with tid < beforeTid
// search backwards for when we first have data record with tid satisfying xid.XTid
for {
prevTid := dh.Tid
err = dh.Decode(fs.f, dataPos)
if err != nil {
return nil, zodb.Tid(0), &ErrOidLoad{oid, err}
return nil, zodb.Tid(0), &ErrXidLoad{xid, err}
}
// check data record consistency
if dh.Oid != oid {
// ... header invalid:
return nil, zodb.Tid(0), &ErrOidLoad{oid, &ErrDataRecord{dataPos, "consistency check", "TODO unexpected oid")}
}
// TODO reenable
// if dh.Oid != oid {
// // ... header invalid:
// return nil, zodb.Tid(0), &ErrXidLoad{xid, &ErrDataRecord{dataPos, "consistency check", "TODO unexpected oid")}
// }
if dh.Tid >= prevTid { ... }
if dh.TxnPos >= dataPos - TxnHeaderSize { ... }
if dh.PrevDataRecPos >= dh.TxnPos - DataHeaderSize - 8 /* XXX */ { ... }
// if dh.Tid >= prevTid { ... }
// if dh.TxnPos >= dataPos - TxnHeaderSize { ... }
// if dh.PrevDataRecPos >= dh.TxnPos - DataHeaderSize - 8 /* XXX */ { ... }
if dh.Tid < beforeTid {
if dh.Tid < tidBefore {
break
}
// continue search
dataPos = dh.PrevDataRecPos
dataPos == 0 {
if dataPos == 0 {
// no such oid revision
return nil, zodb.Tid(0), &ErrOidLoad{oid, zodb.ErrOidRevMissing{oid, "<", beforeTid}}
return nil, zodb.Tid(0), &ErrXidLoad{xid, &zodb.ErrXidMissing{Xid: xid}}
}
}
// found dh.Tid < beforeTid
// found dh.Tid < tidBefore; check it really satisfies xid.XTid
if !xid.XTid.TidBefore && dh.Tid != xid.XTid.Tid {
// XXX unify with ^^^
return nil, zodb.Tid(0), &ErrXidLoad{xid, &zodb.ErrXidMissing{Xid: xid}}
}
// now read actual data / scan via backpointers
if dh.DataLen == 0 {
// backpointer - TODO
......@@ -191,7 +200,7 @@ func (fs *FileStorage) Load(xid zodb.Xid) (data []byte, tid zodb.Tid, err error)
err = nil // we don't mind to get EOF after full data read XXX ok?
}
if err != nil {
return nil, zodb.Tid(0), &ErrOidLoad{oid, err}
return nil, zodb.Tid(0), &ErrXidLoad{xid, err}
}
return data, dh.Tid, nil
......
......@@ -47,8 +47,8 @@ func (oid Oid) String() string {
}
// XXX move me out of here
// XXX naming -> bint ?
func bool2int(b bool) int {
// bint converts bool to int with true => 1; false => 0
func bint(b bool) int {
if b {
return 1
} else {
......@@ -58,16 +58,7 @@ func bool2int(b bool) int {
func (xtid XTid) String() string {
// XXX also print "tid:" prefix ?
/*
s := ""
if xtid.TidBefore {
s = "<"
} else {
s = "="
}
*/
return fmt.Sprintf("%c%v", "=<"[bool2int(xtid.TidBefore)], xtid)
return fmt.Sprintf("%c%v", "=<"[bint(xtid.TidBefore)], xtid)
}
func (xid Xid) String() string {
......@@ -79,19 +70,20 @@ func (xid Xid) String() string {
// ErrOidMissing is an error which tells that there is no such oid in the database at all
type ErrOidMissing struct {
Oid Oid
Serial Tid
Before bool // XXX
}
func (e ErrOidMissing) Error() string {
return "%v: no such oid"
return fmt.Sprintf("%v: no such oid", e.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
// ErrXidMissing is an error which tells that oid exists in the database,
// but there is no its revision satisfying xid.XTid search criteria.
type ErrXidMissing struct {
Xid Xid
}
func (e *ErrXidMissing) Error() string {
return fmt.Sprintf("") // TODO
}
// ----------------------------------------
......
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