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