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