Class: Tina4::DocStore::ObjectId

Inherits:
Object
  • Object
show all
Defined in:
lib/tina4/docstore.rb

Overview

A 12-byte MongoDB-style ObjectId, with no external dependency.

Layout: 4-byte big-endian seconds since epoch, 5-byte per-process random, 3-byte big-endian counter. Renders as a 24-char hex string, so it is interchangeable with a Mongo ObjectId wherever the string form is used.

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(oid = nil) ⇒ ObjectId

Returns a new instance of ObjectId.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/tina4/docstore.rb', line 87

def initialize(oid = nil)
  case oid
  when nil
    @bytes = generate
  when ObjectId
    @bytes = oid.bytes
  when String
    if oid.bytesize == 12 && oid.encoding == Encoding::ASCII_8BIT && !oid.match?(OID_RE)
      @bytes = oid.dup
    elsif oid.match?(OID_RE)
      @bytes = [oid].pack("H*")
    else
      raise InvalidId, "#{oid.inspect} is not a valid 24-character hex ObjectId"
    end
  else
    raise InvalidId, "cannot make an ObjectId from #{oid.class}"
  end
end

Class Attribute Details

.lockObject (readonly)

Returns the value of attribute lock.



69
70
71
# File 'lib/tina4/docstore.rb', line 69

def lock
  @lock
end

Instance Attribute Details

#bytesObject (readonly)

Returns the value of attribute bytes.



85
86
87
# File 'lib/tina4/docstore.rb', line 85

def bytes
  @bytes
end

Class Method Details

.next_counterObject



71
72
73
# File 'lib/tina4/docstore.rb', line 71

def next_counter
  @lock.synchronize { @counter = (@counter + 1) & 0xFFFFFF }
end

.process_bytesObject



75
# File 'lib/tina4/docstore.rb', line 75

def process_bytes = @process

.valid?(value) ⇒ Boolean

Returns:

  • (Boolean)


77
78
79
80
81
82
# File 'lib/tina4/docstore.rb', line 77

def valid?(value)
  new(value)
  true
rescue InvalidId, TypeError
  false
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?



122
123
124
# File 'lib/tina4/docstore.rb', line 122

def ==(other)
  other.is_a?(ObjectId) && other.bytes == @bytes
end

#generateObject

4-byte time + 5-byte random + 3-byte counter.



107
108
109
110
111
# File 'lib/tina4/docstore.rb', line 107

def generate
  ts = [Time.now.to_i].pack("N")               # 4-byte big-endian
  counter = [self.class.next_counter].pack("N")[1, 3]  # low 3 bytes big-endian
  ts + self.class.process_bytes + counter
end

#generation_timeObject



113
114
115
116
# File 'lib/tina4/docstore.rb', line 113

def generation_time
  ts = @bytes[0, 4].unpack1("N")
  Time.at(ts).utc
end

#hashObject



127
# File 'lib/tina4/docstore.rb', line 127

def hash = @bytes.hash

#inspectObject



120
# File 'lib/tina4/docstore.rb', line 120

def inspect = "ObjectId('#{self}')"

#to_sObject



118
# File 'lib/tina4/docstore.rb', line 118

def to_s = @bytes.unpack1("H*")