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

.

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