1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20
21-define(DEFAULT_MIN_NO_SLOTS, 256).
22-define(DEFAULT_MAX_NO_SLOTS, 32*1024*1024).
23-define(DEFAULT_AUTOSAVE, 3). % minutes
24-define(DEFAULT_CACHE, {3000, 14000}). % cache_parms()
25
26%% Type.
27-define(SET, 1).
28-define(BAG, 2).
29-define(DUPLICATE_BAG, 3).
30
31-define(MAGIC, 16#0abcdef).   % dets cookie, won't ever change.
32%% Status values.
33-define(FREE, 16#3abcdef).
34-define(ACTIVE, 16#12345678).
35
36-define(FILE_FORMAT_VERSION_POS, 16).
37
38-define(CHUNK_SIZE, 8192).
39
40-define(SERVER_NAME, dets).
41
42-define(POW(X), (1 bsl (X))).
43
44%% REM2(A,B) = A rem B, if B is a power of 2.
45-define(REM2(A, B), ((A) band ((B)-1))).
46
47-define(DETS_CALL(Pid, Req), {'$dets_call', Pid, Req}).
48
49-type access()      :: 'read' | 'read_write'.
50-type auto_save()   :: 'infinity' | non_neg_integer().
51-type hash_bif()    :: 'phash' | 'phash2'.
52-type keypos()      :: pos_integer().
53-type no_colls()    :: [{LogSize :: non_neg_integer(),
54                         NoCollections :: non_neg_integer()}].
55-type no_slots()    :: 'default' | non_neg_integer().
56-type tab_name()    :: term().
57-type type()        :: 'bag' | 'duplicate_bag' | 'set'.
58-type update_mode() :: 'dirty'
59                     | 'new_dirty'
60                     | 'saved'
61                     | {'error', Reason :: term()}.
62
63%% Record holding the file header and more.
64-record(head,  {
65	  m :: non_neg_integer(),    % size
66	  m2 :: non_neg_integer(),   % m * 2
67	  next :: non_neg_integer(), % next position for growth
68                                     % (segm mgmt only)
69	  fptr :: file:fd(),         % the file descriptor
70	  no_objects :: non_neg_integer() , % number of objects in table,
71	  no_keys :: non_neg_integer(),     % number of keys
72	  maxobjsize :: 'undefined' | non_neg_integer(), % 2-log of
73                           % the size of the biggest object collection
74	  n,               % split indicator
75	  type :: type(),
76	  keypos :: keypos(), % default is 1 as for ets
77	  freelists :: 'undefined'
78                     | tuple(), % tuple of free lists of buddies
79	                        % if fixed =/= false, then a pair of freelists
80	  freelists_p :: 'undefined'
81                       | non_neg_integer(),  % cached FreelistsPointer
82	  no_collections :: 'undefined'
83                          | no_colls(), % number of object collections
84                                        % per size (version 9(b))
85	  auto_save :: auto_save(),
86	  update_mode :: update_mode(),
87	  fixed = false :: 'false'
88                         | {{integer(), integer()}, % time of first fix,
89                            [{pid(),   % and number of fixes per process
90                              non_neg_integer()}]},
91	  hash_bif :: hash_bif(),  % hash bif used for this file
92          has_md5 :: boolean(),    % whether the header has
93                                   % an MD5 sum (version 9(c))
94	  min_no_slots :: no_slots(),  % minimum number of slots
95	  max_no_slots :: no_slots(),  % maximum number of slots
96	  cache :: 'undefined' | cache(), % Write cache.
97
98	  filename :: file:name(), % name of the file being used
99	  access = read_write :: access(),
100	  ram_file = false :: boolean(),
101	  name :: tab_name(),      % the name of the table
102
103	  parent :: 'undefined' | pid(), % The supervisor of Dets processes.
104	  server :: 'undefined' | pid(), % The creator of Dets processes.
105
106          bump :: non_neg_integer(),
107          base :: non_neg_integer()
108
109	 }).
110
111%% Info extracted from the file header.
112-record(fileheader, {
113	  freelist :: non_neg_integer(),
114          fl_base :: non_neg_integer(),
115	  cookie :: non_neg_integer(),
116	  closed_properly :: non_neg_integer(),
117	  type :: 'badtype' | type(),
118	  version :: non_neg_integer(),
119	  m :: non_neg_integer(),
120	  next :: non_neg_integer(),
121	  keypos :: keypos(),
122	  no_objects :: non_neg_integer(),
123	  no_keys :: non_neg_integer(),
124	  min_no_slots :: non_neg_integer(),
125	  max_no_slots :: non_neg_integer(),
126	  no_colls :: 'undefined' | no_colls(),
127	  hash_method :: non_neg_integer(),
128          read_md5 :: binary(),
129          has_md5 :: boolean(),
130          md5 :: binary(),
131	  trailer :: non_neg_integer(),
132	  eof :: non_neg_integer(),
133	  n
134	}).
135
136-type delay() :: non_neg_integer().
137-type threshold() :: non_neg_integer().
138-type cache_parms() ::
139        {Delay :: delay(), % max time items are kept in RAM only,
140                           % in milliseconds
141         Size :: threshold()}. % threshold size of cache, in bytes
142
143%% Write Cache.
144-record(cache, {
145	 cache :: % write cache, last item first
146                 [{Key :: term(),
147                   {Seq :: non_neg_integer(), Item :: term()}}],
148         csize :: non_neg_integer(), % current size of the cached items
149         inserts :: % upper limit on number of inserted keys
150                    non_neg_integer(),
151	 wrtime :: 'undefined' | integer(),  % last write or update time
152	 tsize :: threshold(), % threshold size of cache
153	 delay :: delay()      % max time items are kept in RAM only
154	 }).
155
156-type cache() :: #cache{}.
157