func (x singleWriter) Write(p []byte) (int, error) { w := x.w if w.seq != x.seq { return 0, errors.New("leveldb/journal: stale writer") } if w.err != nil { return 0, w.err } n0 := len(p) for len(p) > 0 { // Write a block, if it is full. if w.j == blockSize { w.fillHeader(false) w.writeBlock() if w.err != nil { return 0, w.err } w.first = false } // Copy bytes into the buffer. n := copy(w.buf[w.j:], p) w.j += n p = p[n:] } return n0, nil }
func (x *singleReader) ReadByte() (byte, error) { r := x.r if r.seq != x.seq { return 0, errors.New("leveldb/journal: stale reader") } if x.err != nil { return 0, x.err } if r.err != nil { return 0, r.err } for r.i == r.j { if r.last { return 0, io.EOF } x.err = r.nextChunk(false) if x.err != nil { if x.err == errSkip { x.err = io.ErrUnexpectedEOF } return 0, x.err } } c := r.buf[r.i] r.i++ return c, nil }
func (x *singleReader) Read(p []byte) (int, error) { r := x.r if r.seq != x.seq { return 0, errors.New("leveldb/journal: stale reader") } if x.err != nil { return 0, x.err } if r.err != nil { return 0, r.err } for r.i == r.j { if r.last { return 0, io.EOF } x.err = r.nextChunk(false) if x.err != nil { if x.err == errSkip { x.err = io.ErrUnexpectedEOF } return 0, x.err } } n := copy(p, r.buf[r.i:r.j]) r.i += n return n, nil }
// Close finishes the current journal and closes the writer. func (w *Writer) Close() error { w.seq++ w.writePending() if w.err != nil { return w.err } w.err = errors.New("leveldb/journal: closed Writer") return nil }
// GetProperty returns value of the given property name. // // Property names: // leveldb.num-files-at-level{n} // Returns the number of files at level 'n'. // leveldb.stats // Returns statistics of the underlying DB. // leveldb.sstables // Returns sstables list for each level. // leveldb.blockpool // Returns block pool stats. // leveldb.cachedblock // Returns size of cached block. // leveldb.openedtables // Returns number of opened tables. // leveldb.alivesnaps // Returns number of alive snapshots. // leveldb.aliveiters // Returns number of alive iterators. func (db *DB) GetProperty(name string) (value string, err error) { err = db.ok() if err != nil { return } const prefix = "leveldb." if !strings.HasPrefix(name, prefix) { return "", errors.New("leveldb: GetProperty: unknown property: " + name) } p := name[len(prefix):] v := db.s.version() defer v.release() numFilesPrefix := "num-files-at-level" switch { case strings.HasPrefix(p, numFilesPrefix): var level uint var rest string n, _ := fmt.Sscanf(p[len(numFilesPrefix):], "%d%s", &level, &rest) if n != 1 || int(level) >= db.s.o.GetNumLevel() { err = errors.New("leveldb: GetProperty: invalid property: " + name) } else { value = fmt.Sprint(v.tLen(int(level))) } case p == "stats": value = "Compactions\n" + " Level | Tables | Size(MB) | Time(sec) | Read(MB) | Write(MB)\n" + "-------+------------+---------------+---------------+---------------+---------------\n" for level, tables := range v.tables { duration, read, write := db.compStats[level].get() if len(tables) == 0 && duration == 0 { continue } value += fmt.Sprintf(" %3d | %10d | %13.5f | %13.5f | %13.5f | %13.5f\n", level, len(tables), float64(tables.size())/1048576.0, duration.Seconds(), float64(read)/1048576.0, float64(write)/1048576.0) } case p == "sstables": for level, tables := range v.tables { value += fmt.Sprintf("--- level %d ---\n", level) for _, t := range tables { value += fmt.Sprintf("%d:%d[%q .. %q]\n", t.file.Num(), t.size, t.imin, t.imax) } } case p == "blockpool": value = fmt.Sprintf("%v", db.s.tops.bpool) case p == "cachedblock": if db.s.tops.bcache != nil { value = fmt.Sprintf("%d", db.s.tops.bcache.Size()) } else { value = "<nil>" } case p == "openedtables": value = fmt.Sprintf("%d", db.s.tops.cache.Size()) case p == "alivesnaps": value = fmt.Sprintf("%d", atomic.LoadInt32(&db.aliveSnaps)) case p == "aliveiters": value = fmt.Sprintf("%d", atomic.LoadInt32(&db.aliveIters)) default: err = errors.New("leveldb: GetProperty: unknown property: " + name) } return }
// Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package leveldb import ( "sync" "time" "github.com/rwcarlsen/cloudlus/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/errors" "github.com/rwcarlsen/cloudlus/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/memdb" "github.com/rwcarlsen/cloudlus/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/opt" ) var ( errCompactionTransactExiting = errors.New("leveldb: compaction transact exiting") ) type cStats struct { sync.Mutex duration time.Duration read uint64 write uint64 } func (p *cStats) add(n *cStatsStaging) { p.Lock() p.duration += n.duration p.read += n.read p.write += n.write p.Unlock()
} // NewReader returns a new reader. The dropper may be nil, and if // strict is true then corrupted or invalid chunk will halt the journal // reader entirely. func NewReader(r io.Reader, dropper Dropper, strict, checksum bool) *Reader { return &Reader{ r: r, dropper: dropper, strict: strict, checksum: checksum, last: true, } } var errSkip = errors.New("leveldb/journal: skipped") func (r *Reader) corrupt(n int, reason string, skip bool) error { if r.dropper != nil { r.dropper.Drop(&ErrCorrupted{n, reason}) } if r.strict && !skip { r.err = errors.NewErrCorrupted(nil, &ErrCorrupted{n, reason}) return r.err } return errSkip } // nextChunk sets r.buf[r.i:r.j] to hold the next chunk's payload, reading the // next block into the buffer if necessary. func (r *Reader) nextChunk(first bool) error {