1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 1997-2017. 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(DISK_LOG_NAME_TABLE, disk_log_names). 22-define(DISK_LOG_PID_TABLE, disk_log_pids). 23 24%% File format version 25-define(VERSION, 2). 26 27%% HEADSZ is the size of the file header, 28%% HEADERSZ is the size of the item header ( = ?SIZESZ + ?MAGICSZ). 29-define(HEADSZ, 8). 30-define(SIZESZ, 4). 31-define(MAGICSZ, 4). 32-define(HEADERSZ, 8). 33-define(MAGICHEAD, <<12,33,44,55>>). 34-define(MAGICINT, 203500599). %% ?MAGICHEAD = <<?MAGICINT:32>> 35-define(BIGMAGICHEAD, <<98,87,76,65>>). 36-define(BIGMAGICINT, 1649888321). %% ?BIGMAGICHEAD = <<?BIGMAGICINT:32>> 37-define(MIN_MD5_TERM, 65528).% (?MAX_CHUNK_SIZE - ?HEADERSZ) 38 39-define(MAX_FILES, 65000). 40-define(MAX_BYTES, ((1 bsl 64) - 1)). 41-define(MAX_CHUNK_SIZE, 65536). 42-define(MAX_FWRITE_CACHE, 65536). 43 44%% Object defines 45-define(LOGMAGIC, <<1,2,3,4>>). 46-define(OPENED, <<6,7,8,9>>). 47-define(CLOSED, <<99,88,77,11>>). 48 49%% Needed for the definition of #file_info{} 50%% Must use include_lib() so that we always can be sure to find 51%% file.hrl. A relative path will not work in an installed system. 52-include_lib("kernel/include/file.hrl"). 53 54%%------------------------------------------------------------------------ 55%% Types -- alphabetically 56%%------------------------------------------------------------------------ 57 58-type dlog_format() :: 'external' | 'internal'. 59-type dlog_format_type() :: 'halt_ext' | 'halt_int' | 'wrap_ext' | 'wrap_int'. 60-type dlog_head() :: 'none' | {'ok', binary()} | mfa(). 61-type dlog_head_opt() :: none | term() | iodata(). 62-type log() :: term(). % XXX: refine 63-type dlog_mode() :: 'read_only' | 'read_write'. 64-type dlog_name() :: atom() | string(). 65-type dlog_optattr() :: 'name' | 'file' | 'linkto' | 'repair' | 'type' 66 | 'format' | 'size' | 'distributed' | 'notify' 67 | 'head' | 'head_func' | 'mode'. 68-type dlog_option() :: {name, Log :: log()} 69 | {file, FileName :: file:filename()} 70 | {linkto, LinkTo :: none | pid()} 71 | {repair, Repair :: true | false | truncate} 72 | {type, Type :: dlog_type()} 73 | {format, Format :: dlog_format()} 74 | {size, Size :: dlog_size()} 75 | {distributed, Nodes :: [node()]} 76 | {notify, boolean()} 77 | {head, Head :: dlog_head_opt()} 78 | {head_func, MFA :: {atom(), atom(), list()}} 79 | {quiet, boolean()} 80 | {mode, Mode :: dlog_mode()}. 81-type dlog_options() :: [dlog_option()]. 82-type dlog_repair() :: 'truncate' | boolean(). 83-type dlog_size() :: 'infinity' | pos_integer() 84 | {MaxNoBytes :: pos_integer(), 85 MaxNoFiles :: pos_integer()}. 86-type dlog_status() :: 'ok' | {'blocked', 'false' | [_]}. %QueueLogRecords 87-type dlog_type() :: 'halt' | 'wrap'. 88 89%%------------------------------------------------------------------------ 90%% Records 91%%------------------------------------------------------------------------ 92 93%% record of args for open 94-record(arg, {name = 0, 95 version = undefined, 96 file = none :: 'none' | file:filename(), 97 repair = true :: dlog_repair(), 98 size = infinity :: dlog_size(), 99 type = halt :: dlog_type(), 100 distributed = false :: 'false' | {'true', [node()]}, 101 format = internal :: dlog_format(), 102 linkto = self() :: 'none' | pid(), 103 head = none, 104 mode = read_write :: dlog_mode(), 105 notify = false :: boolean(), 106 quiet = false :: boolean(), 107 options = [] :: dlog_options()}). 108 109-record(cache, %% Cache for logged terms (per file descriptor). 110 {fd :: file:fd(), %% File descriptor. 111 sz = 0 :: non_neg_integer(), %% Number of bytes in the cache. 112 c = [] :: iodata()} %% The cache. 113 ). 114 115-record(halt, %% For a halt log. 116 {fdc :: #cache{}, %% A cache record. 117 curB :: non_neg_integer(), %% Number of bytes on the file. 118 size :: dlog_size()} 119 ). 120 121-record(handle, %% For a wrap log. 122 {filename :: file:filename(), %% Same as log.filename 123 maxB :: pos_integer(), %% Max size of the files. 124 maxF :: pos_integer() | {pos_integer(),pos_integer()}, 125 %% When pos_integer(), maximum number of files. 126 %% The form {NewMaxF, OldMaxF} is used when the 127 %% number of wrap logs are decreased. The files 128 %% are not removed when the size is changed but 129 %% next time the files are to be used, i.e next 130 %% time the wrap log has filled the 131 %% Dir/Name.NewMaxF file. 132 curB :: non_neg_integer(), %% Number of bytes on current file. 133 curF :: integer(), %% Current file number. 134 cur_fdc :: #cache{}, %% Current file descriptor. 135 cur_name :: file:filename(), %% Current file name for error reports. 136 cur_cnt :: non_neg_integer(), %% Number of items on current file, 137 %% header inclusive. 138 acc_cnt :: non_neg_integer(), %% acc_cnt+cur_cnt is number of items 139 %% written since the log was opened. 140 firstPos :: non_neg_integer(), %% Start position for first item 141 %% (after header). 142 noFull :: non_neg_integer(), %% Number of overflows since last 143 %% use of info/1 on this log, or 144 %% since log was opened if info/1 145 %% has not yet been used on this log. 146 accFull :: non_neg_integer()} %% noFull+accFull is number of 147 %% oveflows since the log was opened. 148 ). 149 150-record(log, 151 {status = ok :: dlog_status(), 152 name :: dlog_name(), %% the key leading to this structure 153 blocked_by = none :: 'none' | pid(), %% pid of blocker 154 users = 0 :: non_neg_integer(), %% non-linked users 155 filename :: file:filename(), %% real name of the file 156 owners = [] :: [{pid(), boolean()}],%% [{pid, notify}] 157 type :: dlog_type(), 158 format :: dlog_format(), 159 format_type :: dlog_format_type(), 160 head = none, %% none | {head, H} | {M,F,A} 161 %% called when wraplog wraps 162 mode :: dlog_mode(), 163 size, %% value of open/1 option 'size' (never changed) 164 extra :: #halt{} | #handle{}, %% type of the log 165 version :: integer()} %% if wrap log file 166 ). 167 168-record(continuation, %% Chunk continuation. 169 {pid = self() :: pid(), 170 pos :: non_neg_integer() | {integer(), non_neg_integer()}, 171 b :: binary() | [] | pos_integer()} 172 ). 173 174-type dlog_cont() :: 'start' | #continuation{}. 175