OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / syndtr / goleveldb / leveldb / db_util.go
1 // Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
2 // All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
6
7 package leveldb
8
9 import (
10         "github.com/syndtr/goleveldb/leveldb/errors"
11         "github.com/syndtr/goleveldb/leveldb/iterator"
12         "github.com/syndtr/goleveldb/leveldb/opt"
13         "github.com/syndtr/goleveldb/leveldb/storage"
14         "github.com/syndtr/goleveldb/leveldb/util"
15 )
16
17 // Reader is the interface that wraps basic Get and NewIterator methods.
18 // This interface implemented by both DB and Snapshot.
19 type Reader interface {
20         Get(key []byte, ro *opt.ReadOptions) (value []byte, err error)
21         NewIterator(slice *util.Range, ro *opt.ReadOptions) iterator.Iterator
22 }
23
24 // Sizes is list of size.
25 type Sizes []int64
26
27 // Sum returns sum of the sizes.
28 func (sizes Sizes) Sum() int64 {
29         var sum int64
30         for _, size := range sizes {
31                 sum += size
32         }
33         return sum
34 }
35
36 // Logging.
37 func (db *DB) log(v ...interface{})                 { db.s.log(v...) }
38 func (db *DB) logf(format string, v ...interface{}) { db.s.logf(format, v...) }
39
40 // Check and clean files.
41 func (db *DB) checkAndCleanFiles() error {
42         v := db.s.version()
43         defer v.release()
44
45         tmap := make(map[int64]bool)
46         for _, tables := range v.levels {
47                 for _, t := range tables {
48                         tmap[t.fd.Num] = false
49                 }
50         }
51
52         fds, err := db.s.stor.List(storage.TypeAll)
53         if err != nil {
54                 return err
55         }
56
57         var nt int
58         var rem []storage.FileDesc
59         for _, fd := range fds {
60                 keep := true
61                 switch fd.Type {
62                 case storage.TypeManifest:
63                         keep = fd.Num >= db.s.manifestFd.Num
64                 case storage.TypeJournal:
65                         if !db.frozenJournalFd.Zero() {
66                                 keep = fd.Num >= db.frozenJournalFd.Num
67                         } else {
68                                 keep = fd.Num >= db.journalFd.Num
69                         }
70                 case storage.TypeTable:
71                         _, keep = tmap[fd.Num]
72                         if keep {
73                                 tmap[fd.Num] = true
74                                 nt++
75                         }
76                 }
77
78                 if !keep {
79                         rem = append(rem, fd)
80                 }
81         }
82
83         if nt != len(tmap) {
84                 var mfds []storage.FileDesc
85                 for num, present := range tmap {
86                         if !present {
87                                 mfds = append(mfds, storage.FileDesc{storage.TypeTable, num})
88                                 db.logf("db@janitor table missing @%d", num)
89                         }
90                 }
91                 return errors.NewErrCorrupted(storage.FileDesc{}, &errors.ErrMissingFiles{Fds: mfds})
92         }
93
94         db.logf("db@janitor F·%d G·%d", len(fds), len(rem))
95         for _, fd := range rem {
96                 db.logf("db@janitor removing %s-%d", fd.Type, fd.Num)
97                 if err := db.s.stor.Remove(fd); err != nil {
98                         return err
99                 }
100         }
101         return nil
102 }