You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
2.4 KiB

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