2019-01-24 20:15:10 +00:00
|
|
|
// Copyright (C) 2019 Storj Labs, Inc.
|
2018-10-01 12:29:27 +01:00
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
2018-09-28 07:59:27 +01:00
|
|
|
package storage
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"io"
|
2019-08-08 02:47:30 +01:00
|
|
|
"os"
|
2019-11-26 16:25:21 +00:00
|
|
|
"time"
|
2019-03-11 08:06:56 +00:00
|
|
|
|
|
|
|
"github.com/zeebo/errs"
|
2020-07-10 20:36:39 +01:00
|
|
|
|
|
|
|
"storj.io/common/storj"
|
2018-09-28 07:59:27 +01:00
|
|
|
)
|
|
|
|
|
2020-02-17 07:56:13 +00:00
|
|
|
// ErrInvalidBlobRef is returned when an blob reference is invalid.
|
2019-03-11 08:06:56 +00:00
|
|
|
var ErrInvalidBlobRef = errs.Class("invalid blob ref")
|
|
|
|
|
2019-08-08 02:47:30 +01:00
|
|
|
// FormatVersion represents differing storage format version values. Different Blobs implementors
|
|
|
|
// might interpret different FormatVersion values differently, but they share a type so that there
|
|
|
|
// can be a common StorageFormatVersion() call on the interface.
|
|
|
|
//
|
|
|
|
// Changes in FormatVersion might affect how a Blobs or BlobReader or BlobWriter instance works, or
|
|
|
|
// they might only be relevant to some higher layer. A FormatVersion must be specified when writing
|
|
|
|
// a new blob, and the blob storage interface must store that value with the blob somehow, so that
|
|
|
|
// the same FormatVersion is returned later when reading that stored blob.
|
|
|
|
type FormatVersion int
|
|
|
|
|
2020-07-16 15:18:02 +01:00
|
|
|
// BlobRef is a reference to a blob.
|
2019-03-11 08:06:56 +00:00
|
|
|
type BlobRef struct {
|
|
|
|
Namespace []byte
|
|
|
|
Key []byte
|
|
|
|
}
|
2018-09-28 07:59:27 +01:00
|
|
|
|
2020-02-17 07:56:13 +00:00
|
|
|
// IsValid returns whether both namespace and key are specified.
|
2019-03-11 08:06:56 +00:00
|
|
|
func (ref *BlobRef) IsValid() bool {
|
|
|
|
return len(ref.Namespace) > 0 && len(ref.Key) > 0
|
|
|
|
}
|
|
|
|
|
|
|
|
// BlobReader is an interface that groups Read, ReadAt, Seek and Close.
|
|
|
|
type BlobReader interface {
|
2018-09-28 07:59:27 +01:00
|
|
|
io.Reader
|
|
|
|
io.ReaderAt
|
|
|
|
io.Seeker
|
|
|
|
io.Closer
|
2020-02-17 07:56:13 +00:00
|
|
|
// Size returns the size of the blob.
|
2019-03-11 08:06:56 +00:00
|
|
|
Size() (int64, error)
|
2019-08-08 02:47:30 +01:00
|
|
|
// StorageFormatVersion returns the storage format version associated with the blob.
|
|
|
|
StorageFormatVersion() FormatVersion
|
2019-03-11 08:06:56 +00:00
|
|
|
}
|
|
|
|
|
2019-08-08 02:47:30 +01:00
|
|
|
// BlobWriter defines the interface that must be satisfied for a general blob storage provider.
|
|
|
|
// BlobWriter instances are returned by the Create() method on Blobs instances.
|
2019-03-11 08:06:56 +00:00
|
|
|
type BlobWriter interface {
|
|
|
|
io.Writer
|
2019-08-08 02:47:30 +01:00
|
|
|
io.Seeker
|
2019-03-11 08:06:56 +00:00
|
|
|
// Cancel discards the blob.
|
2019-06-05 14:06:06 +01:00
|
|
|
Cancel(context.Context) error
|
2019-03-11 08:06:56 +00:00
|
|
|
// Commit ensures that the blob is readable by others.
|
2019-06-05 14:06:06 +01:00
|
|
|
Commit(context.Context) error
|
2019-03-11 08:06:56 +00:00
|
|
|
// Size returns the size of the blob
|
|
|
|
Size() (int64, error)
|
2019-08-08 02:47:30 +01:00
|
|
|
// StorageFormatVersion returns the storage format version associated with the blob.
|
|
|
|
StorageFormatVersion() FormatVersion
|
2018-09-28 07:59:27 +01:00
|
|
|
}
|
|
|
|
|
2019-09-10 14:24:16 +01:00
|
|
|
// Blobs is a blob storage interface.
|
|
|
|
//
|
|
|
|
// architecture: Database
|
2018-09-28 07:59:27 +01:00
|
|
|
type Blobs interface {
|
2020-02-17 07:56:13 +00:00
|
|
|
// Create creates a new blob that can be written.
|
|
|
|
// Optionally takes a size argument for performance improvements, -1 is unknown size.
|
2019-03-11 08:06:56 +00:00
|
|
|
Create(ctx context.Context, ref BlobRef, size int64) (BlobWriter, error)
|
2020-02-17 07:56:13 +00:00
|
|
|
// Open opens a reader with the specified namespace and key.
|
2019-03-11 08:06:56 +00:00
|
|
|
Open(ctx context.Context, ref BlobRef) (BlobReader, error)
|
2019-08-08 02:47:30 +01:00
|
|
|
// OpenWithStorageFormat opens a reader for the already-located blob, avoiding the potential
|
|
|
|
// need to check multiple storage formats to find the blob.
|
|
|
|
OpenWithStorageFormat(ctx context.Context, ref BlobRef, formatVer FormatVersion) (BlobReader, error)
|
2020-02-17 07:56:13 +00:00
|
|
|
// Delete deletes the blob with the namespace and key.
|
2019-03-11 08:06:56 +00:00
|
|
|
Delete(ctx context.Context, ref BlobRef) error
|
2020-02-17 07:56:13 +00:00
|
|
|
// DeleteWithStorageFormat deletes a blob of a specific storage format.
|
2019-11-04 16:59:45 +00:00
|
|
|
DeleteWithStorageFormat(ctx context.Context, ref BlobRef, formatVer FormatVersion) error
|
2020-07-08 11:50:40 +01:00
|
|
|
// DeleteNamespace deletes blobs folder for a specific namespace.
|
|
|
|
DeleteNamespace(ctx context.Context, ref []byte) (err error)
|
2020-02-17 07:56:13 +00:00
|
|
|
// Trash marks a file for pending deletion.
|
2019-11-14 22:19:15 +00:00
|
|
|
Trash(ctx context.Context, ref BlobRef) error
|
2020-02-17 07:56:13 +00:00
|
|
|
// RestoreTrash restores all files in the trash for a given namespace and returns the keys restored.
|
2019-12-21 13:11:24 +00:00
|
|
|
RestoreTrash(ctx context.Context, namespace []byte) ([][]byte, error)
|
2020-02-17 07:56:13 +00:00
|
|
|
// EmptyTrash removes all files in trash that were moved to trash prior to trashedBefore and returns the total bytes emptied and keys deleted.
|
2019-12-21 13:11:24 +00:00
|
|
|
EmptyTrash(ctx context.Context, namespace []byte, trashedBefore time.Time) (int64, [][]byte, error)
|
2020-02-17 07:56:13 +00:00
|
|
|
// Stat looks up disk metadata on the blob file.
|
2019-08-08 02:47:30 +01:00
|
|
|
Stat(ctx context.Context, ref BlobRef) (BlobInfo, error)
|
|
|
|
// StatWithStorageFormat looks up disk metadata for the blob file with the given storage format
|
|
|
|
// version. This avoids the potential need to check multiple storage formats for the blob
|
|
|
|
// when the format is already known.
|
|
|
|
StatWithStorageFormat(ctx context.Context, ref BlobRef, formatVer FormatVersion) (BlobInfo, error)
|
2020-02-17 07:56:13 +00:00
|
|
|
// FreeSpace return how much free space is available to the blobstore.
|
2019-03-18 10:55:06 +00:00
|
|
|
FreeSpace() (int64, error)
|
2020-02-17 07:56:13 +00:00
|
|
|
// SpaceUsedForTrash returns the total space used by the trash.
|
2019-12-21 13:11:24 +00:00
|
|
|
SpaceUsedForTrash(ctx context.Context) (int64, error)
|
2020-02-17 07:56:13 +00:00
|
|
|
// SpaceUsedForBlobs adds up how much is used in all namespaces.
|
2019-12-21 13:11:24 +00:00
|
|
|
SpaceUsedForBlobs(ctx context.Context) (int64, error)
|
2020-02-17 07:56:13 +00:00
|
|
|
// SpaceUsedForBlobsInNamespace adds up how much is used in the given namespace.
|
2019-12-21 13:11:24 +00:00
|
|
|
SpaceUsedForBlobsInNamespace(ctx context.Context, namespace []byte) (int64, error)
|
2019-08-08 02:47:30 +01:00
|
|
|
// ListNamespaces finds all namespaces in which keys might currently be stored.
|
|
|
|
ListNamespaces(ctx context.Context) ([][]byte, error)
|
|
|
|
// WalkNamespace executes walkFunc for each locally stored blob, stored with
|
|
|
|
// storage format V1 or greater, in the given namespace. If walkFunc returns a non-nil
|
|
|
|
// error, WalkNamespace will stop iterating and return the error immediately. The ctx
|
|
|
|
// parameter is intended to allow canceling iteration early.
|
|
|
|
WalkNamespace(ctx context.Context, namespace []byte, walkFunc func(BlobInfo) error) error
|
2020-07-10 20:36:39 +01:00
|
|
|
// CreateVerificationFile creates a file to be used for storage directory verification.
|
|
|
|
CreateVerificationFile(id storj.NodeID) error
|
|
|
|
// VerifyStorageDir verifies that the storage directory is correct by checking for the existence and validity
|
|
|
|
// of the verification file.
|
|
|
|
VerifyStorageDir(id storj.NodeID) error
|
2019-11-13 19:15:31 +00:00
|
|
|
// Close closes the blob store and any resources associated with it.
|
|
|
|
Close() error
|
2019-08-08 02:47:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// BlobInfo allows lazy inspection of a blob and its underlying file during iteration with
|
2020-02-17 07:56:13 +00:00
|
|
|
// WalkNamespace-type methods.
|
2019-08-08 02:47:30 +01:00
|
|
|
type BlobInfo interface {
|
2020-02-17 07:56:13 +00:00
|
|
|
// BlobRef returns the relevant BlobRef for the blob.
|
2019-08-08 02:47:30 +01:00
|
|
|
BlobRef() BlobRef
|
2020-02-17 07:56:13 +00:00
|
|
|
// StorageFormatVersion indicates the storage format version used to store the piece.
|
2019-08-08 02:47:30 +01:00
|
|
|
StorageFormatVersion() FormatVersion
|
2020-02-17 07:56:13 +00:00
|
|
|
// FullPath gives the full path to the on-disk blob file.
|
2019-08-08 02:47:30 +01:00
|
|
|
FullPath(ctx context.Context) (string, error)
|
2020-02-17 07:56:13 +00:00
|
|
|
// Stat does a stat on the on-disk blob file.
|
2019-08-08 02:47:30 +01:00
|
|
|
Stat(ctx context.Context) (os.FileInfo, error)
|
2018-09-28 07:59:27 +01:00
|
|
|
}
|