You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.2 KiB
Lua
84 lines
2.2 KiB
Lua
local mod_name = (...):match ( "^(.*)%..-$" )
|
|
|
|
local setmetatable = setmetatable
|
|
local strbyte = string.byte
|
|
local strformat = string.format
|
|
local t_insert = table.insert
|
|
local t_concat = table.concat
|
|
|
|
local hasposix , posix = pcall ( require , "posix" )
|
|
|
|
local ll = require ( mod_name .. ".ll" )
|
|
local num_to_le_uint = ll.num_to_le_uint
|
|
local num_to_be_uint = ll.num_to_be_uint
|
|
|
|
local function _tostring(ob)
|
|
local t = {}
|
|
for i = 1 , 12 do
|
|
t_insert(t, strformat("%02x", strbyte(ob.id, i, i)))
|
|
end
|
|
return t_concat(t)
|
|
end
|
|
|
|
local function _get_ts(ob)
|
|
return ll.be_uint_to_num(ob.id, 1, 4)
|
|
end
|
|
|
|
local function _get_hostname(ob)
|
|
local t = {}
|
|
for i = 5, 7 do
|
|
t_insert(t, strformat("%02x", strbyte(ob.id, i, i)))
|
|
end
|
|
return t_concat(t)
|
|
end
|
|
|
|
local function _get_pid(ob)
|
|
return ll.be_uint_to_num(ob.id, 8, 9)
|
|
end
|
|
|
|
local function _get_inc(ob)
|
|
return ll.be_uint_to_num(ob.id, 10, 12)
|
|
end
|
|
|
|
local object_id_mt = {
|
|
__tostring = _tostring;
|
|
__eq = function ( a , b ) return a.id == b.id end ;
|
|
}
|
|
|
|
local machineid
|
|
if hasposix then
|
|
machineid = posix.uname("%n")
|
|
else
|
|
machineid = assert(io.popen("uname -n")):read("*l")
|
|
end
|
|
machineid = ngx.md5_bin(machineid):sub(1, 3)
|
|
|
|
local pid = num_to_le_uint(bit.band(ngx.worker.pid(), 0xFFFF), 2)
|
|
|
|
local inc = 0
|
|
local function generate_id ( )
|
|
inc = inc + 1
|
|
-- "A BSON ObjectID is a 12-byte value consisting of a 4-byte timestamp (seconds since epoch), a 3-byte machine id, a 2-byte process id, and a 3-byte counter. Note that the timestamp and counter fields must be stored big endian unlike the rest of BSON"
|
|
return num_to_be_uint ( os.time ( ) , 4 ) .. machineid .. pid .. num_to_be_uint ( inc , 3 )
|
|
end
|
|
|
|
local function new_object_id(str)
|
|
if str then
|
|
assert(#str == 12)
|
|
else
|
|
str = generate_id()
|
|
end
|
|
return setmetatable({id = str,
|
|
tostring = _tostring,
|
|
get_ts = _get_ts,
|
|
get_pid = _get_pid,
|
|
get_hostname = _get_hostname,
|
|
get_inc = _get_inc,
|
|
} , object_id_mt)
|
|
end
|
|
|
|
return {
|
|
new = new_object_id ;
|
|
metatable = object_id_mt ;
|
|
}
|