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  }