class Riak::Stamp
Implements a client-side form of monotonically-increasing k-sorted unique identifiers. These are useful for key generation if your data is time-sequential and needs to be sorted by key, perhaps in Riak
Search
. Inspired by Twitter’s Snowflake project.
Constants
- CLIENT_ID_MASK
- SEQUENCE_MASK
- SEQUENCE_SHIFT
- TIMESTAMP_MASK
- TIMESTAMP_SHIFT
Attributes
client[R]
Public Class Methods
new(client)
click to toggle source
@param [Client] client a {Riak::Client} which will be used for
the "worker ID" component of the stamp.
@see Client#stamp
# File lib/riak/stamp.rb, line 22 def initialize(client) @client = client @mutex = Mutex.new @timestamp = time_gen @sequence = 0 end
Public Instance Methods
next()
click to toggle source
Generates a k-sorted unique ID for use as a key or other disambiguation purposes.
# File lib/riak/stamp.rb, line 31 def next @mutex.synchronize do now = time_gen if @timestamp == now @sequence = (@sequence + 1) & SEQUENCE_MASK now = wait_for_next_ms(@timestamp) if @sequence == 0 else @sequence = 0 end raise BackwardsClockError.new(@timestamp - now) if now < @timestamp @timestamp = now @timestamp << TIMESTAMP_SHIFT | @sequence << SEQUENCE_SHIFT | client_id end end
Private Instance Methods
client_id()
click to toggle source
# File lib/riak/stamp.rb, line 49 def client_id case id = @client.client_id when Integer id & CLIENT_ID_MASK else id.hash & CLIENT_ID_MASK end end
time_gen()
click to toggle source
# File lib/riak/stamp.rb, line 58 def time_gen (Time.now.to_f * 1000).floor & TIMESTAMP_MASK end
wait_for_next_ms(start)
click to toggle source
# File lib/riak/stamp.rb, line 62 def wait_for_next_ms(start) now = time_gen now = time_gen while now <= start now end