mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-03 21:08:25 +00:00 
			
		
		
		
	Simply remove tidb and deps (#3993)
This commit is contained in:
		
				
					committed by
					
						
						techknowlogick
					
				
			
			
				
	
			
			
			
						parent
						
							2e3475f02c
						
					
				
				
					commit
					74f9f98f78
				
			
							
								
								
									
										583
									
								
								vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										583
									
								
								vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,583 +0,0 @@
 | 
			
		||||
// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
 | 
			
		||||
// All rights reservefs.
 | 
			
		||||
//
 | 
			
		||||
// Use of this source code is governed by a BSD-style license that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package storage
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	errFileOpen = errors.New("leveldb/storage: file still open")
 | 
			
		||||
	errReadOnly = errors.New("leveldb/storage: storage is read-only")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type fileLock interface {
 | 
			
		||||
	release() error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type fileStorageLock struct {
 | 
			
		||||
	fs *fileStorage
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (lock *fileStorageLock) Release() {
 | 
			
		||||
	if lock.fs != nil {
 | 
			
		||||
		lock.fs.mu.Lock()
 | 
			
		||||
		defer lock.fs.mu.Unlock()
 | 
			
		||||
		if lock.fs.slock == lock {
 | 
			
		||||
			lock.fs.slock = nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const logSizeThreshold = 1024 * 1024 // 1 MiB
 | 
			
		||||
 | 
			
		||||
// fileStorage is a file-system backed storage.
 | 
			
		||||
type fileStorage struct {
 | 
			
		||||
	path     string
 | 
			
		||||
	readOnly bool
 | 
			
		||||
 | 
			
		||||
	mu      sync.Mutex
 | 
			
		||||
	flock   fileLock
 | 
			
		||||
	slock   *fileStorageLock
 | 
			
		||||
	logw    *os.File
 | 
			
		||||
	logSize int64
 | 
			
		||||
	buf     []byte
 | 
			
		||||
	// Opened file counter; if open < 0 means closed.
 | 
			
		||||
	open int
 | 
			
		||||
	day  int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// OpenFile returns a new filesytem-backed storage implementation with the given
 | 
			
		||||
// path. This also acquire a file lock, so any subsequent attempt to open the
 | 
			
		||||
// same path will fail.
 | 
			
		||||
//
 | 
			
		||||
// The storage must be closed after use, by calling Close method.
 | 
			
		||||
func OpenFile(path string, readOnly bool) (Storage, error) {
 | 
			
		||||
	if fi, err := os.Stat(path); err == nil {
 | 
			
		||||
		if !fi.IsDir() {
 | 
			
		||||
			return nil, fmt.Errorf("leveldb/storage: open %s: not a directory", path)
 | 
			
		||||
		}
 | 
			
		||||
	} else if os.IsNotExist(err) && !readOnly {
 | 
			
		||||
		if err := os.MkdirAll(path, 0755); err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	flock, err := newFileLock(filepath.Join(path, "LOCK"), readOnly)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			flock.release()
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	var (
 | 
			
		||||
		logw    *os.File
 | 
			
		||||
		logSize int64
 | 
			
		||||
	)
 | 
			
		||||
	if !readOnly {
 | 
			
		||||
		logw, err = os.OpenFile(filepath.Join(path, "LOG"), os.O_WRONLY|os.O_CREATE, 0644)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		logSize, err = logw.Seek(0, os.SEEK_END)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			logw.Close()
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fs := &fileStorage{
 | 
			
		||||
		path:     path,
 | 
			
		||||
		readOnly: readOnly,
 | 
			
		||||
		flock:    flock,
 | 
			
		||||
		logw:     logw,
 | 
			
		||||
		logSize:  logSize,
 | 
			
		||||
	}
 | 
			
		||||
	runtime.SetFinalizer(fs, (*fileStorage).Close)
 | 
			
		||||
	return fs, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fs *fileStorage) Lock() (Lock, error) {
 | 
			
		||||
	fs.mu.Lock()
 | 
			
		||||
	defer fs.mu.Unlock()
 | 
			
		||||
	if fs.open < 0 {
 | 
			
		||||
		return nil, ErrClosed
 | 
			
		||||
	}
 | 
			
		||||
	if fs.readOnly {
 | 
			
		||||
		return &fileStorageLock{}, nil
 | 
			
		||||
	}
 | 
			
		||||
	if fs.slock != nil {
 | 
			
		||||
		return nil, ErrLocked
 | 
			
		||||
	}
 | 
			
		||||
	fs.slock = &fileStorageLock{fs: fs}
 | 
			
		||||
	return fs.slock, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func itoa(buf []byte, i int, wid int) []byte {
 | 
			
		||||
	u := uint(i)
 | 
			
		||||
	if u == 0 && wid <= 1 {
 | 
			
		||||
		return append(buf, '0')
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Assemble decimal in reverse order.
 | 
			
		||||
	var b [32]byte
 | 
			
		||||
	bp := len(b)
 | 
			
		||||
	for ; u > 0 || wid > 0; u /= 10 {
 | 
			
		||||
		bp--
 | 
			
		||||
		wid--
 | 
			
		||||
		b[bp] = byte(u%10) + '0'
 | 
			
		||||
	}
 | 
			
		||||
	return append(buf, b[bp:]...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fs *fileStorage) printDay(t time.Time) {
 | 
			
		||||
	if fs.day == t.Day() {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	fs.day = t.Day()
 | 
			
		||||
	fs.logw.Write([]byte("=============== " + t.Format("Jan 2, 2006 (MST)") + " ===============\n"))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fs *fileStorage) doLog(t time.Time, str string) {
 | 
			
		||||
	if fs.logSize > logSizeThreshold {
 | 
			
		||||
		// Rotate log file.
 | 
			
		||||
		fs.logw.Close()
 | 
			
		||||
		fs.logw = nil
 | 
			
		||||
		fs.logSize = 0
 | 
			
		||||
		rename(filepath.Join(fs.path, "LOG"), filepath.Join(fs.path, "LOG.old"))
 | 
			
		||||
	}
 | 
			
		||||
	if fs.logw == nil {
 | 
			
		||||
		var err error
 | 
			
		||||
		fs.logw, err = os.OpenFile(filepath.Join(fs.path, "LOG"), os.O_WRONLY|os.O_CREATE, 0644)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		// Force printDay on new log file.
 | 
			
		||||
		fs.day = 0
 | 
			
		||||
	}
 | 
			
		||||
	fs.printDay(t)
 | 
			
		||||
	hour, min, sec := t.Clock()
 | 
			
		||||
	msec := t.Nanosecond() / 1e3
 | 
			
		||||
	// time
 | 
			
		||||
	fs.buf = itoa(fs.buf[:0], hour, 2)
 | 
			
		||||
	fs.buf = append(fs.buf, ':')
 | 
			
		||||
	fs.buf = itoa(fs.buf, min, 2)
 | 
			
		||||
	fs.buf = append(fs.buf, ':')
 | 
			
		||||
	fs.buf = itoa(fs.buf, sec, 2)
 | 
			
		||||
	fs.buf = append(fs.buf, '.')
 | 
			
		||||
	fs.buf = itoa(fs.buf, msec, 6)
 | 
			
		||||
	fs.buf = append(fs.buf, ' ')
 | 
			
		||||
	// write
 | 
			
		||||
	fs.buf = append(fs.buf, []byte(str)...)
 | 
			
		||||
	fs.buf = append(fs.buf, '\n')
 | 
			
		||||
	fs.logw.Write(fs.buf)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fs *fileStorage) Log(str string) {
 | 
			
		||||
	if !fs.readOnly {
 | 
			
		||||
		t := time.Now()
 | 
			
		||||
		fs.mu.Lock()
 | 
			
		||||
		defer fs.mu.Unlock()
 | 
			
		||||
		if fs.open < 0 {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		fs.doLog(t, str)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fs *fileStorage) log(str string) {
 | 
			
		||||
	if !fs.readOnly {
 | 
			
		||||
		fs.doLog(time.Now(), str)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fs *fileStorage) SetMeta(fd FileDesc) (err error) {
 | 
			
		||||
	if !FileDescOk(fd) {
 | 
			
		||||
		return ErrInvalidFile
 | 
			
		||||
	}
 | 
			
		||||
	if fs.readOnly {
 | 
			
		||||
		return errReadOnly
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fs.mu.Lock()
 | 
			
		||||
	defer fs.mu.Unlock()
 | 
			
		||||
	if fs.open < 0 {
 | 
			
		||||
		return ErrClosed
 | 
			
		||||
	}
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			fs.log(fmt.Sprintf("CURRENT: %v", err))
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
	path := fmt.Sprintf("%s.%d", filepath.Join(fs.path, "CURRENT"), fd.Num)
 | 
			
		||||
	w, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	_, err = fmt.Fprintln(w, fsGenName(fd))
 | 
			
		||||
	// Close the file first.
 | 
			
		||||
	if cerr := w.Close(); cerr != nil {
 | 
			
		||||
		fs.log(fmt.Sprintf("close CURRENT.%d: %v", fd.Num, cerr))
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	return rename(path, filepath.Join(fs.path, "CURRENT"))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fs *fileStorage) GetMeta() (fd FileDesc, err error) {
 | 
			
		||||
	fs.mu.Lock()
 | 
			
		||||
	defer fs.mu.Unlock()
 | 
			
		||||
	if fs.open < 0 {
 | 
			
		||||
		return FileDesc{}, ErrClosed
 | 
			
		||||
	}
 | 
			
		||||
	dir, err := os.Open(fs.path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	names, err := dir.Readdirnames(0)
 | 
			
		||||
	// Close the dir first before checking for Readdirnames error.
 | 
			
		||||
	if ce := dir.Close(); ce != nil {
 | 
			
		||||
		fs.log(fmt.Sprintf("close dir: %v", ce))
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	// Find latest CURRENT file.
 | 
			
		||||
	var rem []string
 | 
			
		||||
	var pend bool
 | 
			
		||||
	var cerr error
 | 
			
		||||
	for _, name := range names {
 | 
			
		||||
		if strings.HasPrefix(name, "CURRENT") {
 | 
			
		||||
			pend1 := len(name) > 7
 | 
			
		||||
			var pendNum int64
 | 
			
		||||
			// Make sure it is valid name for a CURRENT file, otherwise skip it.
 | 
			
		||||
			if pend1 {
 | 
			
		||||
				if name[7] != '.' || len(name) < 9 {
 | 
			
		||||
					fs.log(fmt.Sprintf("skipping %s: invalid file name", name))
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				var e1 error
 | 
			
		||||
				if pendNum, e1 = strconv.ParseInt(name[8:], 10, 0); e1 != nil {
 | 
			
		||||
					fs.log(fmt.Sprintf("skipping %s: invalid file num: %v", name, e1))
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			path := filepath.Join(fs.path, name)
 | 
			
		||||
			r, e1 := os.OpenFile(path, os.O_RDONLY, 0)
 | 
			
		||||
			if e1 != nil {
 | 
			
		||||
				return FileDesc{}, e1
 | 
			
		||||
			}
 | 
			
		||||
			b, e1 := ioutil.ReadAll(r)
 | 
			
		||||
			if e1 != nil {
 | 
			
		||||
				r.Close()
 | 
			
		||||
				return FileDesc{}, e1
 | 
			
		||||
			}
 | 
			
		||||
			var fd1 FileDesc
 | 
			
		||||
			if len(b) < 1 || b[len(b)-1] != '\n' || !fsParseNamePtr(string(b[:len(b)-1]), &fd1) {
 | 
			
		||||
				fs.log(fmt.Sprintf("skipping %s: corrupted or incomplete", name))
 | 
			
		||||
				if pend1 {
 | 
			
		||||
					rem = append(rem, name)
 | 
			
		||||
				}
 | 
			
		||||
				if !pend1 || cerr == nil {
 | 
			
		||||
					metaFd, _ := fsParseName(name)
 | 
			
		||||
					cerr = &ErrCorrupted{
 | 
			
		||||
						Fd:  metaFd,
 | 
			
		||||
						Err: errors.New("leveldb/storage: corrupted or incomplete meta file"),
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			} else if pend1 && pendNum != fd1.Num {
 | 
			
		||||
				fs.log(fmt.Sprintf("skipping %s: inconsistent pending-file num: %d vs %d", name, pendNum, fd1.Num))
 | 
			
		||||
				rem = append(rem, name)
 | 
			
		||||
			} else if fd1.Num < fd.Num {
 | 
			
		||||
				fs.log(fmt.Sprintf("skipping %s: obsolete", name))
 | 
			
		||||
				if pend1 {
 | 
			
		||||
					rem = append(rem, name)
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				fd = fd1
 | 
			
		||||
				pend = pend1
 | 
			
		||||
			}
 | 
			
		||||
			if err := r.Close(); err != nil {
 | 
			
		||||
				fs.log(fmt.Sprintf("close %s: %v", name, err))
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// Don't remove any files if there is no valid CURRENT file.
 | 
			
		||||
	if fd.Nil() {
 | 
			
		||||
		if cerr != nil {
 | 
			
		||||
			err = cerr
 | 
			
		||||
		} else {
 | 
			
		||||
			err = os.ErrNotExist
 | 
			
		||||
		}
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if !fs.readOnly {
 | 
			
		||||
		// Rename pending CURRENT file to an effective CURRENT.
 | 
			
		||||
		if pend {
 | 
			
		||||
			path := fmt.Sprintf("%s.%d", filepath.Join(fs.path, "CURRENT"), fd.Num)
 | 
			
		||||
			if err := rename(path, filepath.Join(fs.path, "CURRENT")); err != nil {
 | 
			
		||||
				fs.log(fmt.Sprintf("CURRENT.%d -> CURRENT: %v", fd.Num, err))
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// Remove obsolete or incomplete pending CURRENT files.
 | 
			
		||||
		for _, name := range rem {
 | 
			
		||||
			path := filepath.Join(fs.path, name)
 | 
			
		||||
			if err := os.Remove(path); err != nil {
 | 
			
		||||
				fs.log(fmt.Sprintf("remove %s: %v", name, err))
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fs *fileStorage) List(ft FileType) (fds []FileDesc, err error) {
 | 
			
		||||
	fs.mu.Lock()
 | 
			
		||||
	defer fs.mu.Unlock()
 | 
			
		||||
	if fs.open < 0 {
 | 
			
		||||
		return nil, ErrClosed
 | 
			
		||||
	}
 | 
			
		||||
	dir, err := os.Open(fs.path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	names, err := dir.Readdirnames(0)
 | 
			
		||||
	// Close the dir first before checking for Readdirnames error.
 | 
			
		||||
	if cerr := dir.Close(); cerr != nil {
 | 
			
		||||
		fs.log(fmt.Sprintf("close dir: %v", cerr))
 | 
			
		||||
	}
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		for _, name := range names {
 | 
			
		||||
			if fd, ok := fsParseName(name); ok && fd.Type&ft != 0 {
 | 
			
		||||
				fds = append(fds, fd)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fs *fileStorage) Open(fd FileDesc) (Reader, error) {
 | 
			
		||||
	if !FileDescOk(fd) {
 | 
			
		||||
		return nil, ErrInvalidFile
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fs.mu.Lock()
 | 
			
		||||
	defer fs.mu.Unlock()
 | 
			
		||||
	if fs.open < 0 {
 | 
			
		||||
		return nil, ErrClosed
 | 
			
		||||
	}
 | 
			
		||||
	of, err := os.OpenFile(filepath.Join(fs.path, fsGenName(fd)), os.O_RDONLY, 0)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if fsHasOldName(fd) && os.IsNotExist(err) {
 | 
			
		||||
			of, err = os.OpenFile(filepath.Join(fs.path, fsGenOldName(fd)), os.O_RDONLY, 0)
 | 
			
		||||
			if err == nil {
 | 
			
		||||
				goto ok
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
ok:
 | 
			
		||||
	fs.open++
 | 
			
		||||
	return &fileWrap{File: of, fs: fs, fd: fd}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fs *fileStorage) Create(fd FileDesc) (Writer, error) {
 | 
			
		||||
	if !FileDescOk(fd) {
 | 
			
		||||
		return nil, ErrInvalidFile
 | 
			
		||||
	}
 | 
			
		||||
	if fs.readOnly {
 | 
			
		||||
		return nil, errReadOnly
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fs.mu.Lock()
 | 
			
		||||
	defer fs.mu.Unlock()
 | 
			
		||||
	if fs.open < 0 {
 | 
			
		||||
		return nil, ErrClosed
 | 
			
		||||
	}
 | 
			
		||||
	of, err := os.OpenFile(filepath.Join(fs.path, fsGenName(fd)), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	fs.open++
 | 
			
		||||
	return &fileWrap{File: of, fs: fs, fd: fd}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fs *fileStorage) Remove(fd FileDesc) error {
 | 
			
		||||
	if !FileDescOk(fd) {
 | 
			
		||||
		return ErrInvalidFile
 | 
			
		||||
	}
 | 
			
		||||
	if fs.readOnly {
 | 
			
		||||
		return errReadOnly
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fs.mu.Lock()
 | 
			
		||||
	defer fs.mu.Unlock()
 | 
			
		||||
	if fs.open < 0 {
 | 
			
		||||
		return ErrClosed
 | 
			
		||||
	}
 | 
			
		||||
	err := os.Remove(filepath.Join(fs.path, fsGenName(fd)))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if fsHasOldName(fd) && os.IsNotExist(err) {
 | 
			
		||||
			if e1 := os.Remove(filepath.Join(fs.path, fsGenOldName(fd))); !os.IsNotExist(e1) {
 | 
			
		||||
				fs.log(fmt.Sprintf("remove %s: %v (old name)", fd, err))
 | 
			
		||||
				err = e1
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			fs.log(fmt.Sprintf("remove %s: %v", fd, err))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fs *fileStorage) Rename(oldfd, newfd FileDesc) error {
 | 
			
		||||
	if !FileDescOk(oldfd) || !FileDescOk(newfd) {
 | 
			
		||||
		return ErrInvalidFile
 | 
			
		||||
	}
 | 
			
		||||
	if oldfd == newfd {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	if fs.readOnly {
 | 
			
		||||
		return errReadOnly
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fs.mu.Lock()
 | 
			
		||||
	defer fs.mu.Unlock()
 | 
			
		||||
	if fs.open < 0 {
 | 
			
		||||
		return ErrClosed
 | 
			
		||||
	}
 | 
			
		||||
	return rename(filepath.Join(fs.path, fsGenName(oldfd)), filepath.Join(fs.path, fsGenName(newfd)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fs *fileStorage) Close() error {
 | 
			
		||||
	fs.mu.Lock()
 | 
			
		||||
	defer fs.mu.Unlock()
 | 
			
		||||
	if fs.open < 0 {
 | 
			
		||||
		return ErrClosed
 | 
			
		||||
	}
 | 
			
		||||
	// Clear the finalizer.
 | 
			
		||||
	runtime.SetFinalizer(fs, nil)
 | 
			
		||||
 | 
			
		||||
	if fs.open > 0 {
 | 
			
		||||
		fs.log(fmt.Sprintf("close: warning, %d files still open", fs.open))
 | 
			
		||||
	}
 | 
			
		||||
	fs.open = -1
 | 
			
		||||
	if fs.logw != nil {
 | 
			
		||||
		fs.logw.Close()
 | 
			
		||||
	}
 | 
			
		||||
	return fs.flock.release()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type fileWrap struct {
 | 
			
		||||
	*os.File
 | 
			
		||||
	fs     *fileStorage
 | 
			
		||||
	fd     FileDesc
 | 
			
		||||
	closed bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fw *fileWrap) Sync() error {
 | 
			
		||||
	if err := fw.File.Sync(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if fw.fd.Type == TypeManifest {
 | 
			
		||||
		// Also sync parent directory if file type is manifest.
 | 
			
		||||
		// See: https://code.google.com/p/leveldb/issues/detail?id=190.
 | 
			
		||||
		if err := syncDir(fw.fs.path); err != nil {
 | 
			
		||||
			fw.fs.log(fmt.Sprintf("syncDir: %v", err))
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fw *fileWrap) Close() error {
 | 
			
		||||
	fw.fs.mu.Lock()
 | 
			
		||||
	defer fw.fs.mu.Unlock()
 | 
			
		||||
	if fw.closed {
 | 
			
		||||
		return ErrClosed
 | 
			
		||||
	}
 | 
			
		||||
	fw.closed = true
 | 
			
		||||
	fw.fs.open--
 | 
			
		||||
	err := fw.File.Close()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		fw.fs.log(fmt.Sprintf("close %s: %v", fw.fd, err))
 | 
			
		||||
	}
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func fsGenName(fd FileDesc) string {
 | 
			
		||||
	switch fd.Type {
 | 
			
		||||
	case TypeManifest:
 | 
			
		||||
		return fmt.Sprintf("MANIFEST-%06d", fd.Num)
 | 
			
		||||
	case TypeJournal:
 | 
			
		||||
		return fmt.Sprintf("%06d.log", fd.Num)
 | 
			
		||||
	case TypeTable:
 | 
			
		||||
		return fmt.Sprintf("%06d.ldb", fd.Num)
 | 
			
		||||
	case TypeTemp:
 | 
			
		||||
		return fmt.Sprintf("%06d.tmp", fd.Num)
 | 
			
		||||
	default:
 | 
			
		||||
		panic("invalid file type")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func fsHasOldName(fd FileDesc) bool {
 | 
			
		||||
	return fd.Type == TypeTable
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func fsGenOldName(fd FileDesc) string {
 | 
			
		||||
	switch fd.Type {
 | 
			
		||||
	case TypeTable:
 | 
			
		||||
		return fmt.Sprintf("%06d.sst", fd.Num)
 | 
			
		||||
	}
 | 
			
		||||
	return fsGenName(fd)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func fsParseName(name string) (fd FileDesc, ok bool) {
 | 
			
		||||
	var tail string
 | 
			
		||||
	_, err := fmt.Sscanf(name, "%d.%s", &fd.Num, &tail)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		switch tail {
 | 
			
		||||
		case "log":
 | 
			
		||||
			fd.Type = TypeJournal
 | 
			
		||||
		case "ldb", "sst":
 | 
			
		||||
			fd.Type = TypeTable
 | 
			
		||||
		case "tmp":
 | 
			
		||||
			fd.Type = TypeTemp
 | 
			
		||||
		default:
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		return fd, true
 | 
			
		||||
	}
 | 
			
		||||
	n, _ := fmt.Sscanf(name, "MANIFEST-%d%s", &fd.Num, &tail)
 | 
			
		||||
	if n == 1 {
 | 
			
		||||
		fd.Type = TypeManifest
 | 
			
		||||
		return fd, true
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func fsParseNamePtr(name string, fd *FileDesc) bool {
 | 
			
		||||
	_fd, ok := fsParseName(name)
 | 
			
		||||
	if fd != nil {
 | 
			
		||||
		*fd = _fd
 | 
			
		||||
	}
 | 
			
		||||
	return ok
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										65
									
								
								vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage_plan9.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										65
									
								
								vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage_plan9.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,65 +0,0 @@
 | 
			
		||||
// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
 | 
			
		||||
// All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
// Use of this source code is governed by a BSD-style license that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package storage
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type plan9FileLock struct {
 | 
			
		||||
	f *os.File
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fl *plan9FileLock) release() error {
 | 
			
		||||
	return fl.f.Close()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newFileLock(path string, readOnly bool) (fl fileLock, err error) {
 | 
			
		||||
	var (
 | 
			
		||||
		flag int
 | 
			
		||||
		perm os.FileMode
 | 
			
		||||
	)
 | 
			
		||||
	if readOnly {
 | 
			
		||||
		flag = os.O_RDONLY
 | 
			
		||||
	} else {
 | 
			
		||||
		flag = os.O_RDWR
 | 
			
		||||
		perm = os.ModeExclusive
 | 
			
		||||
	}
 | 
			
		||||
	f, err := os.OpenFile(path, flag, perm)
 | 
			
		||||
	if os.IsNotExist(err) {
 | 
			
		||||
		f, err = os.OpenFile(path, flag|os.O_CREATE, perm|0644)
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	fl = &plan9FileLock{f: f}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func rename(oldpath, newpath string) error {
 | 
			
		||||
	if _, err := os.Stat(newpath); err == nil {
 | 
			
		||||
		if err := os.Remove(newpath); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, fname := filepath.Split(newpath)
 | 
			
		||||
	return os.Rename(oldpath, fname)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func syncDir(name string) error {
 | 
			
		||||
	f, err := os.Open(name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	defer f.Close()
 | 
			
		||||
	if err := f.Sync(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										81
									
								
								vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage_solaris.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										81
									
								
								vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage_solaris.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,81 +0,0 @@
 | 
			
		||||
// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
 | 
			
		||||
// All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
// Use of this source code is governed by a BSD-style license that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// +build solaris
 | 
			
		||||
 | 
			
		||||
package storage
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"os"
 | 
			
		||||
	"syscall"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type unixFileLock struct {
 | 
			
		||||
	f *os.File
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fl *unixFileLock) release() error {
 | 
			
		||||
	if err := setFileLock(fl.f, false, false); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return fl.f.Close()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newFileLock(path string, readOnly bool) (fl fileLock, err error) {
 | 
			
		||||
	var flag int
 | 
			
		||||
	if readOnly {
 | 
			
		||||
		flag = os.O_RDONLY
 | 
			
		||||
	} else {
 | 
			
		||||
		flag = os.O_RDWR
 | 
			
		||||
	}
 | 
			
		||||
	f, err := os.OpenFile(path, flag, 0)
 | 
			
		||||
	if os.IsNotExist(err) {
 | 
			
		||||
		f, err = os.OpenFile(path, flag|os.O_CREATE, 0644)
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	err = setFileLock(f, readOnly, true)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		f.Close()
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	fl = &unixFileLock{f: f}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func setFileLock(f *os.File, readOnly, lock bool) error {
 | 
			
		||||
	flock := syscall.Flock_t{
 | 
			
		||||
		Type:   syscall.F_UNLCK,
 | 
			
		||||
		Start:  0,
 | 
			
		||||
		Len:    0,
 | 
			
		||||
		Whence: 1,
 | 
			
		||||
	}
 | 
			
		||||
	if lock {
 | 
			
		||||
		if readOnly {
 | 
			
		||||
			flock.Type = syscall.F_RDLCK
 | 
			
		||||
		} else {
 | 
			
		||||
			flock.Type = syscall.F_WRLCK
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return syscall.FcntlFlock(f.Fd(), syscall.F_SETLK, &flock)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func rename(oldpath, newpath string) error {
 | 
			
		||||
	return os.Rename(oldpath, newpath)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func syncDir(name string) error {
 | 
			
		||||
	f, err := os.Open(name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	defer f.Close()
 | 
			
		||||
	if err := f.Sync(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										86
									
								
								vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage_unix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										86
									
								
								vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage_unix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,86 +0,0 @@
 | 
			
		||||
// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
 | 
			
		||||
// All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
// Use of this source code is governed by a BSD-style license that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// +build darwin dragonfly freebsd linux netbsd openbsd
 | 
			
		||||
 | 
			
		||||
package storage
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"os"
 | 
			
		||||
	"syscall"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type unixFileLock struct {
 | 
			
		||||
	f *os.File
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fl *unixFileLock) release() error {
 | 
			
		||||
	if err := setFileLock(fl.f, false, false); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return fl.f.Close()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newFileLock(path string, readOnly bool) (fl fileLock, err error) {
 | 
			
		||||
	var flag int
 | 
			
		||||
	if readOnly {
 | 
			
		||||
		flag = os.O_RDONLY
 | 
			
		||||
	} else {
 | 
			
		||||
		flag = os.O_RDWR
 | 
			
		||||
	}
 | 
			
		||||
	f, err := os.OpenFile(path, flag, 0)
 | 
			
		||||
	if os.IsNotExist(err) {
 | 
			
		||||
		f, err = os.OpenFile(path, flag|os.O_CREATE, 0644)
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	err = setFileLock(f, readOnly, true)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		f.Close()
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	fl = &unixFileLock{f: f}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func setFileLock(f *os.File, readOnly, lock bool) error {
 | 
			
		||||
	how := syscall.LOCK_UN
 | 
			
		||||
	if lock {
 | 
			
		||||
		if readOnly {
 | 
			
		||||
			how = syscall.LOCK_SH
 | 
			
		||||
		} else {
 | 
			
		||||
			how = syscall.LOCK_EX
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return syscall.Flock(int(f.Fd()), how|syscall.LOCK_NB)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func rename(oldpath, newpath string) error {
 | 
			
		||||
	return os.Rename(oldpath, newpath)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isErrInvalid(err error) bool {
 | 
			
		||||
	if err == os.ErrInvalid {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	if syserr, ok := err.(*os.SyscallError); ok && syserr.Err == syscall.EINVAL {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func syncDir(name string) error {
 | 
			
		||||
	f, err := os.Open(name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	defer f.Close()
 | 
			
		||||
	if err := f.Sync(); err != nil && !isErrInvalid(err) {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										78
									
								
								vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										78
									
								
								vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,78 +0,0 @@
 | 
			
		||||
// Copyright (c) 2013, Suryandaru Triandana <syndtr@gmail.com>
 | 
			
		||||
// All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
// Use of this source code is governed by a BSD-style license that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package storage
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	modkernel32 = syscall.NewLazyDLL("kernel32.dll")
 | 
			
		||||
 | 
			
		||||
	procMoveFileExW = modkernel32.NewProc("MoveFileExW")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	_MOVEFILE_REPLACE_EXISTING = 1
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type windowsFileLock struct {
 | 
			
		||||
	fd syscall.Handle
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fl *windowsFileLock) release() error {
 | 
			
		||||
	return syscall.Close(fl.fd)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newFileLock(path string, readOnly bool) (fl fileLock, err error) {
 | 
			
		||||
	pathp, err := syscall.UTF16PtrFromString(path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	var access, shareMode uint32
 | 
			
		||||
	if readOnly {
 | 
			
		||||
		access = syscall.GENERIC_READ
 | 
			
		||||
		shareMode = syscall.FILE_SHARE_READ
 | 
			
		||||
	} else {
 | 
			
		||||
		access = syscall.GENERIC_READ | syscall.GENERIC_WRITE
 | 
			
		||||
	}
 | 
			
		||||
	fd, err := syscall.CreateFile(pathp, access, shareMode, nil, syscall.OPEN_EXISTING, syscall.FILE_ATTRIBUTE_NORMAL, 0)
 | 
			
		||||
	if err == syscall.ERROR_FILE_NOT_FOUND {
 | 
			
		||||
		fd, err = syscall.CreateFile(pathp, access, shareMode, nil, syscall.OPEN_ALWAYS, syscall.FILE_ATTRIBUTE_NORMAL, 0)
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	fl = &windowsFileLock{fd: fd}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func moveFileEx(from *uint16, to *uint16, flags uint32) error {
 | 
			
		||||
	r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags))
 | 
			
		||||
	if r1 == 0 {
 | 
			
		||||
		if e1 != 0 {
 | 
			
		||||
			return error(e1)
 | 
			
		||||
		}
 | 
			
		||||
		return syscall.EINVAL
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func rename(oldpath, newpath string) error {
 | 
			
		||||
	from, err := syscall.UTF16PtrFromString(oldpath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	to, err := syscall.UTF16PtrFromString(newpath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return moveFileEx(from, to, _MOVEFILE_REPLACE_EXISTING)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func syncDir(name string) error { return nil }
 | 
			
		||||
							
								
								
									
										218
									
								
								vendor/github.com/syndtr/goleveldb/leveldb/storage/mem_storage.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										218
									
								
								vendor/github.com/syndtr/goleveldb/leveldb/storage/mem_storage.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,218 +0,0 @@
 | 
			
		||||
// Copyright (c) 2013, Suryandaru Triandana <syndtr@gmail.com>
 | 
			
		||||
// All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
// Use of this source code is governed by a BSD-style license that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package storage
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"os"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const typeShift = 3
 | 
			
		||||
 | 
			
		||||
type memStorageLock struct {
 | 
			
		||||
	ms *memStorage
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (lock *memStorageLock) Release() {
 | 
			
		||||
	ms := lock.ms
 | 
			
		||||
	ms.mu.Lock()
 | 
			
		||||
	defer ms.mu.Unlock()
 | 
			
		||||
	if ms.slock == lock {
 | 
			
		||||
		ms.slock = nil
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// memStorage is a memory-backed storage.
 | 
			
		||||
type memStorage struct {
 | 
			
		||||
	mu    sync.Mutex
 | 
			
		||||
	slock *memStorageLock
 | 
			
		||||
	files map[uint64]*memFile
 | 
			
		||||
	meta  FileDesc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewMemStorage returns a new memory-backed storage implementation.
 | 
			
		||||
func NewMemStorage() Storage {
 | 
			
		||||
	return &memStorage{
 | 
			
		||||
		files: make(map[uint64]*memFile),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ms *memStorage) Lock() (Lock, error) {
 | 
			
		||||
	ms.mu.Lock()
 | 
			
		||||
	defer ms.mu.Unlock()
 | 
			
		||||
	if ms.slock != nil {
 | 
			
		||||
		return nil, ErrLocked
 | 
			
		||||
	}
 | 
			
		||||
	ms.slock = &memStorageLock{ms: ms}
 | 
			
		||||
	return ms.slock, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (*memStorage) Log(str string) {}
 | 
			
		||||
 | 
			
		||||
func (ms *memStorage) SetMeta(fd FileDesc) error {
 | 
			
		||||
	if !FileDescOk(fd) {
 | 
			
		||||
		return ErrInvalidFile
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ms.mu.Lock()
 | 
			
		||||
	ms.meta = fd
 | 
			
		||||
	ms.mu.Unlock()
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ms *memStorage) GetMeta() (FileDesc, error) {
 | 
			
		||||
	ms.mu.Lock()
 | 
			
		||||
	defer ms.mu.Unlock()
 | 
			
		||||
	if ms.meta.Nil() {
 | 
			
		||||
		return FileDesc{}, os.ErrNotExist
 | 
			
		||||
	}
 | 
			
		||||
	return ms.meta, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ms *memStorage) List(ft FileType) ([]FileDesc, error) {
 | 
			
		||||
	ms.mu.Lock()
 | 
			
		||||
	var fds []FileDesc
 | 
			
		||||
	for x, _ := range ms.files {
 | 
			
		||||
		fd := unpackFile(x)
 | 
			
		||||
		if fd.Type&ft != 0 {
 | 
			
		||||
			fds = append(fds, fd)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	ms.mu.Unlock()
 | 
			
		||||
	return fds, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ms *memStorage) Open(fd FileDesc) (Reader, error) {
 | 
			
		||||
	if !FileDescOk(fd) {
 | 
			
		||||
		return nil, ErrInvalidFile
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ms.mu.Lock()
 | 
			
		||||
	defer ms.mu.Unlock()
 | 
			
		||||
	if m, exist := ms.files[packFile(fd)]; exist {
 | 
			
		||||
		if m.open {
 | 
			
		||||
			return nil, errFileOpen
 | 
			
		||||
		}
 | 
			
		||||
		m.open = true
 | 
			
		||||
		return &memReader{Reader: bytes.NewReader(m.Bytes()), ms: ms, m: m}, nil
 | 
			
		||||
	}
 | 
			
		||||
	return nil, os.ErrNotExist
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ms *memStorage) Create(fd FileDesc) (Writer, error) {
 | 
			
		||||
	if !FileDescOk(fd) {
 | 
			
		||||
		return nil, ErrInvalidFile
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	x := packFile(fd)
 | 
			
		||||
	ms.mu.Lock()
 | 
			
		||||
	defer ms.mu.Unlock()
 | 
			
		||||
	m, exist := ms.files[x]
 | 
			
		||||
	if exist {
 | 
			
		||||
		if m.open {
 | 
			
		||||
			return nil, errFileOpen
 | 
			
		||||
		}
 | 
			
		||||
		m.Reset()
 | 
			
		||||
	} else {
 | 
			
		||||
		m = &memFile{}
 | 
			
		||||
		ms.files[x] = m
 | 
			
		||||
	}
 | 
			
		||||
	m.open = true
 | 
			
		||||
	return &memWriter{memFile: m, ms: ms}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ms *memStorage) Remove(fd FileDesc) error {
 | 
			
		||||
	if !FileDescOk(fd) {
 | 
			
		||||
		return ErrInvalidFile
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	x := packFile(fd)
 | 
			
		||||
	ms.mu.Lock()
 | 
			
		||||
	defer ms.mu.Unlock()
 | 
			
		||||
	if _, exist := ms.files[x]; exist {
 | 
			
		||||
		delete(ms.files, x)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return os.ErrNotExist
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ms *memStorage) Rename(oldfd, newfd FileDesc) error {
 | 
			
		||||
	if FileDescOk(oldfd) || FileDescOk(newfd) {
 | 
			
		||||
		return ErrInvalidFile
 | 
			
		||||
	}
 | 
			
		||||
	if oldfd == newfd {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	oldx := packFile(oldfd)
 | 
			
		||||
	newx := packFile(newfd)
 | 
			
		||||
	ms.mu.Lock()
 | 
			
		||||
	defer ms.mu.Unlock()
 | 
			
		||||
	oldm, exist := ms.files[oldx]
 | 
			
		||||
	if !exist {
 | 
			
		||||
		return os.ErrNotExist
 | 
			
		||||
	}
 | 
			
		||||
	newm, exist := ms.files[newx]
 | 
			
		||||
	if (exist && newm.open) || oldm.open {
 | 
			
		||||
		return errFileOpen
 | 
			
		||||
	}
 | 
			
		||||
	delete(ms.files, oldx)
 | 
			
		||||
	ms.files[newx] = oldm
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (*memStorage) Close() error { return nil }
 | 
			
		||||
 | 
			
		||||
type memFile struct {
 | 
			
		||||
	bytes.Buffer
 | 
			
		||||
	open bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type memReader struct {
 | 
			
		||||
	*bytes.Reader
 | 
			
		||||
	ms     *memStorage
 | 
			
		||||
	m      *memFile
 | 
			
		||||
	closed bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (mr *memReader) Close() error {
 | 
			
		||||
	mr.ms.mu.Lock()
 | 
			
		||||
	defer mr.ms.mu.Unlock()
 | 
			
		||||
	if mr.closed {
 | 
			
		||||
		return ErrClosed
 | 
			
		||||
	}
 | 
			
		||||
	mr.m.open = false
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type memWriter struct {
 | 
			
		||||
	*memFile
 | 
			
		||||
	ms     *memStorage
 | 
			
		||||
	closed bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (*memWriter) Sync() error { return nil }
 | 
			
		||||
 | 
			
		||||
func (mw *memWriter) Close() error {
 | 
			
		||||
	mw.ms.mu.Lock()
 | 
			
		||||
	defer mw.ms.mu.Unlock()
 | 
			
		||||
	if mw.closed {
 | 
			
		||||
		return ErrClosed
 | 
			
		||||
	}
 | 
			
		||||
	mw.memFile.open = false
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func packFile(fd FileDesc) uint64 {
 | 
			
		||||
	return uint64(fd.Num)<<typeShift | uint64(fd.Type)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func unpackFile(x uint64) FileDesc {
 | 
			
		||||
	return FileDesc{FileType(x) & TypeAll, int64(x >> typeShift)}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										177
									
								
								vendor/github.com/syndtr/goleveldb/leveldb/storage/storage.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										177
									
								
								vendor/github.com/syndtr/goleveldb/leveldb/storage/storage.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,177 +0,0 @@
 | 
			
		||||
// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
 | 
			
		||||
// All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
// Use of this source code is governed by a BSD-style license that can be
 | 
			
		||||
// found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// Package storage provides storage abstraction for LevelDB.
 | 
			
		||||
package storage
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
 | 
			
		||||
	"github.com/syndtr/goleveldb/leveldb/util"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type FileType int
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	TypeManifest FileType = 1 << iota
 | 
			
		||||
	TypeJournal
 | 
			
		||||
	TypeTable
 | 
			
		||||
	TypeTemp
 | 
			
		||||
 | 
			
		||||
	TypeAll = TypeManifest | TypeJournal | TypeTable | TypeTemp
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (t FileType) String() string {
 | 
			
		||||
	switch t {
 | 
			
		||||
	case TypeManifest:
 | 
			
		||||
		return "manifest"
 | 
			
		||||
	case TypeJournal:
 | 
			
		||||
		return "journal"
 | 
			
		||||
	case TypeTable:
 | 
			
		||||
		return "table"
 | 
			
		||||
	case TypeTemp:
 | 
			
		||||
		return "temp"
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf("<unknown:%d>", t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	ErrInvalidFile = errors.New("leveldb/storage: invalid file for argument")
 | 
			
		||||
	ErrLocked      = errors.New("leveldb/storage: already locked")
 | 
			
		||||
	ErrClosed      = errors.New("leveldb/storage: closed")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ErrCorrupted is the type that wraps errors that indicate corruption of
 | 
			
		||||
// a file. Package storage has its own type instead of using
 | 
			
		||||
// errors.ErrCorrupted to prevent circular import.
 | 
			
		||||
type ErrCorrupted struct {
 | 
			
		||||
	Fd  FileDesc
 | 
			
		||||
	Err error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *ErrCorrupted) Error() string {
 | 
			
		||||
	if !e.Fd.Nil() {
 | 
			
		||||
		return fmt.Sprintf("%v [file=%v]", e.Err, e.Fd)
 | 
			
		||||
	} else {
 | 
			
		||||
		return e.Err.Error()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Syncer is the interface that wraps basic Sync method.
 | 
			
		||||
type Syncer interface {
 | 
			
		||||
	// Sync commits the current contents of the file to stable storage.
 | 
			
		||||
	Sync() error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Reader is the interface that groups the basic Read, Seek, ReadAt and Close
 | 
			
		||||
// methods.
 | 
			
		||||
type Reader interface {
 | 
			
		||||
	io.ReadSeeker
 | 
			
		||||
	io.ReaderAt
 | 
			
		||||
	io.Closer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Writer is the interface that groups the basic Write, Sync and Close
 | 
			
		||||
// methods.
 | 
			
		||||
type Writer interface {
 | 
			
		||||
	io.WriteCloser
 | 
			
		||||
	Syncer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Lock interface {
 | 
			
		||||
	util.Releaser
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FileDesc is a file descriptor.
 | 
			
		||||
type FileDesc struct {
 | 
			
		||||
	Type FileType
 | 
			
		||||
	Num  int64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fd FileDesc) String() string {
 | 
			
		||||
	switch fd.Type {
 | 
			
		||||
	case TypeManifest:
 | 
			
		||||
		return fmt.Sprintf("MANIFEST-%06d", fd.Num)
 | 
			
		||||
	case TypeJournal:
 | 
			
		||||
		return fmt.Sprintf("%06d.log", fd.Num)
 | 
			
		||||
	case TypeTable:
 | 
			
		||||
		return fmt.Sprintf("%06d.ldb", fd.Num)
 | 
			
		||||
	case TypeTemp:
 | 
			
		||||
		return fmt.Sprintf("%06d.tmp", fd.Num)
 | 
			
		||||
	default:
 | 
			
		||||
		return fmt.Sprintf("%#x-%d", fd.Type, fd.Num)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Nil returns true if fd == (FileDesc{}).
 | 
			
		||||
func (fd FileDesc) Nil() bool {
 | 
			
		||||
	return fd == (FileDesc{})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FileDescOk returns true if fd is a valid file descriptor.
 | 
			
		||||
func FileDescOk(fd FileDesc) bool {
 | 
			
		||||
	switch fd.Type {
 | 
			
		||||
	case TypeManifest:
 | 
			
		||||
	case TypeJournal:
 | 
			
		||||
	case TypeTable:
 | 
			
		||||
	case TypeTemp:
 | 
			
		||||
	default:
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	return fd.Num >= 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Storage is the storage. A storage instance must be goroutine-safe.
 | 
			
		||||
type Storage interface {
 | 
			
		||||
	// Lock locks the storage. Any subsequent attempt to call Lock will fail
 | 
			
		||||
	// until the last lock released.
 | 
			
		||||
	// After use the caller should call the Release method.
 | 
			
		||||
	Lock() (Lock, error)
 | 
			
		||||
 | 
			
		||||
	// Log logs a string. This is used for logging.
 | 
			
		||||
	// An implementation may write to a file, stdout or simply do nothing.
 | 
			
		||||
	Log(str string)
 | 
			
		||||
 | 
			
		||||
	// SetMeta sets to point to the given fd, which then can be acquired using
 | 
			
		||||
	// GetMeta method.
 | 
			
		||||
	// SetMeta should be implemented in such way that changes should happened
 | 
			
		||||
	// atomically.
 | 
			
		||||
	SetMeta(fd FileDesc) error
 | 
			
		||||
 | 
			
		||||
	// GetManifest returns a manifest file.
 | 
			
		||||
	// Returns os.ErrNotExist if meta doesn't point to any fd, or point to fd
 | 
			
		||||
	// that doesn't exist.
 | 
			
		||||
	GetMeta() (FileDesc, error)
 | 
			
		||||
 | 
			
		||||
	// List returns fds that match the given file types.
 | 
			
		||||
	// The file types may be OR'ed together.
 | 
			
		||||
	List(ft FileType) ([]FileDesc, error)
 | 
			
		||||
 | 
			
		||||
	// Open opens file with the given fd read-only.
 | 
			
		||||
	// Returns os.ErrNotExist error if the file does not exist.
 | 
			
		||||
	// Returns ErrClosed if the underlying storage is closed.
 | 
			
		||||
	Open(fd FileDesc) (Reader, error)
 | 
			
		||||
 | 
			
		||||
	// Create creates file with the given fd, truncate if already exist and
 | 
			
		||||
	// opens write-only.
 | 
			
		||||
	// Returns ErrClosed if the underlying storage is closed.
 | 
			
		||||
	Create(fd FileDesc) (Writer, error)
 | 
			
		||||
 | 
			
		||||
	// Remove removes file with the given fd.
 | 
			
		||||
	// Returns ErrClosed if the underlying storage is closed.
 | 
			
		||||
	Remove(fd FileDesc) error
 | 
			
		||||
 | 
			
		||||
	// Rename renames file from oldfd to newfd.
 | 
			
		||||
	// Returns ErrClosed if the underlying storage is closed.
 | 
			
		||||
	Rename(oldfd, newfd FileDesc) error
 | 
			
		||||
 | 
			
		||||
	// Close closes the storage.
 | 
			
		||||
	// It is valid to call Close multiple times. Other methods should not be
 | 
			
		||||
	// called after the storage has been closed.
 | 
			
		||||
	Close() error
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user