storj/satellite/metainfo/objectdeletion/identifier.go
Rafael Gomes 375d76638d satellite/metainfo/objectdeletion: Object deletion implementation
Improve our delete logic to require fewer database requests.
This PR creates a new objectdeletion package

Change-Id: I0500173bb9b8c771accb350f076329ede6dbb42c
2020-07-20 16:09:48 +00:00

87 lines
2.4 KiB
Go

// Copyright (C) 2020 Storj Labs, Inc.
// See LICENSE for copying information.
package objectdeletion
import (
"errors"
"strconv"
"strings"
"github.com/zeebo/errs"
"storj.io/common/storj"
"storj.io/common/uuid"
)
// ObjectIdentifier contains information about an object
// that are needed for delete operation.
type ObjectIdentifier struct {
ProjectID uuid.UUID
Bucket []byte
EncryptedPath []byte
}
// SegmentPath returns a raw path for a specific segment index.
func (id *ObjectIdentifier) SegmentPath(segmentIndex int64) ([]byte, error) {
if segmentIndex < lastSegmentIndex {
return nil, errors.New("invalid segment index")
}
segment := "l"
if segmentIndex > lastSegmentIndex {
segment = "s" + strconv.FormatInt(segmentIndex, 10)
}
return []byte(storj.JoinPaths(
id.ProjectID.String(),
segment,
string(id.Bucket),
string(id.EncryptedPath),
)), nil
}
// ParseSegmentPath parses a raw path and returns an
// object identifier from that path along with the path's segment index.
// example: <project-id>/01/<bucket-name>/<encrypted-path>
func ParseSegmentPath(rawPath []byte) (ObjectIdentifier, int64, error) {
elements := storj.SplitPath(string(rawPath))
if len(elements) < 4 {
return ObjectIdentifier{}, -1, errs.New("invalid path %q", string(rawPath))
}
projectID, err := uuid.FromString(elements[0])
if err != nil {
return ObjectIdentifier{}, -1, errs.Wrap(err)
}
var segmentIndex int64
if elements[1] == "l" {
segmentIndex = lastSegmentIndex
} else {
segmentIndex, err = strconv.ParseInt(elements[1][1:], 10, 64) // remove the strng `s` from segment index we got
if err != nil {
return ObjectIdentifier{}, -1, errs.Wrap(err)
}
}
return ObjectIdentifier{
ProjectID: projectID,
Bucket: []byte(elements[2]),
EncryptedPath: []byte(storj.JoinPaths(elements[3:]...)),
}, segmentIndex, nil
}
// Key returns a string concatenated by all object identifier fields plus 0.
// It's a unique string used to identify an object.
// It's not a valid key for retrieving pointers from metainfo database.
func (id *ObjectIdentifier) Key() string {
builder := strings.Builder{}
// we don't need the return value here
// Write will always return the length of the argument and nil error
_, _ = builder.Write(id.ProjectID[:])
_, _ = builder.Write(id.Bucket)
_, _ = builder.Write(id.EncryptedPath)
return builder.String()
}