diff --git a/doc/uuid.md b/doc/uuid.md new file mode 100644 index 000000000..5b7bd0aa0 --- /dev/null +++ b/doc/uuid.md @@ -0,0 +1,19 @@ +## Mongodb ObjectId + +* 4-byte value representing the seconds since the Unix epoch, +* 3-byte machine identifier, +* 2-byte process id, and +* 3-byte counter, starting with a random value. + +## Flake Id + +* 64bits Timestamp +* 48bits WorkerId +* 16bits Sequence + +## emqttd Id + +* 64bits Timestamp: erlang:now(), erlang:system_time +* 48bits (node+pid): Node + Pid -> Integer +* 16bits Sequence: PktId + diff --git a/src/emqttd_guid.erl b/src/emqttd_guid.erl new file mode 100644 index 000000000..ffdf4c646 --- /dev/null +++ b/src/emqttd_guid.erl @@ -0,0 +1,126 @@ +%%%----------------------------------------------------------------------------- +%%% Copyright (c) 2012-2015 eMQTT.IO, All Rights Reserved. +%%% +%%% Permission is hereby granted, free of charge, to any person obtaining a copy +%%% of this software and associated documentation files (the "Software"), to deal +%%% in the Software without restriction, including without limitation the rights +%%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +%%% copies of the Software, and to permit persons to whom the Software is +%%% furnished to do so, subject to the following conditions: +%%% +%%% The above copyright notice and this permission notice shall be included in all +%%% copies or substantial portions of the Software. +%%% +%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +%%% SOFTWARE. +%%%----------------------------------------------------------------------------- +%%% @doc +%%% +%%% Generate global unique id for mqtt message. +%%% +%%% -------------------------------------------------------- +%%% | Timestamp | NodeID + PID | Sequence | +%%% |<------- 64bits ------->|<--- 48bits --->|<- 16bits ->| +%%% -------------------------------------------------------- +%%% +%%% 1. Timestamp: erlang:system_time if Erlang >= R18, otherwise os:timestamp +%%% 2. NodeId: encode node() to 2 bytes integer +%%% 3. Pid: encode pid to 4 bytes integer +%%% 4. Sequence: 2 bytes sequence no per pid +%%% +%%% @end +%%%----------------------------------------------------------------------------- + +-module(emqttd_guid). + +-export([gen/0]). + +-define(MAX_SEQ, 16#FFFF). + +-type guid() :: <<_:128>>. + +-spec gen() -> guid(). +gen() -> + Guid = case get(guid) of + undefined -> new(); + {_Ts, NPid, Seq} -> next(NPid, Seq) + end, + put(guid, Guid), enc(Guid). + +new() -> + {ts(), npid(), 0}. + +next(NPid, Seq) when Seq >= ?MAX_SEQ -> + {ts(), NPid, 0}; +next(NPid, Seq) -> + {ts(), NPid, Seq + 1}. + +enc({Ts, NPid, Seq}) -> + <>. + +ts() -> + case erlang:function_exported(erlang, system_time, 1) of + true -> %% R18 + erlang:system_time(micro_seconds); + false -> + {MegaSeconds, Seconds, MicroSeconds} = erlang:now(), + (MegaSeconds * 1000000 + Seconds) * 1000000 + MicroSeconds + end. + +%% code copied from https://github.com/okeuday/uuid.git. +npid() -> + <> = + crypto:hash(sha, erlang:list_to_binary(erlang:atom_to_list(node()))), + + % later, when the pid format changes, handle the different format + ExternalTermFormatVersion = 131, + PidExtType = 103, + <> = erlang:term_to_binary(self()), + % 72 bits for the Erlang pid + <> = binary:part(PidBin, erlang:byte_size(PidBin), -9), + + % reduce the 160 bit NodeData checksum to 16 bits + NodeByte1 = ((((((((NodeD01 bxor NodeD02) + bxor NodeD03) + bxor NodeD04) + bxor NodeD05) + bxor NodeD06) + bxor NodeD07) + bxor NodeD08) + bxor NodeD09) + bxor NodeD10, + NodeByte2 = (((((((((NodeD11 bxor NodeD12) + bxor NodeD13) + bxor NodeD14) + bxor NodeD15) + bxor NodeD16) + bxor NodeD17) + bxor NodeD18) + bxor NodeD19) + bxor NodeD20) + bxor PidCR1, + + % reduce the Erlang pid to 32 bits + PidByte1 = PidID1 bxor PidSR4, + PidByte2 = PidID2 bxor PidSR3, + PidByte3 = PidID3 bxor PidSR2, + PidByte4 = PidID4 bxor PidSR1, + + <> = <>, + NPid. + diff --git a/src/emqttd_msg_store.erl b/src/emqttd_retained.erl similarity index 100% rename from src/emqttd_msg_store.erl rename to src/emqttd_retained.erl