[#264] transformer: Finalize parent header once

In previous implementation parent object header finalized twice in size
limiter + formatter. On the one hand, this added redundant action, on the
other hand, it could provoke a difference in the headers of the linking and
the last part. Change formatter to finalize parent header if it does not
container the signature. Change size limiter to reuse parent header after
last child finalization in linking child.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2020-12-18 13:39:44 +03:00 committed by Leonard Lyubich
parent edef9463d7
commit ec21040542
3 changed files with 36 additions and 7 deletions

View file

@ -69,9 +69,12 @@ func (f *formatter) Close() (*AccessIdentifiers, error) {
f.obj.SetSessionToken(f.prm.SessionToken)
f.obj.SetCreationEpoch(curEpoch)
var parID *objectSDK.ID
var (
parID *objectSDK.ID
parHdr *objectSDK.Object
)
if par := f.obj.Parent(); par != nil {
if par := f.obj.Parent(); par != nil && par.Signature() == nil {
rawPar := objectSDK.NewRawFromV2(par.ToV2())
rawPar.SetSessionToken(f.prm.SessionToken)
@ -82,8 +85,9 @@ func (f *formatter) Close() (*AccessIdentifiers, error) {
}
parID = rawPar.ID()
parHdr = rawPar.Object()
f.obj.SetParent(rawPar.Object())
f.obj.SetParent(parHdr)
}
if err := objectSDK.SetIDWithSignature(f.prm.Key, f.obj.SDK()); err != nil {
@ -100,5 +104,6 @@ func (f *formatter) Close() (*AccessIdentifiers, error) {
return new(AccessIdentifiers).
WithSelfID(f.obj.ID()).
WithParentID(parID), nil
WithParentID(parID).
WithParent(parHdr), nil
}

View file

@ -196,7 +196,7 @@ func (s *payloadSizeLimiter) release(close bool) (*AccessIdentifiers, error) {
if withParent {
// generate and release linking object
s.initializeLinking()
s.initializeLinking(ids.Parent())
s.initializeCurrent()
if _, err := s.release(false); err != nil {
@ -214,9 +214,9 @@ func writeHashes(hashers []*payloadChecksumHasher) {
}
}
func (s *payloadSizeLimiter) initializeLinking() {
func (s *payloadSizeLimiter) initializeLinking(parHdr *objectSDK.Object) {
s.current = fromObject(s.current)
s.current.SetParent(s.parent.Object().SDK())
s.current.SetParent(parHdr)
s.current.SetChildren(s.previous...)
s.current.SetSplitID(s.splitID)
}
@ -279,6 +279,7 @@ func (s *payloadSizeLimiter) detachParent() {
s.parent = s.current
s.current = fromObject(s.parent)
s.parent.ResetRelations()
s.parent.SetSignature(nil)
s.parentHashers = s.currentHashers
// return source attributes

View file

@ -12,6 +12,8 @@ import (
// Consists of the ID of the stored object and the ID of the parent object.
type AccessIdentifiers struct {
par, self *objectSDK.ID
parHdr *objectSDK.Object
}
// ObjectTarget is an interface of the object writer.
@ -88,3 +90,24 @@ func (a *AccessIdentifiers) WithParentID(v *objectSDK.ID) *AccessIdentifiers {
return res
}
// Parent return identifier of the parent of the written object.
func (a *AccessIdentifiers) Parent() *objectSDK.Object {
if a != nil {
return a.parHdr
}
return nil
}
// WithParentID returns AccessIdentifiers with passed parent identifier.
func (a *AccessIdentifiers) WithParent(v *objectSDK.Object) *AccessIdentifiers {
res := a
if res == nil {
res = new(AccessIdentifiers)
}
res.parHdr = v
return res
}