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  }