Commit 2ef35dde authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 230cf05d
......@@ -524,17 +524,13 @@ func (fs *FileStorage) saveIndex() (err error) {
// XXX lock?
defer xerr.Contextf(&err, "%s: index save", fs.file.Name())
idxname := fs.file.Name() + ".index"
idxtmp := idxname + ".index_tmp"
err = fs.index.SaveFile(idxtmp)
err = fs.index.SaveFile(fs.file.Name() + ".index")
if err != nil {
return err
}
// XXX fsync here?
err = os.Rename(idxtmp, idxname)
return err
return nil
}
// IndexCorruptError is the error returned when index verification fails
......
......@@ -32,54 +32,38 @@ import (
// Reindex rebuilds index for FileStorage file @ path
func Reindex(path string) error {
// XXX open read-only
fs, err := fs1.Open(context.Background(), path) // XXX , fs1.OpenWithoutIndex)
// XXX lock path.lock ?
index, err := fs1.BuildIndexForFile(context.Background(), path)
if err != nil {
return nil // XXX err ctx
return err
}
defer fs.Close() // XXX err
err = fs.Reindex(nil)
return err // XXX ok?
}
// VerifyIndexFor verifies that on-disk index for FileStorage file @ path is correct
func VerifyIndexFor(path string) error {
// XXX open read-only
fs, err := fs1.Open(context.Background(), path) // XXX , 0)
err = index.SaveFile(path + ".index")
if err != nil {
return nil // XXX err ctx
return err // XXX err ctx
}
defer fs.Close() // XXX err
err = fs.VerifyIndex(nil)
return err
//fs.Index()
//fs.ComputeIndex
return nil
}
// ----------------------------------------
const reindexSummary = "XXX" // XXX
const reindexSummary = "rebuild database index"
func reindexUsage(w io.Writer) {
fmt.Fprintf(w,
`Usage: fs1 reindex [options] <storage>
Dump transactions from a FileStorage in reverse order XXX
Rebuild FileStorage index
<storage> is a path to FileStorage
options:
-h --help this help text.
-verify verify that existing index is correct; don't overwrite it
`, ntxnDefault)
`)
}
func reindexMain(argv []string) {
flags := flag.FlagSet{Usage: func() { reindexUsage(os.Stderr) }}
flags.Init("", flag.ExitOnError)
// XXX -verify
flags.Parse(argv[1:])
argv = flags.Args()
......@@ -95,5 +79,35 @@ func reindexMain(argv []string) {
}
}
// ----------------------------------------
// TODO verify-index
// TODO verify-index -quick (only small sanity check)
// VerifyIndexFor verifies that on-disk index for FileStorage file @ path is correct
func VerifyIndexFor(path string) error {
panic("TODO")
/*
// XXX open read-only
fs, err := fs1.Open(context.Background(), path) // XXX , 0)
if err != nil {
return nil // XXX err ctx
}
defer fs.Close() // XXX err
err = fs.VerifyIndex(nil)
return err
//fs.Index()
//fs.ComputeIndex
*/
}
const verifyIdxSummary = "verify database index"
func verifyIdxUsage(w io.Writer) {
panic("TODO") // XXX
}
func verifyIdxMaxin(argv []string) {
panic("TODO") // XXX
}
......@@ -26,8 +26,10 @@ import (
"encoding/binary"
"fmt"
"io"
"io/ioutil"
"math/big"
"os"
"path/filepath"
"strconv"
"lab.nexedi.com/kirr/neo/go/zodb"
......@@ -169,22 +171,35 @@ out:
}
// SaveFile saves index to a file @ path
func (fsi *Index) SaveFile(path string) (err error) {
f, err := os.Create(path)
//
// Index data is first saved to a temporary file and when complete the
// temporary is renamed to be at requested path. This way file @ path will be
// updated only with complete index data.
func (fsi *Index) SaveFile(path string) error {
dir, name := filepath.Dir(path), filepath.Base(path)
f, err := ioutil.TempFile(dir, name + ".tmp")
if err != nil {
return &IndexSaveError{err}
return &IndexSaveError{err} // XXX needed?
}
// TODO use buffering for f (ogórek does not buffer itself on encoding)
defer func() {
err1 := fsi.Save(f)
err2 := f.Close()
if err2 != nil && err == nil {
err = &IndexSaveError{err2}
if err1 != nil || err2 != nil {
os.Remove(f.Name())
err = err1
if err == nil {
err = &IndexSaveError{err2} // XXX needed?
}
return err
}
err = os.Rename(f.Name(), path)
if err != nil {
return &IndexSaveError{err} // XXX needed?
}
}()
return fsi.Save(f)
return nil
}
// IndexLoadError is the error type returned by index load routines
......@@ -507,7 +522,7 @@ func BuildIndex(ctx context.Context, r io.ReaderAt) (*Index, error) {
func BuildIndexForFile(ctx context.Context, path string) (index *Index, err error) {
f, err := os.Open(path)
if err != nil {
return IndexNew(), err
return IndexNew(), err // XXX add err ctx?
}
defer func() {
......
......@@ -121,6 +121,8 @@ Usage:
The commands are:
`, prog.Summary, prog.Name)
// XXX 11 -> max width of cmd.Name
for _, cmd := range prog.Commands {
fmt.Fprintf(w, "\t%-11s %s\n", cmd.Name, cmd.Summary)
}
......@@ -138,6 +140,7 @@ Additional help topics:
`)
// XXX 11 -> max width of topic.Name
for _, topic := range prog.HelpTopics {
fmt.Fprintf(w, "\t%-11s %s\n", topic.Name, topic.Summary)
}
......
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