github.com/petermattis/pebble@v0.0.0-20190905164901-ab51a2166067/internal/base/filenames.go (about)

     1  // Copyright 2012 The LevelDB-Go and Pebble Authors. All rights reserved. Use
     2  // of this source code is governed by a BSD-style license that can be found in
     3  // the LICENSE file.
     4  
     5  package base
     6  
     7  import (
     8  	"fmt"
     9  	"os"
    10  	"path/filepath"
    11  	"strconv"
    12  	"strings"
    13  )
    14  
    15  // FileType enumerates the types of files found in a DB.
    16  type FileType int
    17  
    18  // The FileType enumeration.
    19  const (
    20  	FileTypeLog FileType = iota
    21  	FileTypeLock
    22  	FileTypeTable
    23  	FileTypeManifest
    24  	FileTypeCurrent
    25  	FileTypeOptions
    26  )
    27  
    28  // MakeFilename builds a filename from components.
    29  func MakeFilename(dirname string, fileType FileType, fileNum uint64) string {
    30  	for len(dirname) > 0 && dirname[len(dirname)-1] == os.PathSeparator {
    31  		dirname = dirname[:len(dirname)-1]
    32  	}
    33  	switch fileType {
    34  	case FileTypeLog:
    35  		return fmt.Sprintf("%s%c%06d.log", dirname, os.PathSeparator, fileNum)
    36  	case FileTypeLock:
    37  		return fmt.Sprintf("%s%cLOCK", dirname, os.PathSeparator)
    38  	case FileTypeTable:
    39  		return fmt.Sprintf("%s%c%06d.sst", dirname, os.PathSeparator, fileNum)
    40  	case FileTypeManifest:
    41  		return fmt.Sprintf("%s%cMANIFEST-%06d", dirname, os.PathSeparator, fileNum)
    42  	case FileTypeCurrent:
    43  		return fmt.Sprintf("%s%cCURRENT", dirname, os.PathSeparator)
    44  	case FileTypeOptions:
    45  		return fmt.Sprintf("%s%cOPTIONS-%06d", dirname, os.PathSeparator, fileNum)
    46  	}
    47  	panic("unreachable")
    48  }
    49  
    50  // ParseFilename parses the components from a filename.
    51  func ParseFilename(filename string) (fileType FileType, fileNum uint64, ok bool) {
    52  	filename = filepath.Base(filename)
    53  	switch {
    54  	case filename == "CURRENT":
    55  		return FileTypeCurrent, 0, true
    56  	case filename == "LOCK":
    57  		return FileTypeLock, 0, true
    58  	case strings.HasPrefix(filename, "MANIFEST-"):
    59  		u, err := strconv.ParseUint(filename[len("MANIFEST-"):], 10, 64)
    60  		if err != nil {
    61  			break
    62  		}
    63  		return FileTypeManifest, u, true
    64  	case strings.HasPrefix(filename, "OPTIONS-"):
    65  		u, err := strconv.ParseUint(filename[len("OPTIONS-"):], 10, 64)
    66  		if err != nil {
    67  			break
    68  		}
    69  		return FileTypeOptions, u, true
    70  	default:
    71  		i := strings.IndexByte(filename, '.')
    72  		if i < 0 {
    73  			break
    74  		}
    75  		u, err := strconv.ParseUint(filename[:i], 10, 64)
    76  		if err != nil {
    77  			break
    78  		}
    79  		switch filename[i+1:] {
    80  		case "sst":
    81  			return FileTypeTable, u, true
    82  		case "log":
    83  			return FileTypeLog, u, true
    84  		}
    85  	}
    86  	return 0, 0, false
    87  }