storage.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // Copyright (c) 2012, Suryandaru Triandana <[email protected]>
  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 storage provides storage abstraction for LevelDB.
  7. package storage
  8. import (
  9. "errors"
  10. "fmt"
  11. "io"
  12. )
  13. // FileType represent a file type.
  14. type FileType int
  15. // File types.
  16. const (
  17. TypeManifest FileType = 1 << iota
  18. TypeJournal
  19. TypeTable
  20. TypeTemp
  21. TypeAll = TypeManifest | TypeJournal | TypeTable | TypeTemp
  22. )
  23. func (t FileType) String() string {
  24. switch t {
  25. case TypeManifest:
  26. return "manifest"
  27. case TypeJournal:
  28. return "journal"
  29. case TypeTable:
  30. return "table"
  31. case TypeTemp:
  32. return "temp"
  33. }
  34. return fmt.Sprintf("<unknown:%d>", t)
  35. }
  36. // Common error.
  37. var (
  38. ErrInvalidFile = errors.New("leveldb/storage: invalid file for argument")
  39. ErrLocked = errors.New("leveldb/storage: already locked")
  40. ErrClosed = errors.New("leveldb/storage: closed")
  41. )
  42. // ErrCorrupted is the type that wraps errors that indicate corruption of
  43. // a file. Package storage has its own type instead of using
  44. // errors.ErrCorrupted to prevent circular import.
  45. type ErrCorrupted struct {
  46. Fd FileDesc
  47. Err error
  48. }
  49. func (e *ErrCorrupted) Error() string {
  50. if !e.Fd.Zero() {
  51. return fmt.Sprintf("%v [file=%v]", e.Err, e.Fd)
  52. }
  53. return e.Err.Error()
  54. }
  55. // Syncer is the interface that wraps basic Sync method.
  56. type Syncer interface {
  57. // Sync commits the current contents of the file to stable storage.
  58. Sync() error
  59. }
  60. // Reader is the interface that groups the basic Read, Seek, ReadAt and Close
  61. // methods.
  62. type Reader interface {
  63. io.ReadSeeker
  64. io.ReaderAt
  65. io.Closer
  66. }
  67. // Writer is the interface that groups the basic Write, Sync and Close
  68. // methods.
  69. type Writer interface {
  70. io.WriteCloser
  71. Syncer
  72. }
  73. // Locker is the interface that wraps Unlock method.
  74. type Locker interface {
  75. Unlock()
  76. }
  77. // FileDesc is a 'file descriptor'.
  78. type FileDesc struct {
  79. Type FileType
  80. Num int64
  81. }
  82. func (fd FileDesc) String() string {
  83. switch fd.Type {
  84. case TypeManifest:
  85. return fmt.Sprintf("MANIFEST-%06d", fd.Num)
  86. case TypeJournal:
  87. return fmt.Sprintf("%06d.log", fd.Num)
  88. case TypeTable:
  89. return fmt.Sprintf("%06d.ldb", fd.Num)
  90. case TypeTemp:
  91. return fmt.Sprintf("%06d.tmp", fd.Num)
  92. default:
  93. return fmt.Sprintf("%#x-%d", fd.Type, fd.Num)
  94. }
  95. }
  96. // Zero returns true if fd == (FileDesc{}).
  97. func (fd FileDesc) Zero() bool {
  98. return fd == (FileDesc{})
  99. }
  100. // FileDescOk returns true if fd is a valid 'file descriptor'.
  101. func FileDescOk(fd FileDesc) bool {
  102. switch fd.Type {
  103. case TypeManifest:
  104. case TypeJournal:
  105. case TypeTable:
  106. case TypeTemp:
  107. default:
  108. return false
  109. }
  110. return fd.Num >= 0
  111. }
  112. // Storage is the storage. A storage instance must be safe for concurrent use.
  113. type Storage interface {
  114. // Lock locks the storage. Any subsequent attempt to call Lock will fail
  115. // until the last lock released.
  116. // Caller should call Unlock method after use.
  117. Lock() (Locker, error)
  118. // Log logs a string. This is used for logging.
  119. // An implementation may write to a file, stdout or simply do nothing.
  120. Log(str string)
  121. // SetMeta store 'file descriptor' that can later be acquired using GetMeta
  122. // method. The 'file descriptor' should point to a valid file.
  123. // SetMeta should be implemented in such way that changes should happen
  124. // atomically.
  125. SetMeta(fd FileDesc) error
  126. // GetMeta returns 'file descriptor' stored in meta. The 'file descriptor'
  127. // can be updated using SetMeta method.
  128. // Returns os.ErrNotExist if meta doesn't store any 'file descriptor', or
  129. // 'file descriptor' point to nonexistent file.
  130. GetMeta() (FileDesc, error)
  131. // List returns file descriptors that match the given file types.
  132. // The file types may be OR'ed together.
  133. List(ft FileType) ([]FileDesc, error)
  134. // Open opens file with the given 'file descriptor' read-only.
  135. // Returns os.ErrNotExist error if the file does not exist.
  136. // Returns ErrClosed if the underlying storage is closed.
  137. Open(fd FileDesc) (Reader, error)
  138. // Create creates file with the given 'file descriptor', truncate if already
  139. // exist and opens write-only.
  140. // Returns ErrClosed if the underlying storage is closed.
  141. Create(fd FileDesc) (Writer, error)
  142. // Remove removes file with the given 'file descriptor'.
  143. // Returns ErrClosed if the underlying storage is closed.
  144. Remove(fd FileDesc) error
  145. // Rename renames file from oldfd to newfd.
  146. // Returns ErrClosed if the underlying storage is closed.
  147. Rename(oldfd, newfd FileDesc) error
  148. // Close closes the storage.
  149. // It is valid to call Close multiple times. Other methods should not be
  150. // called after the storage has been closed.
  151. Close() error
  152. }