Line data Source code
1 : //-*- Mode: C++ -*-
2 : // $Id$
3 : #ifndef ALIHLTCORRUPTORCOMPONENT_H
4 : #define ALIHLTCORRUPTORCOMPONENT_H
5 : /* This file is property of and copyright by the ALICE HLT Project *
6 : * ALICE Experiment at CERN, All rights reserved. *
7 : * See cxx source for full Copyright notice */
8 :
9 : /// \file AliHLTCorruptorComponent.h
10 : /// \author Artur Szostak <artursz@iafrica.com>
11 : /// \date 5 Aug 2010
12 : /// \brief Declaration of the AliHLTCorruptorComponent component class.
13 :
14 : #include "AliHLTProcessor.h"
15 : #include <vector>
16 :
17 : /**
18 : * \class AliHLTCorruptorComponent
19 : * The corruptor component is used for testing purposes. It should be used to corrupt
20 : * input data meant for a normal processing component to check the stable behaviour
21 : * of such a component to data corruption.
22 : * The component will copy all input data blocks that it will corrupt to the output
23 : * and modify the data by corrupting it in some way. This includes removing parts of
24 : * the data, adding garbage to it or flipping single bits.
25 : * One can select which data block types to modify; then unmodified data blocks are
26 : * just forwarded.
27 : *
28 : * <h2>General properties:</h2>
29 : *
30 : * Component ID: \b CorruptorComponent <br>
31 : * Library: \b libAliHLTUtil.so <br>
32 : * Input Data Types: ::kAliHLTAnyDataType <br>
33 : * Output Data Types: ::kAliHLTAnyDataType <br>
34 : *
35 : * <h2>Mandatory arguments:</h2>
36 : * None.
37 : *
38 : * <h2>Optional arguments:</h2>
39 : * \li -seed <i>number</i> <br>
40 : * Sets the random number generator's seed value. The default value of zero
41 : * forces the generator to use the current time for the seed.
42 : * \li -datatype <i>id</i> <i>origin</i> <br>
43 : * Data block type ID and origin to filter on. Only blocks with this type are
44 : * modified.
45 : * \li -origin <i>origin</i> <br>
46 : * Data block origin to filter on. Only blocks with this origin are modified.
47 : * \li -typeid <i>id</i> <br>
48 : * Data block type ID to filter on. Only blocks with this type ID are modified.
49 : * \li -dataspec <i>specification</i> <br>
50 : * Data block specification to filter on. Only blocks with this specification
51 : * are modified.
52 : * \li -range <i>min</i> <i>max</i> <br>
53 : * Sets the range that the current corruption settings will be applied to.
54 : * The current corruption settings are selected with "-singleflips",
55 : * "-bursterrors", "-replace", "-insert" and "-remove".
56 : * The min/max values specify the range in bytes. One can also specify it on
57 : * the bit level with the following syntax: "\<byte\>:\<bit\>",
58 : * where \<byte\> indicates the byte position counted from zero, \<bit\>
59 : * indicates the bit position inside the byte, which can be one of [0..7].
60 : * An example of using the "-range" option: "-range 3:2 4:7". This indicates
61 : * a range of 14 bits from the 4th byte, bit 3 to the 5th byte up to and
62 : * including bit 8.
63 : * The special tags "min" and "max" can be used as placeholders for <i>min</i>
64 : * and <i>max</i> respectively. These will automatically use the minimum and
65 : * maximum size for the data block.
66 : * One can also use the syntax: "max-\<byte\>:\<bit\>", which allows to select
67 : * positions relative to the end of the block.
68 : * \li -alignment <i>value</i> <br>
69 : * Sets the alignment in bits to use for the applied errors.
70 : * For example if one wants to apply errors to locations aligned to 16 bit
71 : * words, then <i>value</i> should be 16. With the default value equal to 1.
72 : * The alignment is relative to the start of the range given by "-range".
73 : * Thus, the location <i>l</i> is calculated with:
74 : * <i>l</i> = floor((<i>r</i> - <i>m</i>) / <i>value</i>) * <i>value</i> + <i>m</i>
75 : * where <i>r</i> is a random number chosen in the current range, <i>m</i> is
76 : * the minimum bit position of the range and <i>value</i> is the alignment value.
77 : * \li -errorrate <i>rate</i> <br>
78 : * Sets the rate of errors to apply to the current range as a percentage or
79 : * fraction of the current block size. If no range has been selected then the
80 : * rate is for the whole data block by default.
81 : * \li -errorcount <i>min</i> <i>max</i> <br>
82 : * This is an alternative to "-errorrate", where a random number of errors is
83 : * generated within the range [<i>min</i>..<i>max</i>]. If <i>min</i> is set
84 : * to equal <i>max</i> then a fixed number of errors is always applied to the
85 : * current range.
86 : * \li -singleflips <br>
87 : * Generates <i>n</i> single bit errors distributed evenly within the current
88 : * data range given by "-range". <i>n</i> is determined either from the rate
89 : * given by "-errorrate" or from the range given by "-errorcount".
90 : * \li -bursterrors <i>length</i> <i>count</i> <br>
91 : * Generates burst errors in the current data range. Burst errors have <i>count</i>
92 : * number of bit flips within a <i>length</i> number of consecutive bits
93 : * closely spaced together. The total number of burst errors generated is
94 : * controlled by the "-errorrate" or "-errorcount" options.
95 : * \li -replace <i>pattern</i> [<i>pattern</i> ...] <br>
96 : * Allows one to replace parts of the data with the given pattern or consecutive
97 : * patterns. The format of <i>pattern</i> should be "\<value\>/\<width\>",
98 : * where \<value\> is a number or hexadecimal value (interpreted in little
99 : * endian format) to be used as the replacement. \<width\> is an optional
100 : * field to indicate the width of the pattern in bits. The maximum valid value
101 : * for \<width\> is 64.
102 : * A special symbol "removed" can be used for the pattern, which will cause
103 : * the command to use the bits last removed by the "-remove" command. If no
104 : * bits were removed or no previous "-remove" command was issued then nothing
105 : * is replaced.
106 : * Note that the location of the replacement is controlled by the "-range"
107 : * option. Normally the position is randomly selected within this range.
108 : * For specific placement one can use "-range x x" where x is the exact
109 : * position of the replacement. The total number of replacements is
110 : * controlled by the "-errorrate" or "-errorcount" options.
111 : * \li -replace-random <i>min</i> <i>max</i> <br>
112 : * Replaces a random number of bits within the range [<i>min</i>..<i>max</i>]
113 : * from locations selected within the current range and for a total number of
114 : * times controlled by the "-errorrate" or "-errorcount" options.
115 : * The placeholder symbols "min" and "max" can be used.
116 : * \li -insert <i>pattern</i> [<i>pattern</i> ...] <br>
117 : * Allows one to insert a pattern or patterns into the data within the current
118 : * data range. The format of <i>pattern</i> is the same as for "-replace".
119 : * The total number of insertions is controlled by the "-errorrate" or
120 : * "-errorcount" options and the locations of the insertions by "-range".
121 : * \li -insert-random <i>min</i> <i>max</i> <br>
122 : * Inserts a random number of bits within the range [<i>min</i>..<i>max</i>]
123 : * into locations selected within the current range and for a total number of
124 : * times controlled by the "-errorrate" or "-errorcount" options.
125 : * \li -remove <i>min</i> <i>max</i> <br>
126 : * Removes a random number of bits within the range [<i>min</i>..<i>max</i>]
127 : * at locations selected within the current range and for a total number of
128 : * times controlled by the "-errorrate" or "-errorcount" options.
129 : * For removing bytes one needs to specify a multiple of 8. Also, to remove
130 : * a fixed number of bits one must set <i>min</i> equal <i>max</i>.
131 : *
132 : * \note All corruption operations are applied in the order they as specified on
133 : * the command line. So the first argument will be applied first, and the
134 : * last one last.
135 : * \note The default corruption settings is to introduce only 1% single bit flips
136 : * if no other settings are set and for all data block types if none specified.
137 : *
138 : * <h2>Configuration:</h2>
139 : * Can only be configured with the command line arguments.
140 : *
141 : * <h2>Default CDB entries:</h2>
142 : * None.
143 : *
144 : * <h2>Performance:</h2>
145 : * Depends on complexity of corruption, but typically should easily run with a
146 : * 3kHz event rate.
147 : *
148 : * <h2>Memory consumption:</h2>
149 : * The amount of memory is used as up to 8 times the size of the largest input
150 : * data block.
151 : *
152 : * <h2>Output size:</h2>
153 : * The same as the input data size, unless garbage insertion options are used.
154 : * In that case the output size depends on the exact settings.
155 : *
156 : * \ingroup alihlt_util_components
157 : */
158 : class AliHLTCorruptorComponent : public AliHLTProcessor
159 : {
160 : public:
161 :
162 : AliHLTCorruptorComponent();
163 : virtual ~AliHLTCorruptorComponent();
164 :
165 : // Methods inherited from AliHLTComponent:
166 : virtual const char* GetComponentID();
167 : virtual void GetInputDataTypes(AliHLTComponentDataTypeList& list);
168 : virtual AliHLTComponentDataType GetOutputDataType();
169 : virtual int GetOutputDataTypes(AliHLTComponentDataTypeList& list);
170 : virtual void GetOutputDataSize(unsigned long& constBase, double& inputMultiplier);
171 : virtual AliHLTComponent* Spawn();
172 : virtual Int_t DoInit(int argc, const char** argv);
173 : virtual Int_t DoDeinit();
174 :
175 : protected:
176 :
177 : // Method inherited from AliHLTProcessor:
178 : virtual int DoEvent(
179 : const AliHLTComponentEventData& evtData,
180 : const AliHLTComponentBlockData* blocks,
181 : AliHLTComponentTriggerData& trigData,
182 : AliHLTUInt8_t* outputPtr,
183 : AliHLTUInt32_t& size,
184 : AliHLTComponentBlockDataList& outputBlocks
185 : );
186 :
187 : using AliHLTProcessor::DoEvent;
188 :
189 : private:
190 :
191 : enum AliCorruptionType
192 : {
193 : kUnknownErrorType = 0, // Unknown corruption type.
194 : kSingleFlips, // Single bit flip errors.
195 : kBurstErrors, // Burst errors.
196 : kReplace, // Replacement of data.
197 : kReplaceRandom, // Replacement of data with random bits.
198 : kInsert, // Insertion of data.
199 : kInsertRandom, // Insertion of random data.
200 : kRemove, // Removal of data.
201 : };
202 :
203 : struct AliBlockId
204 : {
205 : AliHLTComponentDataType fType; // Data type and origin.
206 : AliHLTUInt32_t fSpec; // Data block specification.
207 : bool fTypeSet; // Flag indicating if the fType.fID field was set.
208 : bool fOriginSet; // Flag indicating if the fType.fOrigin field was set.
209 : bool fSpecSet; // Flag indicating if the fSpec field was set.
210 : };
211 :
212 : typedef std::vector<AliBlockId> AliBlockIdList;
213 :
214 : struct AliPattern
215 : {
216 : AliHLTUInt64_t fPattern; // The bit pattern.
217 : AliHLTUInt8_t fWidth; // The width of the bit pattern in bits.
218 : bool fUseRemoved; // Indicates if the removed bits should be used.
219 : };
220 :
221 : typedef std::vector<AliPattern> AliPatternList;
222 :
223 : struct AliCorruptionInfo
224 : {
225 : AliCorruptionType fType; // The type of error/modification being applied.
226 : AliHLTUInt64_t fMinRange; // The minimum range to apply the errors in bits.
227 : AliHLTUInt64_t fMaxRange; // The maximum range to apply the errors in bits.
228 : AliHLTUInt64_t fAlignment; // The alignment to use for error location selection in bits.
229 : bool fMinRangeRelative; // Indicates that the fMinRange value is relative to the end of the buffer.
230 : bool fMaxRangeRelative; // Indicates that the fMaxRange value is relative to the end of the buffer.
231 : bool fUseRate; // Indicates if the rate or the range should be used.
232 : union
233 : {
234 : double fRate; // The rate that should be used if fUseRate == true.
235 : struct
236 : {
237 : AliHLTUInt64_t fMinErrors; // The minimum error count that should be used if fUseRate == false.
238 : AliHLTUInt64_t fMaxErrors; // The maximum error count that should be used if fUseRate == false.
239 : };
240 : };
241 : union
242 : {
243 : struct
244 : {
245 : AliHLTUInt64_t fBurstErrorLength; // Maximum burst error length in bits.
246 : AliHLTUInt64_t fBurstErrorCount; // Number of bit flips in a burst error.
247 : };
248 : struct
249 : {
250 : AliHLTUInt64_t fMinBits; // Minimum number of bits to replace/insert/remove.
251 : AliHLTUInt64_t fMaxBits; // Maximum number of bits to replace/insert/remove.
252 : };
253 : struct
254 : {
255 : size_t fFirstPattern; // First pattern to use for replacement or insertion.
256 : size_t fLastPattern; // Last pattern to use for replacement or insertion.
257 : };
258 : };
259 : };
260 :
261 : typedef std::vector<AliCorruptionInfo> AliCorruptionInfoList;
262 :
263 : /**
264 : * Converts the value to a positive 64 bit integer.
265 : * \param [in] value The command line parameter to convert.
266 : * \param [out] num The result is stored in this variable.
267 : * \param [in] printErrors Indicates if error messages should be generated.
268 : * \returns true if the convertion was successful.
269 : */
270 : bool ConvertToPositiveInt(const char* value, AliHLTUInt64_t& num, bool printErrors = true) const;
271 :
272 : /**
273 : * Converts the value to a bit position.
274 : * \param [in] value The command line parameter to convert.
275 : * \param [out] pos The result is stored in this variable.
276 : * \param [out] relative Flag filled to indicate if the resulting position
277 : * is relative to the end of the data block buffer.
278 : * \param [in] printErrors Indicates if error messages should be generated.
279 : * \returns true if the convertion was successful.
280 : */
281 : bool ConvertToBitPosition(const char* value, AliHLTUInt64_t& pos, bool& relative, bool printErrors = true) const;
282 :
283 : /**
284 : * Converts the value to a percentage fraction in the range [0..1].
285 : * \param [in] value The command line parameter to convert.
286 : * \param [out] num The result is stored in this variable.
287 : * \param [in] printErrors Indicates if error messages should be generated.
288 : * \returns true if the convertion was successful.
289 : */
290 : bool ConvertToPercentage(const char* value, double& num, bool printErrors = true) const;
291 :
292 : /**
293 : * Converts a string to a pattern for the -replace and -insert command line options.
294 : * \param [in] value The command line parameter to convert.
295 : * \param [out] pattern The resulting pattern structure.
296 : * \param [in] printErrors Indicates if error messages should be generated.
297 : * \returns true if the convertion was successful.
298 : */
299 : bool ConvertToPattern(const char* value, AliPattern& pattern, bool printErrors = true) const;
300 :
301 : /**
302 : * Adds a data block type to the current data block filter rule.
303 : * A new filter rule is created if the type is already set.
304 : * \param type The type of the data block.
305 : * \returns true if the type string was valid.
306 : */
307 : bool AddBlockTypeId(const char* type);
308 :
309 : /**
310 : * Adds a data block origin to the current data block filter rule.
311 : * A new filter rule is created if the origin is already set.
312 : * \param origin The origin of the data block.
313 : * \returns true if the origin string was valid.
314 : */
315 : bool AddBlockOrigin(const char* origin);
316 :
317 : /**
318 : * Adds a data block specification to the current data block filter rule.
319 : * A new filter rule is created if the specification is already set.
320 : * \param spec The specification of the data block.
321 : * \returns true if the specification string was a valid string.
322 : */
323 : bool AddBlockSpec(const char* spec);
324 :
325 : /**
326 : * Adds a corruption command as a AliCorruptionInfo structure to the list
327 : * of commands to apply to the input data blocks.
328 : */
329 : void AddCorruptionCommand(
330 : AliCorruptionType type,
331 : AliHLTUInt64_t minrange,
332 : AliHLTUInt64_t maxrange,
333 : AliHLTUInt64_t alignment,
334 : bool minRangeRelative,
335 : bool maxRangeRelative,
336 : bool userate = true,
337 : double rate = 0,
338 : AliHLTUInt64_t minerrors = 0,
339 : AliHLTUInt64_t maxerrors = 0,
340 : AliHLTUInt64_t burstlength = 0,
341 : AliHLTUInt64_t burstcount = 0,
342 : AliHLTUInt64_t minbits = 0,
343 : AliHLTUInt64_t maxbits = 0,
344 : size_t firstpattern = 0,
345 : size_t lastpattern = 0
346 : );
347 :
348 : /// Parses command line parameters for a command with pattern fields.
349 : int CheckForCommandWithPatterns(
350 : const char* name, AliCorruptionType type,
351 : int& i, int argc, const char** argv,
352 : AliHLTUInt64_t minrange,
353 : AliHLTUInt64_t maxrange,
354 : AliHLTUInt64_t alignment,
355 : bool minRangeRelative,
356 : bool maxRangeRelative,
357 : bool userate,
358 : double errorrate,
359 : AliHLTUInt64_t minerrors,
360 : AliHLTUInt64_t maxerrors
361 : );
362 :
363 : /// Parses command line parameters for a command with min and max fields.
364 : int CheckForCommandWithMinMax(
365 : const char* name, AliCorruptionType type,
366 : int& i, int argc, const char** argv,
367 : AliHLTUInt64_t minrange,
368 : AliHLTUInt64_t maxrange,
369 : AliHLTUInt64_t alignment,
370 : bool minRangeRelative,
371 : bool maxRangeRelative,
372 : bool userate,
373 : double errorrate,
374 : AliHLTUInt64_t minerrors,
375 : AliHLTUInt64_t maxerrors
376 : );
377 :
378 : /// Checks to see if a data block should be processed or not.
379 : bool ShouldProcess(const AliHLTComponentBlockData* block) const;
380 :
381 : /// Applies the corruption commands to a bit string.
382 : void ApplyCorruption(std::vector<bool>& bits) const;
383 :
384 : double fBufferMultiplier; // The multiplier used by GetOutputDataSize.
385 : AliBlockIdList fBlockIdList; // The list of data block filters.
386 : AliCorruptionInfoList fCorruptionInfoList; // The list of corruptions to be applied.
387 : AliPatternList fPatterns; // Patterns to use for replacements or insertions.
388 :
389 8 : ClassDef(AliHLTCorruptorComponent, 0) // Data corruption component for testing.
390 : };
391 :
392 : #endif // ALIHLTCORRUPTORCOMPONENT_H
|