-
Notifications
You must be signed in to change notification settings - Fork 6
/
dataset.h
435 lines (414 loc) · 18.3 KB
/
dataset.h
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
/* *********************************************************************
* This Original Work is copyright of 51 Degrees Mobile Experts Limited.
* Copyright 2023 51 Degrees Mobile Experts Limited, Davidson House,
* Forbury Square, Reading, Berkshire, United Kingdom RG1 3EU.
*
* This Original Work is licensed under the European Union Public Licence
* (EUPL) v.1.2 and is subject to its terms as set out below.
*
* If a copy of the EUPL was not distributed with this file, You can obtain
* one at https://opensource.org/licenses/EUPL-1.2.
*
* The 'Compatible Licences' set out in the Appendix to the EUPL (as may be
* amended by the European Commission) shall be deemed incompatible for
* the purposes of the Work and the provisions of the compatibility
* clause in Article 5 of the EUPL shall not apply.
*
* If using the Work as, or as part of, a network application, by
* including the attribution notice(s) required under Article 5 of the EUPL
* in the end user terms of the application under an appropriate heading,
* such notice(s) shall fulfill the requirements of that article.
* ********************************************************************* */
#ifndef FIFTYONE_DEGREES_DATASET_H_INCLUDED
#define FIFTYONE_DEGREES_DATASET_H_INCLUDED
/**
* @ingroup FiftyOneDegreesCommon
* @defgroup FiftyOneDegreesDataSet Data Set
*
* A data file initialised in a structure.
*
* ## Terms
*
* **Get** : returns an immutable data set that must be released when the
* caller is finished with it.
* **Release** : releases a reference on the data set returned from the Get
* operation.
* **Reload** : reloads an existing data set while maintaining any current
* references to the existing data set.
*
* ## Introduction
*
* A DataSet is a data file initialised in a structure that can be used to
* process data. Collections from the file may be stored in memory or streamed
* from the file when needed.
*
* A DataSet is used to process data, in most cases this is in the form of
* evidence. Values for the Properties which the data set is capable of
* returning can then be retrieved from the result of processing.
*
* ## Creation
*
* A DataSet is created by allocating the structure and initialising from one
* of the following:
*
* **File** : a data file is either read into memory or handle maintained for
* streaming by the data set.
*
* **Memory** : a data file read into continuous memory is used by the data set.
*
* ## Operation
*
* A DataSet is a resource to be maintained by a Resource Manager. So any
* thread wanting to use it must get a reference from the manager
* (see resource.h).
*
* The data set implementation extending will contain methods to process data.
* Usually these will return a Results instance (or an extending structure),
* see results.h for more details.
*
* ## Reloading
*
* A DataSet can be reloaded without interrupting operation by using the
* defined Reload methods. These take either a new data file or a new memory
* pointer, initialise a new data set, and replace the existing one in a
* thread-safe manor.
*
* ## Free
*
* A DataSet is a managed resource, so it should not be freed directly. Instead
* the manager should be freed, so that the data set is safely freed without
* impacting other threads.
*
* @{
*/
#include "exceptions.h"
#include "file.h"
#include "memory.h"
#include "resource.h"
#include "properties.h"
#include "headers.h"
#include "config.h"
#include "overrides.h"
#include "common.h"
/**
* Base data set structure which contains the 'must have's for all data sets.
*/
typedef struct fiftyone_degrees_dataset_base_t {
const char fileName[FIFTYONE_DEGREES_FILE_MAX_PATH]; /**< Path to the file
used to initialise the
data set. This will
either be the same as
the master file name,
or the path to the
temp file being used. */
const char masterFileName[FIFTYONE_DEGREES_FILE_MAX_PATH]; /**< Path to the
file used to
initialise the
data set. */
void *memoryToFree; /**< A pointer to the memory where the data within the
data set is held. NULL if the entire data set is not
held in memory, the caller is going to free the
memory or there are a mixture of caches and
partially allocated memory in use. */
bool isInMemory; /**< True if the data file has been read into continuous
memory */
fiftyoneDegreesFilePool filePool; /**< Linked list of file readers */
fiftyoneDegreesResourceHandle *handle; /**< Pointer to the handle that
tracks this data set instance */
fiftyoneDegreesPropertiesAvailable *available; /**< Available properties */
fiftyoneDegreesHeaders *uniqueHeaders; /**< Related HTTP headers */
fiftyoneDegreesOverridePropertyArray *overridable; /**< Array of properties
that can be
overridden */
const void *config; /**< Pointer to the config used to create the dataset */
} fiftyoneDegreesDataSetBase;
/**
* Initialses the data set from data stored in continuous memory.
* @param dataSet pointer to the data set to be initialised
* @param config configuration for the operation of the data set, or NULL if
* default configuration is required
* @param properties the properties that will be consumed from the data set, or
* NULL if all available properties in the hash data file should be available
* for consumption
* @param memory pointer to continuous memory containing the data set
* @param size the number of bytes that make up the data set
* @param exception pointer to an exception data structure to be used if an
* exception occurs. See exceptions.h.
* @return the status associated with the data set intialisation. Any value
* other than #FIFTYONE_DEGREES_STATUS_SUCCESS means the data set was not
* initialised correctly
*/
typedef fiftyoneDegreesStatusCode(*fiftyoneDegreesDataSetInitFromMemoryMethod)(
void *dataSet,
const void *config,
fiftyoneDegreesPropertiesRequired *properties,
void *memory,
long size,
fiftyoneDegreesException *exception);
/**
* Initialses the data set from data stored on file. This method
* should clean up the resource properly if the initialisation process fails.
* That means all allocated memory should be freed and pointers to these
* memorys should be set to NULL. The input dataSet should also be freed.
* @param dataSet pointer to the data set to be initialised
* @param config configuration for the operation of the data set, or NULL if
* default configuration is required
* @param properties the properties that will be consumed from the data set, or
* NULL if all available properties in the hash data file should be available
* for consumption
* @param fileName the full path to a file with read permission that contains
* the data set
* @param exception pointer to an exception data structure to be used if an
* exception occurs. See exceptions.h
* @return the status associated with the data set intialisation. Any value
* other than #FIFTYONE_DEGREES_STATUS_SUCCESS means the data set was not
* initialised correctly
*/
typedef fiftyoneDegreesStatusCode(*fiftyoneDegreesDataSetInitFromFileMethod)(
void *dataSet,
const void *config,
fiftyoneDegreesPropertiesRequired *properties,
const char *fileName,
fiftyoneDegreesException *exception);
/**
* Initialises the properties in the data set. Usually this means constructing
* an array of pointers to the properties which are required for quick access.
* @param dataSet pointer to a valid data set
* @param properties the properties which should be initialised in the data set
* @param state pointer to data which is needed by getPropertymethod
* @param getPropertyMethod method used to retrieve the name of a property at
* a specified index from the data set
* @param getEvidencePropertiesMethod method used to populate the list of
* evidence required for a property in the data set
* @return the status associated with the property initialisation. Any value
* other than #FIFTYONE_DEGREES_STATUS_SUCCESS means the properties were not
* initialised correctly
*/
fiftyoneDegreesStatusCode fiftyoneDegreesDataSetInitProperties(
fiftyoneDegreesDataSetBase *dataSet,
fiftyoneDegreesPropertiesRequired *properties,
void *state,
fiftyoneDegreesPropertiesGetMethod getPropertyMethod,
fiftyoneDegreesEvidencePropertiesGetMethod getEvidencePropertiesMethod);
/**
* Initialises the HTTP headers in the data set. Usually this means
* constructing an array of pointers to the headers which are required for
* quick access.
* @param dataSet pointer to a valid data set
* @param state pointer to data which is needed by getPropertymethod
* @param getHeaderMethod method used to retrieve the unique id and name of a
* header at a specified index from the data set
* @return the status associated with the header initialisation. Any value
* other than #FIFTYONE_DEGREES_STATUS_SUCCESS means the headers were not
* initialised correctly
*/
fiftyoneDegreesStatusCode fiftyoneDegreesDataSetInitHeaders(
fiftyoneDegreesDataSetBase *dataSet,
void *state,
fiftyoneDegreesHeadersGetMethod getHeaderMethod);
/**
* Initialses the data set from data stored on file.
* @param dataSet pointer to the pre allocated data set to be initialised
* @param fileName the full path to a file with read permission that contains
* the data set
* @param bytesToCompare the number of bytes to compare if the reuse temporary
* file option is enabled. If a temporary file is found and the first bytes are
* equal to the master file, then the file is used, if not then a new temporary
* file is created
* @return the status associated with the data set intialisation. Any value
* other than #FIFTYONE_DEGREES_STATUS_SUCCESS means the data set was not
* initialised correctly
*/
fiftyoneDegreesStatusCode fiftyoneDegreesDataSetInitFromFile(
fiftyoneDegreesDataSetBase *dataSet,
const char *fileName,
long bytesToCompare);
/**
* Initialses the data set from data stored in continuous memory.
* @param dataSet pointer to the pre allocated data set to be initialised
* @param reader constructed to read the memory containing the data set
* @return the status associated with the data set intialisation. Any value
* other than #FIFTYONE_DEGREES_STATUS_SUCCESS means the data set was not
* initialised correctly
*/
fiftyoneDegreesStatusCode fiftyoneDegreesDataSetInitInMemory(
fiftyoneDegreesDataSetBase *dataSet,
fiftyoneDegreesMemoryReader *reader);
/**
* Resets a newly allocated data set structure ready for initialisation.
* @param dataSet pointer to the allocated data set
*/
void fiftyoneDegreesDataSetReset(fiftyoneDegreesDataSetBase *dataSet);
/**
* Gets a pointer to the active data set from a resource manager.
* Note that when this is finished with it must be released with the
* corresponding release method.
* @param manager pointer to the manager which manages the data set resource
* @return pointer to the data set resource
*/
EXTERNAL fiftyoneDegreesDataSetBase* fiftyoneDegreesDataSetGet(
fiftyoneDegreesResourceManager *manager);
/**
* Releases a reference to a data set which has been fetched via the DataSetGet
* method.
* @param dataSet pointer to the data set to release
*/
EXTERNAL void fiftyoneDegreesDataSetRelease(fiftyoneDegreesDataSetBase *dataSet);
/**
* Closes the data set by freeing anything which has been initialised at
* creation. This does not free the data set structure itself.
* @param dataSet pointer to the data set to complete
*/
void fiftyoneDegreesDataSetFree(fiftyoneDegreesDataSetBase *dataSet);
/**
* Reload the data set being used by the resource manager using a data file
* loaded into contiguous memory. When initialising the data, the configuration
* that manager was first created with is used.
*
* If the data passed in is successfully initialised, the current data set is
* replaced The old data will remain in memory until the last reference to it
* is released.
* @param manager pointer to the resource manager to reload the data set for
* @param source pointer to the memory location where the new data file is
* stored
* @param length of the data in memory
* @param dataSetSize size of the data set structure to allocate for the new
* data set
* @param initDataSet init method used to initialise the new data set from the
* memory pointer provided
* @param exception pointer to an exception data structure to be used if an
* exception occurs. See exceptions.h.
* @return the status associated with the data set reload. Any value other than
* #FIFTYONE_DEGREES_STATUS_SUCCESS means the data set was not reloaded
* correctly
*/
fiftyoneDegreesStatusCode fiftyoneDegreesDataSetReloadManagerFromMemory(
fiftyoneDegreesResourceManager *manager,
void *source,
long length,
size_t dataSetSize,
fiftyoneDegreesDataSetInitFromMemoryMethod initDataSet,
fiftyoneDegreesException *exception);
/**
* Reload the data set being used by the resource manager using the data file
* location specified. When initialising the data, the configuration that
* manager was first created with is used.
*
* If the new data file is successfully initialised, the current data set is
* replaced The old data will remain in memory until the last reference to it
* is released.
* @param manager pointer to the resource manager to reload the data set for
* @param fileName path to the new data file
* @param dataSetSize size of the data set structure to allocate for the new
* data set
* @param initDataSet init method used to initialise the new data set from the
* file provided
* @param exception pointer to an exception data structure to be used if an
* exception occurs. See exceptions.h.
* @return the status associated with the data set reload. Any value other than
* #FIFTYONE_DEGREES_STATUS_SUCCESS means the data set was not reloaded
* correctly
*/
fiftyoneDegreesStatusCode fiftyoneDegreesDataSetReloadManagerFromFile(
fiftyoneDegreesResourceManager* manager,
const char *fileName,
size_t dataSetSize,
fiftyoneDegreesDataSetInitFromFileMethod initDataSet,
fiftyoneDegreesException *exception);
/**
* Reload functions are common across all data set implementations where
* the naming of the data set type and the init methods comform to the common
* pattern. This macro requires the init methods to be static and of the
* form initDataFrom[Memory|File]. The data set name must be DataSet[Type].
* @param t the name of the resource type to define reload methods for
*/
#define FIFTYONE_DEGREES_DATASET_RELOAD(t) \
/** \
* Reload the data set being used by the resource manager using a data file \
* loaded into contiguous memory. When initialising the data, the configuration \
* that manager was first created with is used. \
* \
* If the data passed in is successfully initialised, the current data set is \
* replaced The old data will remain in memory until the last reference to it \
* is released. \
* @param manager pointer to the resource manager to reload the data set for \
* @param source pointer to the memory location where the new data file is \
* stored \
* @param length of the data in memory \
* @param exception pointer to an exception data structure to be used if an \
* exception occurs. See exceptions.h \
* @return the status associated with the data set reload. Any value other than \
* #FIFTYONE_DEGREES_STATUS_SUCCESS means the data set was not reloaded \
* correctly \
*/ \
fiftyoneDegreesStatusCode fiftyoneDegrees##t##ReloadManagerFromMemory( \
fiftyoneDegreesResourceManager *manager, \
void *source, \
long length, \
fiftyoneDegreesException *exception) { \
return fiftyoneDegreesDataSetReloadManagerFromMemory( \
manager, \
source, \
length, \
sizeof(DataSet##t), \
initDataSetFromMemory, \
exception); \
} \
/** \
* Reload the data set being used by the resource manager using the data file \
* location specified. When initialising the data, the configuration that \
* manager was first created with is used. \
* \
* If the new data file is successfully initialised, the current data set is \
* replaced The old data will remain in memory until the last reference to it \
* is released. \
* @param manager pointer to the resource manager to reload the data set for \
* @param fileName path to the new data file \
* @param exception pointer to an exception data structure to be used if an \
* exception occurs. See exceptions.h \
* @return the status associated with the data set reload. Any value other than \
* #FIFTYONE_DEGREES_STATUS_SUCCESS means the data set was not reloaded \
* correctly \
*/ \
fiftyoneDegreesStatusCode fiftyoneDegrees##t##ReloadManagerFromFile( \
fiftyoneDegreesResourceManager* manager, \
const char *fileName, \
fiftyoneDegreesException *exception) { \
return fiftyoneDegreesDataSetReloadManagerFromFile( \
manager, \
fileName, \
sizeof(DataSet##t), \
initDataSetFromFile, \
exception); \
} \
/** \
* Reload the data set being used by the resource manager using the data file \
* which the data set was initialised with. When initialising the data, the
* configuration that manager was first created with is used. \
* \
* If the new data file is successfully initialised, the current data set is \
* replaced The old data will remain in memory until the last reference to it \
* is released. \
* @param manager pointer to the resource manager to reload the data set for \
* @param exception pointer to an exception data structure to be used if an \
* exception occurs. See exceptions.h \
* @return the status associated with the data set reload. Any value other than \
* #FIFTYONE_DEGREES_STATUS_SUCCESS means the data set was not reloaded \
* correctly \
*/ \
fiftyoneDegreesStatusCode fiftyoneDegrees##t##ReloadManagerFromOriginalFile( \
fiftyoneDegreesResourceManager* manager, \
fiftyoneDegreesException *exception) { \
fiftyoneDegreesStatusCode status = FIFTYONE_DEGREES_STATUS_NOT_SET; \
DataSet##t* dataSet = fiftyoneDegreesDataSet##t##Get(manager); \
status = fiftyoneDegrees##t##ReloadManagerFromFile( \
manager, \
dataSet->b.b.masterFileName, \
exception); \
fiftyoneDegreesDataSet##t##Release(dataSet); \
return status; \
}
/**
* @}
*/
#endif