db

package
v1.30.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 20, 2025 License: MPL-2.0 Imports: 29 Imported by: 18

Documentation

Overview

Package db provides a set type to track local/remote files with newness checks. We must do a certain amount of normalization in here. We will get fed paths with either native or wire-format separators and encodings depending on who calls us. We transform paths to wire-format (NFC and slashes) on the way to the database, and transform to native format (varying separator and encoding) on the way back out.

Index

Constants

View Source
const (
	// KeyTypeDevice <int32 folder ID> <int32 device ID> <file name> = FileInfo
	KeyTypeDevice byte = 0

	// KeyTypeGlobal <int32 folder ID> <file name> = VersionList
	KeyTypeGlobal byte = 1

	// KeyTypeBlock <int32 folder ID> <32 bytes hash> <§file name> = int32 (block index)
	KeyTypeBlock byte = 2

	// KeyTypeDeviceStatistic <device ID as string> <some string> = some value
	KeyTypeDeviceStatistic byte = 3

	// KeyTypeFolderStatistic <folder ID as string> <some string> = some value
	KeyTypeFolderStatistic byte = 4

	// KeyTypeVirtualMtime <int32 folder ID> <file name> = mtimeMapping
	KeyTypeVirtualMtime byte = 5

	// KeyTypeFolderIdx <int32 id> = string value
	KeyTypeFolderIdx byte = 6

	// KeyTypeDeviceIdx <int32 id> = string value
	KeyTypeDeviceIdx byte = 7

	// KeyTypeIndexID <int32 device ID> <int32 folder ID> = protocol.IndexID
	KeyTypeIndexID byte = 8

	// KeyTypeFolderMeta <int32 folder ID> = CountsSet
	KeyTypeFolderMeta byte = 9

	// KeyTypeMiscData <some string> = some value
	KeyTypeMiscData byte = 10

	// KeyTypeSequence <int32 folder ID> <int64 sequence number> = KeyTypeDevice key
	KeyTypeSequence byte = 11

	// KeyTypeNeed <int32 folder ID> <file name> = <nothing>
	KeyTypeNeed byte = 12

	// KeyTypeBlockList <block list hash> = BlockList
	KeyTypeBlockList byte = 13

	// KeyTypeBlockListMap <int32 folder ID> <block list hash> <file name> = <nothing>
	KeyTypeBlockListMap byte = 14

	// KeyTypeVersion <version hash> = Vector
	KeyTypeVersion byte = 15

	// KeyTypePendingFolder <int32 device ID> <folder ID as string> = ObservedFolder
	KeyTypePendingFolder byte = 16

	// KeyTypePendingDevice <device ID in wire format> = ObservedDevice
	KeyTypePendingDevice byte = 17
)
View Source
const (
	MaxBatchSizeBytes = 250 * 1024 // Aim for making index messages no larger than 250 KiB (uncompressed)
	MaxBatchSizeFiles = 1000       // Either way, don't include more files than this
)

How many files to send in each Index/IndexUpdate message.

Variables

This section is empty.

Functions

func DropDeltaIndexIDs added in v0.14.52

func DropDeltaIndexIDs(db *Lowlevel)

DropDeltaIndexIDs removes all delta index IDs from the database. This will cause a full index transmission on the next connection. Must be called before using FileSets, i.e. before NewFileSet is called for the first time.

func DropFolder

func DropFolder(db *Lowlevel, folder string)

DropFolder clears out all information related to the given folder from the database.

func Need added in v1.10.0

func Need(global *dbproto.FileVersion, haveLocal bool, localVersion protocol.Vector) bool

func UpdateSchema added in v0.14.52

func UpdateSchema(db *Lowlevel) error

UpdateSchema updates a possibly outdated database to the current schema and also does repairs where necessary.

Types

type BlockFinder

type BlockFinder struct {
	// contains filtered or unexported fields
}

func NewBlockFinder

func NewBlockFinder(db *Lowlevel) *BlockFinder

func (*BlockFinder) Iterate

func (f *BlockFinder) Iterate(folders []string, hash []byte, iterFn func(string, string, int32) bool) bool

Iterate takes an iterator function which iterates over all matching blocks for the given hash. The iterator function has to return either true (if they are happy with the block) or false to continue iterating for whatever reason. The iterator finally returns the result, whether or not a satisfying block was eventually found.

func (*BlockFinder) String

func (f *BlockFinder) String() string

type Counts added in v0.14.10

type Counts struct {
	Files       int
	Directories int
	Symlinks    int
	Deleted     int
	Bytes       int64
	Sequence    int64             // zero for the global state
	DeviceID    protocol.DeviceID // device ID for remote devices, or special values for local/global
	LocalFlags  uint32            // the local flag for this count bucket
}

func (Counts) Add added in v0.14.50

func (c Counts) Add(other Counts) Counts

func (Counts) Equal added in v1.6.0

func (c Counts) Equal(o Counts) bool

Equal compares the numbers only, not sequence/dev/flags.

func (Counts) String added in v0.14.43

func (c Counts) String() string

func (Counts) TotalItems added in v1.0.0

func (c Counts) TotalItems() int

type CountsSet added in v0.14.43

type CountsSet struct {
	Counts  []Counts
	Created int64 // unix nanos
}

type DebugVersionList added in v1.29.0

type DebugVersionList struct {
	*dbproto.VersionList
}

DebugFileVersion is the database-internal representation of a file version, with a nicer string representation, used only by API debug methods.

func (DebugVersionList) String added in v1.29.0

func (vl DebugVersionList) String() string

type FileInfoBatch added in v1.17.0

type FileInfoBatch struct {
	// contains filtered or unexported fields
}

FileInfoBatch is a utility to do file operations on the database in suitably sized batches.

func NewFileInfoBatch added in v1.17.0

func NewFileInfoBatch(fn func([]protocol.FileInfo) error) *FileInfoBatch

NewFileInfoBatch returns a new FileInfoBatch that calls fn when it's time to flush. Errors from the flush function are considered non-recoverable; once an error is returned the flush function wil not be called again, and any further calls to Flush will return the same error (unless Reset is called).

func (*FileInfoBatch) Append added in v1.17.0

func (b *FileInfoBatch) Append(f protocol.FileInfo)

func (*FileInfoBatch) Flush added in v1.17.0

func (b *FileInfoBatch) Flush() error

func (*FileInfoBatch) FlushIfFull added in v1.17.0

func (b *FileInfoBatch) FlushIfFull() error

func (*FileInfoBatch) Full added in v1.17.0

func (b *FileInfoBatch) Full() bool

func (*FileInfoBatch) Reset added in v1.17.0

func (b *FileInfoBatch) Reset()

func (*FileInfoBatch) SetFlushFunc added in v1.17.0

func (b *FileInfoBatch) SetFlushFunc(fn func([]protocol.FileInfo) error)

func (*FileInfoBatch) Size added in v1.17.0

func (b *FileInfoBatch) Size() int

type FileSet

type FileSet struct {
	// contains filtered or unexported fields
}

func NewFileSet

func NewFileSet(folder string, db *Lowlevel) (*FileSet, error)

func (*FileSet) Drop added in v0.14.41

func (s *FileSet) Drop(device protocol.DeviceID)

func (*FileSet) IndexID added in v0.14.1

func (s *FileSet) IndexID(device protocol.DeviceID) protocol.IndexID

func (*FileSet) ListDevices added in v0.14.4

func (s *FileSet) ListDevices() []protocol.DeviceID

func (*FileSet) MtimeOption added in v1.20.0

func (s *FileSet) MtimeOption() fs.Option

func (*FileSet) RemoveLocalItems added in v1.18.5

func (s *FileSet) RemoveLocalItems(items []string)

func (*FileSet) RepairSequence added in v1.4.1

func (s *FileSet) RepairSequence() (int, error)

func (*FileSet) Sequence added in v0.14.4

func (s *FileSet) Sequence(device protocol.DeviceID) int64

func (*FileSet) SetIndexID added in v0.14.1

func (s *FileSet) SetIndexID(device protocol.DeviceID, id protocol.IndexID)

func (*FileSet) Snapshot added in v1.4.0

func (s *FileSet) Snapshot() (*Snapshot, error)

func (*FileSet) Update

func (s *FileSet) Update(device protocol.DeviceID, fs []protocol.FileInfo)

type Iterator

type Iterator func(f protocol.FileInfo) bool

The Iterator is called with either a protocol.FileInfo or a FileInfoTruncated (depending on the method) and returns true to continue iteration, false to stop.

type Lowlevel added in v0.14.52

type Lowlevel struct {
	*suture.Supervisor
	backend.Backend
	// contains filtered or unexported fields
}

Lowlevel is the lowest level database interface. It has a very simple purpose: hold the actual backend database, and the in-memory state that belong to that database. In the same way that a single on disk database can only be opened once, there should be only one Lowlevel for any given backend.

func NewLowlevel added in v0.14.52

func NewLowlevel(backend backend.Backend, evLogger events.Logger, opts ...Option) (*Lowlevel, error)

func (*Lowlevel) AddOrUpdatePendingDevice added in v1.13.0

func (db *Lowlevel) AddOrUpdatePendingDevice(device protocol.DeviceID, name, address string) error

func (*Lowlevel) AddOrUpdatePendingFolder added in v1.13.0

func (db *Lowlevel) AddOrUpdatePendingFolder(id string, of ObservedFolder, device protocol.DeviceID) error

func (*Lowlevel) ListFolders added in v0.14.52

func (db *Lowlevel) ListFolders() []string

ListFolders returns the list of folders currently in the database

func (*Lowlevel) PendingDevices added in v1.13.0

func (db *Lowlevel) PendingDevices() (map[protocol.DeviceID]ObservedDevice, error)

PendingDevices enumerates all entries. Invalid ones are dropped from the database after a warning log message, as a side-effect.

func (*Lowlevel) PendingFolders added in v1.13.0

func (db *Lowlevel) PendingFolders() (map[string]PendingFolder, error)

func (*Lowlevel) PendingFoldersForDevice added in v1.13.0

func (db *Lowlevel) PendingFoldersForDevice(device protocol.DeviceID) (map[string]PendingFolder, error)

PendingFoldersForDevice enumerates only entries matching the given device ID, unless it is EmptyDeviceID. Invalid ones are dropped from the database after a info log message, as a side-effect.

func (*Lowlevel) RemovePendingDevice added in v1.13.0

func (db *Lowlevel) RemovePendingDevice(device protocol.DeviceID) error

func (*Lowlevel) RemovePendingFolder added in v1.13.0

func (db *Lowlevel) RemovePendingFolder(id string) error

RemovePendingFolder removes all entries matching a specific folder ID.

func (*Lowlevel) RemovePendingFolderForDevice added in v1.13.0

func (db *Lowlevel) RemovePendingFolderForDevice(id string, device protocol.DeviceID) error

RemovePendingFolderForDevice removes entries for specific folder / device combinations.

type NamespacedKV

type NamespacedKV struct {
	// contains filtered or unexported fields
}

NamespacedKV is a simple key-value store using a specific namespace within a leveldb.

func NewDeviceStatisticsNamespace added in v0.14.52

func NewDeviceStatisticsNamespace(db backend.Backend, device string) *NamespacedKV

NewDeviceStatisticsNamespace creates a KV namespace for device statistics for the given device.

func NewFolderStatisticsNamespace added in v0.14.52

func NewFolderStatisticsNamespace(db backend.Backend, folder string) *NamespacedKV

NewFolderStatisticsNamespace creates a KV namespace for folder statistics for the given folder.

func NewMiscDataNamespace added in v0.14.52

func NewMiscDataNamespace(db backend.Backend) *NamespacedKV

NewMiscDataNamespace creates a KV namespace for miscellaneous metadata.

func NewNamespacedKV

func NewNamespacedKV(db backend.Backend, prefix string) *NamespacedKV

NewNamespacedKV returns a new NamespacedKV that lives in the namespace specified by the prefix.

func (NamespacedKV) Bool

func (n NamespacedKV) Bool(key string) (bool, bool, error)

Bool returns the stored value as a boolean and a boolean that is false if no value was stored at the key.

func (NamespacedKV) Bytes

func (n NamespacedKV) Bytes(key string) ([]byte, bool, error)

Bytes returns the stored value as a raw byte slice and a boolean that is false if no value was stored at the key.

func (NamespacedKV) Delete

func (n NamespacedKV) Delete(key string) error

Delete deletes the specified key. It is allowed to delete a nonexistent key.

func (*NamespacedKV) Int64

func (n *NamespacedKV) Int64(key string) (int64, bool, error)

Int64 returns the stored value interpreted as an int64 and a boolean that is false if no value was stored at the key.

func (*NamespacedKV) PutBool

func (n *NamespacedKV) PutBool(key string, val bool) error

PutBool stores a new boolean. Any existing value (even if of another type) is overwritten.

func (*NamespacedKV) PutBytes

func (n *NamespacedKV) PutBytes(key string, val []byte) error

PutBytes stores a new byte slice. Any existing value (even if of another type) is overwritten.

func (*NamespacedKV) PutInt64

func (n *NamespacedKV) PutInt64(key string, val int64) error

PutInt64 stores a new int64. Any existing value (even if of another type) is overwritten.

func (*NamespacedKV) PutString

func (n *NamespacedKV) PutString(key, val string) error

PutString stores a new string. Any existing value (even if of another type) is overwritten.

func (*NamespacedKV) PutTime

func (n *NamespacedKV) PutTime(key string, val time.Time) error

PutTime stores a new time.Time. Any existing value (even if of another type) is overwritten.

func (NamespacedKV) String

func (n NamespacedKV) String(key string) (string, bool, error)

String returns the stored value interpreted as a string and a boolean that is false if no value was stored at the key.

func (NamespacedKV) Time

func (n NamespacedKV) Time(key string) (time.Time, bool, error)

Time returns the stored value interpreted as a time.Time and a boolean that is false if no value was stored at the key.

type ObservedDevice added in v1.13.0

type ObservedDevice struct {
	Time    time.Time `json:"time"`
	Name    string    `json:"name"`
	Address string    `json:"address"`
}

type ObservedFolder added in v1.13.0

type ObservedFolder struct {
	Time             time.Time `json:"time"`
	Label            string    `json:"label"`
	ReceiveEncrypted bool      `json:"receiveEncrypted"`
	RemoteEncrypted  bool      `json:"remoteEncrypted"`
}

type Option added in v1.5.0

type Option func(*Lowlevel)

func WithIndirectGCInterval added in v1.5.0

func WithIndirectGCInterval(dur time.Duration) Option

WithIndirectGCInterval sets the time interval in between GC runs.

func WithRecheckInterval added in v1.5.0

func WithRecheckInterval(dur time.Duration) Option

WithRecheckInterval sets the time interval in between metadata recalculations and consistency checks.

type PendingFolder added in v1.13.0

type PendingFolder struct {
	OfferedBy map[protocol.DeviceID]ObservedFolder `json:"offeredBy"`
}

Consolidated information about a pending folder

type Snapshot added in v1.4.0

type Snapshot struct {
	// contains filtered or unexported fields
}

func (*Snapshot) Availability added in v1.4.0

func (s *Snapshot) Availability(file string) []protocol.DeviceID

func (*Snapshot) DebugGlobalVersions added in v1.12.1

func (s *Snapshot) DebugGlobalVersions(file string) *DebugVersionList

func (*Snapshot) Get added in v1.4.0

func (s *Snapshot) Get(device protocol.DeviceID, file string) (protocol.FileInfo, bool)

func (*Snapshot) GetGlobal added in v1.4.0

func (s *Snapshot) GetGlobal(file string) (protocol.FileInfo, bool)

func (*Snapshot) GetGlobalTruncated added in v1.4.0

func (s *Snapshot) GetGlobalTruncated(file string) (protocol.FileInfo, bool)

func (*Snapshot) GlobalSize added in v1.4.0

func (s *Snapshot) GlobalSize() Counts

func (*Snapshot) LocalSize added in v1.4.0

func (s *Snapshot) LocalSize() Counts

func (*Snapshot) NeedSize added in v1.4.0

func (s *Snapshot) NeedSize(device protocol.DeviceID) Counts

func (*Snapshot) ReceiveOnlyChangedSize added in v1.4.0

func (s *Snapshot) ReceiveOnlyChangedSize() Counts

func (*Snapshot) Release added in v1.4.0

func (s *Snapshot) Release()

func (*Snapshot) RemoteSequences added in v1.27.4

func (s *Snapshot) RemoteSequences() map[protocol.DeviceID]int64

RemoteSequences returns a map of the sequence numbers seen for each remote device sharing this folder.

func (*Snapshot) Sequence added in v1.4.0

func (s *Snapshot) Sequence(device protocol.DeviceID) int64

func (*Snapshot) WithBlocksHash added in v1.6.0

func (s *Snapshot) WithBlocksHash(hash []byte, fn Iterator)

func (*Snapshot) WithGlobal added in v1.4.0

func (s *Snapshot) WithGlobal(fn Iterator)

func (*Snapshot) WithGlobalTruncated added in v1.4.0

func (s *Snapshot) WithGlobalTruncated(fn Iterator)

func (*Snapshot) WithHave added in v1.4.0

func (s *Snapshot) WithHave(device protocol.DeviceID, fn Iterator)

func (*Snapshot) WithHaveSequence added in v1.4.0

func (s *Snapshot) WithHaveSequence(startSeq int64, fn Iterator)

func (*Snapshot) WithHaveTruncated added in v1.4.0

func (s *Snapshot) WithHaveTruncated(device protocol.DeviceID, fn Iterator)

func (*Snapshot) WithNeed added in v1.4.0

func (s *Snapshot) WithNeed(device protocol.DeviceID, fn Iterator)

func (*Snapshot) WithNeedTruncated added in v1.4.0

func (s *Snapshot) WithNeedTruncated(device protocol.DeviceID, fn Iterator)

func (*Snapshot) WithPrefixedGlobalTruncated added in v1.4.0

func (s *Snapshot) WithPrefixedGlobalTruncated(prefix string, fn Iterator)

Except for an item with a path equal to prefix, only children of prefix are iterated. E.g. for prefix "dir", "dir/file" is iterated, but "dir.file" is not.

func (*Snapshot) WithPrefixedHaveTruncated added in v1.4.0

func (s *Snapshot) WithPrefixedHaveTruncated(device protocol.DeviceID, prefix string, fn Iterator)

Except for an item with a path equal to prefix, only children of prefix are iterated. E.g. for prefix "dir", "dir/file" is iterated, but "dir.file" is not.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL