1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- This document was generated using DocBuilder 3.3.3 -->
<HTML>
<HEAD>
<TITLE>Appendix D: The Fragmented Table Hashing Call Back Interface</TITLE>
<SCRIPT type="text/javascript" src="../../../../doc/erlresolvelinks.js">
</SCRIPT>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#FF00FF"
ALINK="#FF0000">
<CENTER>
<A HREF="http://www.erlang.se"><IMG BORDER=0 ALT="[Ericsson AB]" SRC="min_head.gif"></A>
</CENTER>
<A NAME="11"><!-- Empty --></A>
<H2>11 Appendix D: The Fragmented Table Hashing Call Back Interface</H2>
<A NAME="11.1"><!-- Empty --></A>
<H3>11.1 mnesia_frag_hash callback behavior</H3>
<P>
<PRE>
-module(mnesia_frag_hash).
%% Fragmented Table Hashing callback functions
-export([
init_state/2,
add_frag/1,
del_frag/1,
key_to_frag_number/2,
match_spec_to_frag_numbers/2
]).
</PRE>
<P>
<PRE>
-record(hash_state, {n_fragments, next_n_to_split, n_doubles}).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
init_state(_Tab, State) when State == undefined ->
#hash_state{n_fragments = 1,
next_n_to_split = 1,
n_doubles = 0}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
add_frag(State) when record(State, hash_state) ->
SplitN = State#hash_state.next_n_to_split,
P = SplitN + 1,
L = State#hash_state.n_doubles,
NewN = State#hash_state.n_fragments + 1,
State2 = case trunc(math:pow(2, L)) + 1 of
P2 when P2 == P ->
State#hash_state{n_fragments = NewN,
n_doubles = L + 1,
next_n_to_split = 1};
_ ->
State#hash_state{n_fragments = NewN,
next_n_to_split = P}
end,
{State2, [SplitN], [NewN]}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
del_frag(State) when record(State, hash_state) ->
P = State#hash_state.next_n_to_split - 1,
L = State#hash_state.n_doubles,
N = State#hash_state.n_fragments,
if
P < 1 ->
L2 = L - 1,
MergeN = trunc(math:pow(2, L2)),
State2 = State#hash_state{n_fragments = N - 1,
next_n_to_split = MergeN,
n_doubles = L2},
{State2, [N], [MergeN]};
true ->
MergeN = P,
State2 = State#hash_state{n_fragments = N - 1,
next_n_to_split = MergeN},
{State2, [N], [MergeN]}
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
key_to_frag_number(State, Key) when record(State, hash_state) ->
L = State#hash_state.n_doubles,
A = erlang:phash(Key, trunc(math:pow(2, L))),
P = State#hash_state.next_n_to_split,
if
A < P ->
erlang:phash(Key, trunc(math:pow(2, L + 1)));
true ->
A
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
match_spec_to_frag_numbers(State, MatchSpec) when record(State, hash_state) ->
case MatchSpec of
[{HeadPat, _, _}] when tuple(HeadPat), size(HeadPat) > 2 ->
KeyPat = element(2, HeadPat),
case has_var(KeyPat) of
false ->
[key_to_frag_number(State, KeyPat)];
true ->
lists:seq(1, State#hash_state.n_fragments)
end;
_ ->
lists:seq(1, State#hash_state.n_fragments)
end.
</PRE>
<CENTER>
<HR>
<SMALL>
Copyright © 1991-2006
<A HREF="http://www.erlang.se">Ericsson AB</A><BR>
</SMALL>
</CENTER>
</BODY>
</HTML>
|