...

Source file src/github.com/syndtr/goleveldb/leveldb/storage/storage.go

Documentation: github.com/syndtr/goleveldb/leveldb/storage

     1  // Copyright (c) 2012, 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 provides storage abstraction for LevelDB.
     8  package storage
     9  
    10  import (
    11  	"errors"
    12  	"fmt"
    13  	"io"
    14  )
    15  
    16  // FileType represent a file type.
    17  type FileType int
    18  
    19  // File types.
    20  const (
    21  	TypeManifest FileType = 1 << iota
    22  	TypeJournal
    23  	TypeTable
    24  	TypeTemp
    25  
    26  	TypeAll = TypeManifest | TypeJournal | TypeTable | TypeTemp
    27  )
    28  
    29  func (t FileType) String() string {
    30  	switch t {
    31  	case TypeManifest:
    32  		return "manifest"
    33  	case TypeJournal:
    34  		return "journal"
    35  	case TypeTable:
    36  		return "table"
    37  	case TypeTemp:
    38  		return "temp"
    39  	}
    40  	return fmt.Sprintf("<unknown:%d>", t)
    41  }
    42  
    43  // Common error.
    44  var (
    45  	ErrInvalidFile = errors.New("leveldb/storage: invalid file for argument")
    46  	ErrLocked      = errors.New("leveldb/storage: already locked")
    47  	ErrClosed      = errors.New("leveldb/storage: closed")
    48  )
    49  
    50  // ErrCorrupted is the type that wraps errors that indicate corruption of
    51  // a file. Package storage has its own type instead of using
    52  // errors.ErrCorrupted to prevent circular import.
    53  type ErrCorrupted struct {
    54  	Fd  FileDesc
    55  	Err error
    56  }
    57  
    58  func isCorrupted(err error) bool {
    59  	switch err.(type) {
    60  	case *ErrCorrupted:
    61  		return true
    62  	default:
    63  		return false
    64  	}
    65  }
    66  
    67  func (e *ErrCorrupted) Error() string {
    68  	if !e.Fd.Zero() {
    69  		return fmt.Sprintf("%v [file=%v]", e.Err, e.Fd)
    70  	}
    71  	return e.Err.Error()
    72  }
    73  
    74  // Syncer is the interface that wraps basic Sync method.
    75  type Syncer interface {
    76  	// Sync commits the current contents of the file to stable storage.
    77  	Sync() error
    78  }
    79  
    80  // Reader is the interface that groups the basic Read, Seek, ReadAt and Close
    81  // methods.
    82  type Reader interface {
    83  	io.ReadSeeker
    84  	io.ReaderAt
    85  	io.Closer
    86  }
    87  
    88  // Writer is the interface that groups the basic Write, Sync and Close
    89  // methods.
    90  type Writer interface {
    91  	io.WriteCloser
    92  	Syncer
    93  }
    94  
    95  // Locker is the interface that wraps Unlock method.
    96  type Locker interface {
    97  	Unlock()
    98  }
    99  
   100  // FileDesc is a 'file descriptor'.
   101  type FileDesc struct {
   102  	Type FileType
   103  	Num  int64
   104  }
   105  
   106  func (fd FileDesc) String() string {
   107  	switch fd.Type {
   108  	case TypeManifest:
   109  		return fmt.Sprintf("MANIFEST-%06d", fd.Num)
   110  	case TypeJournal:
   111  		return fmt.Sprintf("%06d.log", fd.Num)
   112  	case TypeTable:
   113  		return fmt.Sprintf("%06d.ldb", fd.Num)
   114  	case TypeTemp:
   115  		return fmt.Sprintf("%06d.tmp", fd.Num)
   116  	default:
   117  		return fmt.Sprintf("%#x-%d", fd.Type, fd.Num)
   118  	}
   119  }
   120  
   121  // Zero returns true if fd == (FileDesc{}).
   122  func (fd FileDesc) Zero() bool {
   123  	return fd == (FileDesc{})
   124  }
   125  
   126  // FileDescOk returns true if fd is a valid 'file descriptor'.
   127  func FileDescOk(fd FileDesc) bool {
   128  	switch fd.Type {
   129  	case TypeManifest:
   130  	case TypeJournal:
   131  	case TypeTable:
   132  	case TypeTemp:
   133  	default:
   134  		return false
   135  	}
   136  	return fd.Num >= 0
   137  }
   138  
   139  // Storage is the storage. A storage instance must be safe for concurrent use.
   140  type Storage interface {
   141  	// Lock locks the storage. Any subsequent attempt to call Lock will fail
   142  	// until the last lock released.
   143  	// Caller should call Unlock method after use.
   144  	Lock() (Locker, error)
   145  
   146  	// Log logs a string. This is used for logging.
   147  	// An implementation may write to a file, stdout or simply do nothing.
   148  	Log(str string)
   149  
   150  	// SetMeta store 'file descriptor' that can later be acquired using GetMeta
   151  	// method. The 'file descriptor' should point to a valid file.
   152  	// SetMeta should be implemented in such way that changes should happen
   153  	// atomically.
   154  	SetMeta(fd FileDesc) error
   155  
   156  	// GetMeta returns 'file descriptor' stored in meta. The 'file descriptor'
   157  	// can be updated using SetMeta method.
   158  	// Returns os.ErrNotExist if meta doesn't store any 'file descriptor', or
   159  	// 'file descriptor' point to nonexistent file.
   160  	GetMeta() (FileDesc, error)
   161  
   162  	// List returns file descriptors that match the given file types.
   163  	// The file types may be OR'ed together.
   164  	List(ft FileType) ([]FileDesc, error)
   165  
   166  	// Open opens file with the given 'file descriptor' read-only.
   167  	// Returns os.ErrNotExist error if the file does not exist.
   168  	// Returns ErrClosed if the underlying storage is closed.
   169  	Open(fd FileDesc) (Reader, error)
   170  
   171  	// Create creates file with the given 'file descriptor', truncate if already
   172  	// exist and opens write-only.
   173  	// Returns ErrClosed if the underlying storage is closed.
   174  	Create(fd FileDesc) (Writer, error)
   175  
   176  	// Remove removes file with the given 'file descriptor'.
   177  	// Returns ErrClosed if the underlying storage is closed.
   178  	Remove(fd FileDesc) error
   179  
   180  	// Rename renames file from oldfd to newfd.
   181  	// Returns ErrClosed if the underlying storage is closed.
   182  	Rename(oldfd, newfd FileDesc) error
   183  
   184  	// Close closes the storage.
   185  	// It is valid to call Close multiple times. Other methods should not be
   186  	// called after the storage has been closed.
   187  	Close() error
   188  }
   189  

View as plain text