github.com/df-mc/goleveldb@v1.1.9/leveldb/storage/mem_storage.go (about) 1 // Copyright (c) 2013, 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 8 9 import ( 10 "bytes" 11 "os" 12 "sync" 13 ) 14 15 const typeShift = 4 16 17 // Verify at compile-time that typeShift is large enough to cover all FileType 18 // values by confirming that 0 == 0. 19 var _ [0]struct{} = [TypeAll >> typeShift]struct{}{} 20 21 type memStorageLock struct { 22 ms *memStorage 23 } 24 25 func (lock *memStorageLock) Unlock() { 26 ms := lock.ms 27 ms.mu.Lock() 28 defer ms.mu.Unlock() 29 if ms.slock == lock { 30 ms.slock = nil 31 } 32 return 33 } 34 35 // memStorage is a memory-backed storage. 36 type memStorage struct { 37 mu sync.Mutex 38 slock *memStorageLock 39 files map[uint64]*memFile 40 meta FileDesc 41 } 42 43 // NewMemStorage returns a new memory-backed storage implementation. 44 func NewMemStorage() Storage { 45 return &memStorage{ 46 files: make(map[uint64]*memFile), 47 } 48 } 49 50 func (ms *memStorage) Lock() (Locker, error) { 51 ms.mu.Lock() 52 defer ms.mu.Unlock() 53 if ms.slock != nil { 54 return nil, ErrLocked 55 } 56 ms.slock = &memStorageLock{ms: ms} 57 return ms.slock, nil 58 } 59 60 func (*memStorage) Log(str string) {} 61 62 func (ms *memStorage) SetMeta(fd FileDesc) error { 63 if !FileDescOk(fd) { 64 return ErrInvalidFile 65 } 66 67 ms.mu.Lock() 68 ms.meta = fd 69 ms.mu.Unlock() 70 return nil 71 } 72 73 func (ms *memStorage) GetMeta() (FileDesc, error) { 74 ms.mu.Lock() 75 defer ms.mu.Unlock() 76 if ms.meta.Zero() { 77 return FileDesc{}, os.ErrNotExist 78 } 79 return ms.meta, nil 80 } 81 82 func (ms *memStorage) List(ft FileType) ([]FileDesc, error) { 83 ms.mu.Lock() 84 var fds []FileDesc 85 for x := range ms.files { 86 fd := unpackFile(x) 87 if fd.Type&ft != 0 { 88 fds = append(fds, fd) 89 } 90 } 91 ms.mu.Unlock() 92 return fds, nil 93 } 94 95 func (ms *memStorage) Open(fd FileDesc) (Reader, error) { 96 if !FileDescOk(fd) { 97 return nil, ErrInvalidFile 98 } 99 100 ms.mu.Lock() 101 defer ms.mu.Unlock() 102 if m, exist := ms.files[packFile(fd)]; exist { 103 if m.open { 104 return nil, errFileOpen 105 } 106 m.open = true 107 return &memReader{Reader: bytes.NewReader(m.Bytes()), ms: ms, m: m}, nil 108 } 109 return nil, os.ErrNotExist 110 } 111 112 func (ms *memStorage) Create(fd FileDesc) (Writer, error) { 113 if !FileDescOk(fd) { 114 return nil, ErrInvalidFile 115 } 116 117 x := packFile(fd) 118 ms.mu.Lock() 119 defer ms.mu.Unlock() 120 m, exist := ms.files[x] 121 if exist { 122 if m.open { 123 return nil, errFileOpen 124 } 125 m.Reset() 126 } else { 127 m = &memFile{} 128 ms.files[x] = m 129 } 130 m.open = true 131 return &memWriter{memFile: m, ms: ms}, nil 132 } 133 134 func (ms *memStorage) Remove(fd FileDesc) error { 135 if !FileDescOk(fd) { 136 return ErrInvalidFile 137 } 138 139 x := packFile(fd) 140 ms.mu.Lock() 141 defer ms.mu.Unlock() 142 if _, exist := ms.files[x]; exist { 143 delete(ms.files, x) 144 return nil 145 } 146 return os.ErrNotExist 147 } 148 149 func (ms *memStorage) Rename(oldfd, newfd FileDesc) error { 150 if !FileDescOk(oldfd) || !FileDescOk(newfd) { 151 return ErrInvalidFile 152 } 153 if oldfd == newfd { 154 return nil 155 } 156 157 oldx := packFile(oldfd) 158 newx := packFile(newfd) 159 ms.mu.Lock() 160 defer ms.mu.Unlock() 161 oldm, exist := ms.files[oldx] 162 if !exist { 163 return os.ErrNotExist 164 } 165 newm, exist := ms.files[newx] 166 if (exist && newm.open) || oldm.open { 167 return errFileOpen 168 } 169 delete(ms.files, oldx) 170 ms.files[newx] = oldm 171 return nil 172 } 173 174 func (*memStorage) Close() error { return nil } 175 176 type memFile struct { 177 bytes.Buffer 178 open bool 179 } 180 181 type memReader struct { 182 *bytes.Reader 183 ms *memStorage 184 m *memFile 185 closed bool 186 } 187 188 func (mr *memReader) Close() error { 189 mr.ms.mu.Lock() 190 defer mr.ms.mu.Unlock() 191 if mr.closed { 192 return ErrClosed 193 } 194 mr.m.open = false 195 return nil 196 } 197 198 type memWriter struct { 199 *memFile 200 ms *memStorage 201 closed bool 202 } 203 204 func (*memWriter) Sync() error { return nil } 205 206 func (mw *memWriter) Close() error { 207 mw.ms.mu.Lock() 208 defer mw.ms.mu.Unlock() 209 if mw.closed { 210 return ErrClosed 211 } 212 mw.memFile.open = false 213 return nil 214 } 215 216 func packFile(fd FileDesc) uint64 { 217 return uint64(fd.Num)<<typeShift | uint64(fd.Type) 218 } 219 220 func unpackFile(x uint64) FileDesc { 221 return FileDesc{FileType(x) & TypeAll, int64(x >> typeShift)} 222 }