OSDN Git Service

Hulk did something
[bytom/vapor.git] / vendor / github.com / syndtr / goleveldb / leveldb / storage / mem_storage.go
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) Unlock() {
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() (Locker, 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.Zero() {
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 }