onliest 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data/bin/onliest +5 -0
- data/lib/onliest.rb +46 -0
- data/test/test_onliest.rb +46 -0
- data.tar.gz.sig +4 -0
- metadata +71 -0
- metadata.gz.sig +2 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 231435f376731f8c8e9ea57de9c5fa72c93584f6
|
4
|
+
data.tar.gz: fae174999ac03c89d9847efc9f26687cd1b9336a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 75b616b372f8431dbbebd7395fefb3c0ab8737672568f931585cb25e0d2ff7973d23ccd1cfb5d8610a9868bb80d107dc197d5a756d8a95189ab1784aee0c7b9d
|
7
|
+
data.tar.gz: 7a55e1ee34960ce44e98dc0ce63c00a9cfd03462dd8b96b9c68ad1de3dede8da9619c6392acd92fd2d88a5eeaa11e4251826d032bb7acf0f09a08ccc018e6ffa
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data/bin/onliest
ADDED
data/lib/onliest.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
# Onliest generates unique numbers for use as database keys in
|
4
|
+
# distributed applications. The values are composed of the rightmost
|
5
|
+
# 25 bits of a POSIX timestamp and 47 random bits.
|
6
|
+
|
7
|
+
# It uses the method described by Zack Bloom
|
8
|
+
# (https://eager.io/blog/how-long-does-an-id-need-to-be/).
|
9
|
+
class Onliest
|
10
|
+
RANDOM_BITS = 47
|
11
|
+
TIME_BITS = 25
|
12
|
+
RANDOM_BITMASK = (2**RANDOM_BITS) - 1
|
13
|
+
TIME_BITMASK = (2**TIME_BITS) - 1
|
14
|
+
|
15
|
+
DEFAULT_RNG = SecureRandom
|
16
|
+
|
17
|
+
# Return a new unique value, using the default random number
|
18
|
+
# generator
|
19
|
+
def self.value
|
20
|
+
new.value
|
21
|
+
end
|
22
|
+
|
23
|
+
# Create a new unique value generator. +rng+ defaults to
|
24
|
+
# +SecureRandom+. An object that implements +:random_number+
|
25
|
+
# returning a random integer >= 0 and less than value provided as
|
26
|
+
# the first argument.
|
27
|
+
def initialize(rng = DEFAULT_RNG)
|
28
|
+
@rng = rng
|
29
|
+
end
|
30
|
+
|
31
|
+
# Return the unique 72-bit value
|
32
|
+
def value
|
33
|
+
(some_time_bits << RANDOM_BITS) +
|
34
|
+
some_random_bits
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def some_random_bits
|
40
|
+
@rng.random_number(RANDOM_BITMASK + 1)
|
41
|
+
end
|
42
|
+
|
43
|
+
def some_time_bits
|
44
|
+
Time.now.to_i & TIME_BITMASK
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
|
3
|
+
require 'onliest'
|
4
|
+
|
5
|
+
class OnliestTest < Minitest::Unit::TestCase
|
6
|
+
def test_generates_a_number
|
7
|
+
assert_kind_of(Integer, Onliest.value)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_values_are_different
|
11
|
+
refute_equal(Onliest.value, Onliest.value)
|
12
|
+
end
|
13
|
+
|
14
|
+
def fake_prng(value = 1)
|
15
|
+
fake_prng = Minitest::Mock.new
|
16
|
+
fake_prng.expect(:random_number, value, [2**47])
|
17
|
+
end
|
18
|
+
|
19
|
+
def at(value)
|
20
|
+
Time.stub(:now, Time.at(value)) do
|
21
|
+
yield
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_with_a_time_and_a_prng
|
26
|
+
at((2**25) + 1) do
|
27
|
+
random_value = 2
|
28
|
+
gen = Onliest.new(fake_prng(random_value))
|
29
|
+
assert_equal(gen.value, (1 << 47) + random_value)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_the_littlest_onliest
|
34
|
+
at(0) do
|
35
|
+
gen = Onliest.new(fake_prng(0))
|
36
|
+
assert_equal(gen.value, 0)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_the_largest_onliest
|
41
|
+
at(2**25 - 1) do
|
42
|
+
gen = Onliest.new(fake_prng(2**47 - 1))
|
43
|
+
assert_equal(gen.value, 2**72 - 1)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data.tar.gz.sig
ADDED
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: onliest
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Robert Church
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIDaDCCAlCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA9MQ8wDQYDVQQDDAZjaHJj
|
14
|
+
aHIxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2NvbTAe
|
15
|
+
Fw0xNDExMTcwMzU0NDZaFw0xNTExMTcwMzU0NDZaMD0xDzANBgNVBAMMBmNocmNo
|
16
|
+
cjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29tMIIB
|
17
|
+
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxYcGTCEi6hbbKJf8NtH1UIGg
|
18
|
+
OFlMQjzp/QgN4IQV8wJbePzkm9Zfy0I19u/0Q+WmepkpwGLwEb84yiInpHpYKhVW
|
19
|
+
7MQOekiS+JxfGgXfAUtUZLLeeCe+R5IO9mZx+8PmA+S/WWaZngGuJE9vAi0Cobr7
|
20
|
+
dKpsSeavB/mkE0V0jGnaUc6rJeO8sB/nzOeJ9OqxgUUI4698POpGLknhq9of//Yx
|
21
|
+
51WwQul6sItx/AELZKEM/Zuu+nvMCYFU0oM0OHMYaN5EDERjLGVXAYBTyKuUq0js
|
22
|
+
kAydz6hfkrTBw8Aa/2s7w12EFq5jTBPS8fhvTFdGbveoF8HZuYV0PNEnSbhRpQID
|
23
|
+
AQABo3MwcTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUQT0zqrtG
|
24
|
+
cFXJ2o4qWOe8Rq2FsEEwGwYDVR0RBBQwEoEQY2hyY2hyQGdtYWlsLmNvbTAbBgNV
|
25
|
+
HRIEFDASgRBjaHJjaHJAZ21haWwuY29tMA0GCSqGSIb3DQEBBQUAA4IBAQBRdlDl
|
26
|
+
dXzKVcuK/w1EwgfPlI3BVMbSBGx9evofmH8pSWOV7Pqu3ZU9u91SGzMtMULVj+03
|
27
|
+
SJRx2pS3sVfzTt+jPfIqQk37rfc9iYLPCwM5G5RypT3iAIM/V/rJv5+z9lYwE/76
|
28
|
+
8ZrYVUK9zx91u/xkFseEig5ZqCCZIiBGKleos2uruy+eG5On1w5ShGqIaoxQvCa0
|
29
|
+
W6y4KVKgJJKunt/R+DNGrFnPFkd+gzWOyinOhQoVeHvyhslkA+ptgJSk2Q/KwTXO
|
30
|
+
3TLzfUddZ0/HMBNYO9OALcF70YnWb/usnr4lwVfhbJ+fcejAsp5Seurmhw7FeMoZ
|
31
|
+
f4Rtc1iUIHYWfDpz
|
32
|
+
-----END CERTIFICATE-----
|
33
|
+
date: 2014-11-15 00:00:00.000000000 Z
|
34
|
+
dependencies: []
|
35
|
+
description: Generate unique values with numeric locality.
|
36
|
+
email: chrchr@gmail.com
|
37
|
+
executables:
|
38
|
+
- onliest
|
39
|
+
extensions: []
|
40
|
+
extra_rdoc_files: []
|
41
|
+
files:
|
42
|
+
- lib/onliest.rb
|
43
|
+
- bin/onliest
|
44
|
+
- test/test_onliest.rb
|
45
|
+
homepage: https://github.com/chrchr/onliest
|
46
|
+
licenses:
|
47
|
+
- MIT
|
48
|
+
metadata: {}
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - '>='
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
requirements: []
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 2.0.14
|
66
|
+
signing_key:
|
67
|
+
specification_version: 4
|
68
|
+
summary: 'Onliest: generate unique values with numeric locality'
|
69
|
+
test_files:
|
70
|
+
- test/test_onliest.rb
|
71
|
+
has_rdoc:
|
metadata.gz.sig
ADDED