github.com/TrueCloudLab/frostfs-api-go/v2@v2.0.0-20230228134343-196241c4e79a/object/lock.go (about)

     1  package object
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	lock "github.com/TrueCloudLab/frostfs-api-go/v2/lock/grpc"
     8  	"github.com/TrueCloudLab/frostfs-api-go/v2/refs"
     9  	refsGRPC "github.com/TrueCloudLab/frostfs-api-go/v2/refs/grpc"
    10  	"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/grpc"
    11  	"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/message"
    12  	"github.com/TrueCloudLab/frostfs-api-go/v2/util/proto"
    13  )
    14  
    15  // Lock represents object Lock message from NeoFS API V2 protocol.
    16  type Lock struct {
    17  	members []refs.ObjectID
    18  }
    19  
    20  // NumberOfMembers returns length of lock list.
    21  func (x *Lock) NumberOfMembers() int {
    22  	if x != nil {
    23  		return len(x.members)
    24  	}
    25  
    26  	return 0
    27  }
    28  
    29  // IterateMembers passes members of the lock list to f.
    30  func (x *Lock) IterateMembers(f func(refs.ObjectID)) {
    31  	if x != nil {
    32  		for i := range x.members {
    33  			f(x.members[i])
    34  		}
    35  	}
    36  }
    37  
    38  // SetMembers sets list of locked members.
    39  // Arg must not be mutated for the duration of the Lock.
    40  func (x *Lock) SetMembers(ids []refs.ObjectID) {
    41  	x.members = ids
    42  }
    43  
    44  const (
    45  	_ = iota
    46  	fNumLockMembers
    47  )
    48  
    49  // StableMarshal encodes the Lock into Protocol Buffers binary format
    50  // with direct field order.
    51  func (x *Lock) StableMarshal(buf []byte) []byte {
    52  	if x == nil || len(x.members) == 0 {
    53  		return []byte{}
    54  	}
    55  
    56  	if buf == nil {
    57  		buf = make([]byte, x.StableSize())
    58  	}
    59  
    60  	var offset int
    61  
    62  	for i := range x.members {
    63  		offset += proto.NestedStructureMarshal(fNumLockMembers, buf[offset:], &x.members[i])
    64  	}
    65  
    66  	return buf
    67  }
    68  
    69  // StableSize size of the buffer required to write the Lock in Protocol Buffers
    70  // binary format.
    71  func (x *Lock) StableSize() (sz int) {
    72  	if x != nil {
    73  		for i := range x.members {
    74  			sz += proto.NestedStructureSize(fNumLockMembers, &x.members[i])
    75  		}
    76  	}
    77  
    78  	return
    79  }
    80  
    81  // Unmarshal decodes the Lock from its Protocol Buffers binary format.
    82  func (x *Lock) Unmarshal(data []byte) error {
    83  	return message.Unmarshal(x, data, new(lock.Lock))
    84  }
    85  
    86  func (x *Lock) ToGRPCMessage() grpc.Message {
    87  	var m *lock.Lock
    88  
    89  	if x != nil {
    90  		m = new(lock.Lock)
    91  
    92  		var members []*refsGRPC.ObjectID
    93  
    94  		if x.members != nil {
    95  			members = make([]*refsGRPC.ObjectID, len(x.members))
    96  
    97  			for i := range x.members {
    98  				members[i] = x.members[i].ToGRPCMessage().(*refsGRPC.ObjectID)
    99  			}
   100  		}
   101  
   102  		m.SetMembers(members)
   103  	}
   104  
   105  	return m
   106  }
   107  
   108  func (x *Lock) FromGRPCMessage(m grpc.Message) error {
   109  	v, ok := m.(*lock.Lock)
   110  	if !ok {
   111  		return message.NewUnexpectedMessageType(m, v)
   112  	}
   113  
   114  	members := v.GetMembers()
   115  	if members == nil {
   116  		x.members = nil
   117  	} else {
   118  		x.members = make([]refs.ObjectID, len(members))
   119  		var err error
   120  
   121  		for i := range x.members {
   122  			err = x.members[i].FromGRPCMessage(members[i])
   123  			if err != nil {
   124  				return err
   125  			}
   126  		}
   127  	}
   128  
   129  	return nil
   130  }
   131  
   132  // WriteLock writes Lock to the Object as a payload content.
   133  // The object must not be nil.
   134  func WriteLock(obj *Object, lock Lock) {
   135  	hdr := obj.GetHeader()
   136  	if hdr == nil {
   137  		hdr = new(Header)
   138  		obj.SetHeader(hdr)
   139  	}
   140  
   141  	hdr.SetObjectType(TypeLock)
   142  
   143  	payload := lock.StableMarshal(nil)
   144  	obj.SetPayload(payload)
   145  }
   146  
   147  // ReadLock reads Lock from the Object payload content.
   148  func ReadLock(lock *Lock, obj Object) error {
   149  	payload := obj.GetPayload()
   150  	if len(payload) == 0 {
   151  		return errors.New("empty payload")
   152  	}
   153  
   154  	err := lock.Unmarshal(payload)
   155  	if err != nil {
   156  		return fmt.Errorf("decode lock content from payload: %w", err)
   157  	}
   158  
   159  	return nil
   160  }