Class: ClusterId::V1::Value

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/clusterid/v1/value.rb

Overview

A ClusterId version 1 format value.

A Value contains the following accessible properties:

  • a 64-bit millisecond timestamp as a DateTime

  • a 3-bit version number

  • a 3-bit data centre identifier

  • a 2-bit environment identifier

  • a 16-bit type identifier

  • a 40-bit random nonce

It also provides access to the underlying bytes.

Instances of Value are Comparable based on the timestamp.

Random Nonce

A 5 byte random nonce supports generating approximately 150,000 values before reaching a 1% chance of collision. This applies to each millisecond.

Data Layout

The byte layout of a version 1 value in little-endian is:

o-------------------------------------------------------------------------------o
| byte 01 | byte 02 | byte 03 | byte 04 | byte 05 | byte 06 | byte 07 | byte 08 |
|-------------------------------------------------------------------------------|
|                   random nonce                  |      type id      | details |
|-------------------------------------------------------------------------------|
| byte 09 | byte 10 | byte 11 | byte 12 | byte 13 | byte 14 | byte 15 | byte 16 |
|-------------------------------------------------------------------------------|
|                                   timestamp                                   |
o-------------------------------------------------------------------------------o

With the details byte encoding the following data:

o---------------------------------------------------------------o
| bit 8 | bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 |
|---------------------------------------------------------------|
|        version        |      data centre      |  environment  |
o---------------------------------------------------------------o

Since:

  • 1.0.0

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bytes, deserializer) ⇒ Value

Returns a new instance of Value.

Parameters:

  • bytes (String)

    the value as a byte string

  • deserializer (Deserializer)

    a Deserializer to decode custom value attributes

Raises:

Since:

  • 1.0.0



100
101
102
103
104
105
106
107
108
# File 'lib/clusterid/v1/value.rb', line 100

def initialize(bytes, deserializer)
  raise InvalidByteLengthError, bytes.length unless bytes.length == BYTE_SIZE

  version = (bytes[7].unpack1("C") & 0xe0) >> 5
  raise InvalidVersionError.new(FORMAT_VERSION, version) unless version == FORMAT_VERSION

  @bytes = bytes
  @deserializer = deserializer
end

Instance Attribute Details

#bytesString (readonly)

Returns the underlying value bytes.

Returns:

  • (String)

    the underlying value bytes

Since:

  • 1.0.0



55
56
57
# File 'lib/clusterid/v1/value.rb', line 55

def bytes
  @bytes
end

Instance Method Details

#<=>(other) ⇒ -1, ...

Compares ClusterId::V1::Value objects using #datetime

Parameters:

  • other (Value)

    the object to compare against

Returns:

  • (-1, 0, 1)

    -1 when less than other, 0 when equal to other, 1 when greater than other

Since:

  • 1.0.0



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/clusterid/v1/value.rb', line 114

def <=>(other)
  return nil if self.class != other.class

  cmp = datetime <=> other.datetime
  return cmp unless cmp.zero?

  cmp = data_centre <=> other.data_centre
  return cmp unless cmp.zero?

  cmp = environment <=> other.environment
  return cmp unless cmp.zero?

  cmp = type_id <=> other.type_id
  return cmp unless cmp.zero?

  nonce <=> other.nonce
end

#data_centreT

Returns the value's deserialized data centre.

Returns:

  • (T)

    the value's deserialized data centre

Since:

  • 1.0.0



85
86
87
88
# File 'lib/clusterid/v1/value.rb', line 85

def data_centre
  return @dc if instance_variable_defined? :@dc
  @dc = @deserializer.to_data_centre (bytes[7].unpack1("C") & 0x1c) >> 2
end

#datetimeDateTime

Returns the value's creation datetime.

Returns:

  • (DateTime)

    the value's creation datetime

Since:

  • 1.0.0



62
63
64
65
# File 'lib/clusterid/v1/value.rb', line 62

def datetime
  return @dt if instance_variable_defined? :@dt
  @dt = DateTime.strptime(bytes[8..].unpack1("Q").to_s, "%Q")
end

#environmentT

Returns the value's deserialized environment.

Returns:

  • (T)

    the value's deserialized environment

Since:

  • 1.0.0



79
80
81
82
# File 'lib/clusterid/v1/value.rb', line 79

def environment
  return @env if instance_variable_defined? :@env
  @env = @deserializer.to_environment bytes[7].unpack1("C") & 0x03
end

#nonceInteger

Returns the value's random nonce.

Returns:

  • (Integer)

    the value's random nonce

Since:

  • 1.0.0



68
69
70
71
# File 'lib/clusterid/v1/value.rb', line 68

def nonce
  return @nonce if instance_variable_defined? :@nonce
  @nonce = (bytes[0..4] + "\x00\x00\x00").unpack1("Q")
end

#type_idT

Returns the value's deserialized type ID.

Returns:

  • (T)

    the value's deserialized type ID

Since:

  • 1.0.0



91
92
93
94
# File 'lib/clusterid/v1/value.rb', line 91

def type_id
  return @tid if instance_variable_defined? :@tid
  @tid = @deserializer.to_type_id bytes[5..6].unpack1("S")
end

#versionInteger

Returns the value's version.

Returns:

  • (Integer)

    the value's version

Since:

  • 1.0.0



74
75
76
# File 'lib/clusterid/v1/value.rb', line 74

def version
  FORMAT_VERSION
end