%%%------------------------------------------------------------------- %%% File : bbsOid.erl %%% Author : Ulf Wiger %%% Description : %%% %%% Created : 8 Mar 2006 by Ulf Wiger %%%------------------------------------------------------------------- -module(bbsOid). -export([new/0, incr_vsn/1, add_branch/2, add_peer_node/1]). -define(MAX_SEQ, 16#ffffFFFF) new() -> MyNode = node(), NodeId = mnesia:read_table_property(schema, {bbs_node_id,MyNode}), case mnesia:dirty_update_counter(bbsOid, MyNode, 1) of NodeSeq when NodeSeq > ?MAX_SEQ -> NewNodeId = set_new_node_id(MyNode), mnesia:dirty_write({bbsOid, MyNode, 1}), {NewNodeId, 1, initial_vsn()}; NodeSeq -> {NodeId, NodeSeq, initial_vsn()} end. initial_vsn() -> [1]. %%% versions have the structure Branches ++ [integer()], %%% where Branches :: list(binary()). incr_vsn({NId,NSeq,V}) -> [I|RevT] = lists:reverse(V), NewV = lists:reverse([I+1|RevT]), {NId, NSeq, NewV}. add_peer_node(Node) -> mnesia_schema:schema_transaction( fun() -> case is_peer_node(Node) of true -> mnesia:abort({peer_node_exists, Node}); false -> do_set_new_node_id(Node) end end). set_new_node_id(Node) -> mnesia_schema:schema_transaction( fun() -> case is_peer_node(Node) of true -> do_set_new_node_id(Node); false -> mnesia:abort({not_a_peer_node, Node}) end end). do_set_new_node_id(Node) -> PeerNodes = read_property(bbs_peer_nodes, ordsets:new()), OldCtr = read_property(bbs_node_id_ctr, 0), NewCtr = OldCtr + 1, write_property({bbs_node_id_ctr, NewCtr}), write_property({{bbs_node_id, Node}, NewCtr}), write_property({bbs_peer_nodes, ordsets:add_element(Node, PeerNodes)}), NewCtr. read_property(P, Default) -> case mnesia_schema:do_read_table_property( schema, P) of undefined -> Default; Value -> Value end. is_peer_node(Node) -> Peers = read_property(bbs_peer_nodes, ordsets:new()), ordsets:is_element(Node, Peers). write_property(P, Value) -> mnesia_schema:do_write_table_property(schema, {P, Value}).