ident: isolate non-system component of member
This enables more efficient representation in contexts inherently namespaced to the current system. Signed-off-by: Yonah <contrib@gensokyo.uk>
This commit is contained in:
@@ -6,8 +6,8 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// M represents a unique member identifier.
|
||||
type M struct {
|
||||
// PartM represents the first half of [M].
|
||||
type PartM struct {
|
||||
// A per-system value incremented by some unspecified amount every time the
|
||||
// metadata of a member first appears to the backend.
|
||||
Serial uint64
|
||||
@@ -18,7 +18,11 @@ type M struct {
|
||||
// Randomly generated value. The implementation must guarantee that the same
|
||||
// value cannot be emitted for a Time value.
|
||||
ID uint64
|
||||
}
|
||||
|
||||
// M represents a unique member identifier.
|
||||
type M struct {
|
||||
PartM
|
||||
// Underlying system.
|
||||
System S
|
||||
}
|
||||
@@ -35,19 +39,35 @@ const (
|
||||
// EncodedSize returns the number of bytes appended by Encode.
|
||||
func (*M) EncodedSize() int { return EncodedSizeMember }
|
||||
|
||||
// Encode appends the canonical string representation of mid to dst and returns
|
||||
// Encode appends the canonical string representation of pm to dst and returns
|
||||
// the extended buffer.
|
||||
func (mid *M) Encode(dst []byte) []byte {
|
||||
func (pm *PartM) Encode(dst []byte) []byte {
|
||||
var buf [SizeMember - SizeSystem]byte
|
||||
|
||||
p := buf[:]
|
||||
binary.LittleEndian.PutUint64(p, mid.Serial)
|
||||
binary.LittleEndian.PutUint64(p, pm.Serial)
|
||||
p = p[8:]
|
||||
binary.LittleEndian.PutUint64(p, mid.Time)
|
||||
binary.LittleEndian.PutUint64(p, pm.Time)
|
||||
p = p[8:]
|
||||
binary.LittleEndian.PutUint64(p, mid.ID)
|
||||
dst = base64.URLEncoding.AppendEncode(dst, buf[:])
|
||||
binary.LittleEndian.PutUint64(p, pm.ID)
|
||||
return base64.URLEncoding.AppendEncode(dst, buf[:])
|
||||
}
|
||||
|
||||
// String returns the canonical string representation of pm.
|
||||
func (pm *PartM) String() string {
|
||||
s := pm.Encode(nil)
|
||||
return unsafe.String(unsafe.SliceData(s), len(s))
|
||||
}
|
||||
|
||||
// MarshalText returns the result of Encode.
|
||||
func (pm *PartM) MarshalText() (data []byte, err error) {
|
||||
return pm.Encode(nil), nil
|
||||
}
|
||||
|
||||
// Encode appends the canonical string representation of mid to dst and returns
|
||||
// the extended buffer.
|
||||
func (mid *M) Encode(dst []byte) []byte {
|
||||
dst = mid.PartM.Encode(dst)
|
||||
return mid.System.Encode(dst)
|
||||
}
|
||||
|
||||
@@ -62,16 +82,16 @@ func (mid *M) MarshalText() (data []byte, err error) {
|
||||
return mid.Encode(nil), nil
|
||||
}
|
||||
|
||||
// UnmarshalText strictly decodes data into mid.
|
||||
func (mid *M) UnmarshalText(data []byte) error {
|
||||
if len(data) != EncodedSizeMember {
|
||||
return &UnexpectedSizeError{data, EncodedSizeMember}
|
||||
// UnmarshalText strictly decodes data into pm.
|
||||
func (pm *PartM) UnmarshalText(data []byte) error {
|
||||
if len(data) != EncodedSizeMember-EncodedSizeSystem {
|
||||
return &UnexpectedSizeError{data, EncodedSizeMember - EncodedSizeSystem}
|
||||
}
|
||||
|
||||
var buf [SizeMember - SizeSystem]byte
|
||||
if n, err := base64.URLEncoding.Decode(
|
||||
buf[:],
|
||||
data[:EncodedSizeMember-EncodedSizeSystem],
|
||||
data,
|
||||
); err != nil {
|
||||
return err
|
||||
} else if n != SizeMember-SizeSystem {
|
||||
@@ -79,11 +99,23 @@ func (mid *M) UnmarshalText(data []byte) error {
|
||||
}
|
||||
|
||||
p := buf[:]
|
||||
mid.Serial = binary.LittleEndian.Uint64(p)
|
||||
pm.Serial = binary.LittleEndian.Uint64(p)
|
||||
p = p[8:]
|
||||
mid.Time = binary.LittleEndian.Uint64(p)
|
||||
pm.Time = binary.LittleEndian.Uint64(p)
|
||||
p = p[8:]
|
||||
mid.ID = binary.LittleEndian.Uint64(p)
|
||||
pm.ID = binary.LittleEndian.Uint64(p)
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalText strictly decodes data into mid.
|
||||
func (mid *M) UnmarshalText(data []byte) error {
|
||||
if len(data) != EncodedSizeMember {
|
||||
return &UnexpectedSizeError{data, EncodedSizeMember}
|
||||
}
|
||||
if err := mid.PartM.UnmarshalText(
|
||||
data[:EncodedSizeMember-EncodedSizeSystem],
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
return mid.System.UnmarshalText(data[EncodedSizeMember-EncodedSizeSystem:])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user