Class: RedisInt64Autoincrement
- Inherits:
-
Object
- Object
- RedisInt64Autoincrement
- Defined in:
- lib/redis_int64_autoincrement.rb
Defined Under Namespace
Modules: Version
Constant Summary collapse
- REDIS_KEY_TTL_SECONDS =
Why 50 seconds? Easy to debug and more than enouth for sync time delta shift. You can use 10 or 5 seconds - and all must working normal too. 50seconds was chosen by me without any explanation. Just took this value, i do not know why.
50- MAX_BUFFER_BITS_CNT =
Do not use all 64 bits - in this case signed Int64 can be less than result uid
63- TIMESTAMP_BITS_CNT =
34bits for 150+ years more than enougth
34.freeze
- TIMESTAMP_MICROSECONDS_BITS_CNT =
0..999_999 - require 20bits
20.freeze
- INCREMENTED_ID_BITS_CNT =
7bits for 0..127 INCREMENTED_UINT8_ID
7.freeze
- SERVER_ID_BITS_CNT =
2.freeze
- TIMESTAMP_SECONDS_SHIFT_LEFT_CNT =
So in result: 34 + 20 + 7 + 2 = 63bits(MAX_BUFFER_BITS_CNT).
(TIMESTAMP_MICROSECONDS_BITS_CNT + INCREMENTED_ID_BITS_CNT + SERVER_ID_BITS_CNT).freeze
- TIMESTAMP_MICROSECONDS_SHIFT_LEFT_CNT =
9 bits
(INCREMENTED_ID_BITS_CNT + SERVER_ID_BITS_CNT).freeze
- INCREMENTED_ID_MAX_VAL =
1111111b=127
((1 << INCREMENTED_ID_BITS_CNT) - 1).freeze
- UINT63_MAX_VAL =
2^63 = 9223372036854775808
9223372036854775808- LIB_FIRST_VAL =
First id was generated 23.12.2023 at ~17:30 (Kiev +2:00)
914476352027817480- VERSION =
Version::STRING
Class Method Summary collapse
Class Method Details
.generate(redis, namespace = 'default', options = {}) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/redis_int64_autoincrement.rb', line 33 def generate(redis, namespace = 'default', = {}) server_id = [:server_id] || 0 time_redis = [:time_redis] || redis raise("Wrong server_id[#{server_id}]. Allow only 0..3 server_id") unless server_id.between?(0, 3) time_arr = time_redis.time raise("Wrong time type[#{time_arr.inspect}]") unless time_arr.count.eql?(2) unix_seconds = time_arr.first.to_i first_part = unix_seconds << TIMESTAMP_SECONDS_SHIFT_LEFT_CNT microseconds = time_arr[1].to_i raise("Wrong microseconds [#{microseconds}]") unless microseconds.between?(0, 999_999) second_part = microseconds << TIMESTAMP_MICROSECONDS_SHIFT_LEFT_CNT key = "ai64:#{namespace}:#{unix_seconds}:#{microseconds}" incremented_val = redis.incrby(key, 1) redis.expire(key, REDIS_KEY_TTL_SECONDS) raise("Wrong incremented_val [#{incremented_val}]") unless incremented_val.between?(0, INCREMENTED_ID_MAX_VAL) third_part = incremented_val << SERVER_ID_BITS_CNT result = ((first_part | second_part) | third_part) | server_id raise("Wrong result[#{result}]") unless result.between?(LIB_FIRST_VAL, UINT63_MAX_VAL) result end |