das2C
das core C utilities (v3)
Loading...
Searching...
No Matches
dataset.h
Go to the documentation of this file.
1/* Copyright (C) 2017-2024 Chris Piker <chris-piker@uiowa.edu>
2 *
3 * This file is part of das2C, the Core Das2 C Library.
4 *
5 * das2C is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU Lesser General Public License version 2.1 as published
7 * by the Free Software Foundation.
8 *
9 * das2C is distributed in the hope that it will be useful, but WITHOUT ANY
10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * version 2.1 along with das2C; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18
21#ifndef _das_dataset_h_
22#define _das_dataset_h_
23
24#include <das3/dimension.h>
25#include <das3/codec.h>
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31/* Old initial comment that kicked off the entire das2 data model design...
32 *
33 * The structures below are the start of an idea on how to get independent
34 * parameters for data at any particular index. These are just thoughts
35 * at the moment and don't affect any working code. There are many ways
36 * to do this. The CDF and QStream assumption is that there are the same
37 * number of parameters locating a data point in parameter space as there
38 * are indices to the dataset. Because of this x,y,z scatter data are
39 * hard to handle.
40 *
41 * For x,y,z scatter lists there is 1 index for any point in the dataset,
42 * but for each index there are 2 independent parameters. Basically QStream
43 * and CDF assume that all datasets are CUBEs in parameter space but this
44 * is not the case for a great many sets.
45 *
46 * To adequately handle these 'path' datasets a parameter map is required.
47 * The mapping takes 1 index value per data rank and returns 1 to N parameter
48 * values.
49 *
50 * These structures start to handle this idea but are just doodles at this
51 * point. -cwp 2017-07-25
52 */
53
54/* Second comment that added desire for flexible data types ...
55 *
56 * Thinking about coordinate returns, how about a data set of thefts / month
57 * in 5 cities... Won't usually come up, but should be possible
58 * to handle. Here's the data set:
59 *
60 * 2016-01 2016-02 2016-03 2016-04 2016-05 2016-06
61 * Baltimore 2351 3789 4625 5525 6135 5902
62 * Bogotaƃ 109065 110365 99625 98265 43850 33892
63 * Chicago 4789 5764 8901 10145 13456 22678
64 * Des Moines 4 10 33 35 44 107
65 *
66 * Properties: Title -> "Thefts/Month for selected cities"
67 *
68 * Okay, the X axis data type is text[12] (need null char)
69 * Y axis data type is datetime
70 * Z axis data type is datum, "thefts month**-1"
71 *
72 * So what is the return value from pDs->bin(pDs, 0, 0) ?
73 *
74 * The bin is defined on the space of all UTC times, and on the space of all
75 * cities in the data set.
76 *
77 *
78 * So, what about this common data set, interference events:
79 *
80 * |<---------- Bin ------>| |<----- Value --->|
81 * 2016-01-01T14:00 2016-01-02T02:20 Mag Roll
82 * 2016-01-01T15:40 2016-01-01T15:41 Stabilization Pulse
83 * 2016-01-01T15:43 2016-01-01T15:44 Stabilization Pulse
84 * 2016-01-01T15:45 2016-01-01T15:47 Stabilization Pulse
85 * 2016-01-01T15:48 2016-01-01T15:50 Stabilization Pulse
86 *
87 * So what is the return value from pDs->bin(pDs, 0) ?
88 *
89 * The space is UTC time, So each bin start and stop is defined on the space
90 * of all UTC times.
91 * -cwp 2017-??-??
92 */
93
94/* Number of encoders that can be stored internally, more then this and they
95 * have to be allocated on the heap.
96 *
97 * Current test case with the most codec/dateste is ex21, at 7.
98 * If you bump this make a test case with one more variable than the new
99 * value below.
100 */
101#define DASDS_LOC_ENC_SZ 6
102
103/* Small vector size for array and dimension pointer sets. Larger then
104 * DASDS_LOC_ENC_SZ because these are just sizeof(void*) each not ~200 B.
105 *
106 * NOTE: No test case reaches these sizes, but both were reduced to 6 for
107 * a onetime test against ex21_tracers_cdpu_status.d3b (uDims=7,
108 * uArrays=7), on 2026-07-16.
109 *
110 * If you touch the dynamic #of array or dims code, drop these back to 6
111 * each and run `make test`.
112 */
113#define DASDS_LOC_ARY_SZ 32
114#define DASDS_LOC_DIM_SZ 32
115
156typedef struct dataset {
157 DasDesc base; /* This would be equivalent to the properties for
158 a packet descriptor. Typically in das 2.2 packets
159 don't have a descriptor, only streams and planes
160 but access to the stream descriptor forwards through
161 here. */
162
163 int nRank; /* The number of whole-dataset index dimensions.
164 * Variables can define internal dimensions but they
165 * can't use indices in the first nRank positions for
166 * internal use, as these are used to correlate values
167 * across the dataset. */
168
169 /* A text identifier for this instance of a data set */
170 char sId[DAS_MAX_ID_BUFSZ];
171
172 /* A text identifier for the join group for this dataset. Datasets with
173 * the same groupID should be joined automatically by display clients.
174 */
175 char sGroupId[DAS_MAX_ID_BUFSZ];
176
177 size_t uDims; /* Number of dimensions, das datasets are
178 * implicitly bundles in qdataset terms. */
179
180 DasDim** lDims; /* The data variable object arrays, internal or external */
181 size_t uSzDims; /* lDims memory size, internal or external */
182
183 DasDim* aDims[DASDS_LOC_DIM_SZ]; /* small vector memory */
184
185 size_t uArrays; /* The number of low-level arrays */
186 DasAry** lArrays; /* Array objects, internal or external */
187 size_t uSzArrays; /* lArrays memory size, internal or external */
188
189 DasAry* aArrays[DASDS_LOC_ARY_SZ]; /* small vector memory */
190
191 ptrdiff_t _shape[VARIDX_MAX]; /* cache shape calls for speed */
192
193 bool _dynamic; /* If true, the dataset may still be changing and all
194 bulk properties such as the iteration shape should be
195 recalculated instead of using cached values.
196 If false, cached values are expected to already be
197 available */
198
199 /* dataset arrays can be written in chunks to output buffers. The number of
200 * elements in each chuck, the encoding of each element any separators are
201 * defined below. */
202 /* DasCodec** lEncs; */
203
204 size_t uCodecs; /* Number of valid codecs */
205
206 /* These become large vector memory when uSzEncs > DASDS_LOC_ENC_SZ */
207
208 /* When the number of valid codecs grows past DASDS_LOC_ENC_SZ, use an
209 external buffer for all of them */
210
211 DasCodec* lCodecs; /* Codec pointers, internal or external */
212 int* lItems; /* Number of items to decode per codec, internal or ex */
213 size_t uSzCodecs; /* Codec & Item array memory size, internal or external */
214
215 DasCodec aCodecs[DASDS_LOC_ENC_SZ]; /* small vector memory */
216 int aItems[DASDS_LOC_ENC_SZ]; /* small vector memory */
217
218 /* Set to true when encode is called, make sure data doesn't go
219 * out the door unless the descriptor is sent first */
220 bool bSentHdr;
221
229 void* pUser;
230
231} DasDs;
232
268 const char* sId, const char* sGroupId, int nRank
269);
270
303DAS_API DasDs* DasDs_copy(const DasDs* pThis);
304
337DAS_API DasErrCode DasDs_replaceAry(DasDs* pThis, const char* sOldId, DasAry* pNew);
338
348DAS_API void del_DasDs(DasDs* pThis);
349
366DAS_API void DasDs_setMutable(DasDs* pThis, bool bChangeAllowed);
367
368
373#define DasDs_mutable(P) P->_mutable
374
418DAS_API int DasDs_shape(const DasDs* pThis, ptrdiff_t* pShape);
419
437DAS_API ptrdiff_t DasDs_lengthIn(const DasDs* pThis, int nIdx, ptrdiff_t* pLoc);
438
439
456#define DasDs_group(P) ((const char*)(P)->sGroupId)
457
464#define DasDs_id(P) ((const char*)(P)->sId)
465
466
483#define DasDs_rank(P) ((P)->nRank)
484
507DAS_API DasErrCode DasDs_addAry(DasDs* pThis, DasAry* pAry);
508
509
514#define DasDs_numAry(P) ((P)->uArrays)
515
523#define DasDs_getAry(P, I) ((P)->lArrays[(I)])
524
525
540DAS_API DasAry* DasDs_getAryById(DasDs* pThis, const char* sAryId);
541
563DAS_API size_t DasDs_memUsed(const DasDs* pThis);
564
569DAS_API size_t DasDs_memIndexed(const DasDs* pThis);
570
590DAS_API size_t DasDs_memOwned(const DasDs* pThis);
591
598#define DasDs_numCodecs( pThis ) ( (pThis)->uCodecs )
599
607#define DasDs_getCodec( pThis, I ) ( &( (pThis)->lCodecs[(I)] ) )
608
626 const DasDs* pThis, const char* sAryId, int* pItems
627);
628
634#define DasDs_pktItems( P, I ) ( (P)->lItems[(I)] )
635
681 DasDs* pThis, const char* sAryId, const char* sSemantic,
682 const char* sEncType, int nItemBytes, int nNumItems, bool bRead
683);
684
729 DasDs* pThis, const char* sAryId, const char* sSemantic,
730 const char* sEncType, int nItemTerm, ubyte uTerm, int nNumItems,
731 bool bRead
732);
733
734
760 DasDs* pThis, const char* sAryId, const DasCodec* pOther, int nNumItems,
761 bool bRead
762);
763
782DAS_API DasDs* new_DasDs_xml(DasBuf* pBuf, DasDesc* pParent, int nPktId);
783
800DAS_API DasErrCode DasDs_encodeHdr(DasDs* pThis, DasBuf* pBuf);
801
817
834DAS_API DasErrCode DasDs_encodeData(DasDs* pThis, DasBuf* pBuf, ptrdiff_t iIdx0);
835
836
852DAS_API int DasDs_recBytes(const DasDs* pThis);
853
854
873DAS_API size_t DasDs_clearRagged0(DasDs* pThis);
874
875
899 DasDs* pThis, enum dim_type dType, const char* sDim, const char* sId
900);
901
916DAS_API DasErrCode DasDs_addDim(DasDs* pThis, DasDim* pDim);
917
925DAS_API size_t DasDs_numDims(const DasDs* pThis, enum dim_type dmt);
926
927
936 DasDs* pThis, const char* sDim, enum dim_type dmt
937);
938
947 DasDs* pThis, size_t idx, enum dim_type vt
948);
949
961DAS_API DasDim* DasDs_getDimById(DasDs* pThis, const char* sId);
962
963
972DAS_API char* DasDs_toStr(const DasDs* pThis, char* sBuf, int nLen);
973
974
994bool DasDs_cubicCoords(const DasDs* pThis, const DasDim** pCoords);
995
996
997
998
999/* Ideas I'm still working on...
1000
1001bool DataGen_grid(const DataSet* pDataset);
1002
1003const DataSet** Dg_griddedIn(const DataSet* pDataset);
1004
1005
1006/ * The two functions below are really useful but I'll need to crack open
1007 a double pack of Flex and Bison to get it done so I'm punting for now. * /
1008
1009/ * Ex Expression: $spec_dens[i][j][k] * /
1010const Function* Dataset_evalDataExp(Dataset* pThis, const char* sExpression);
1011
1012/ * Ex Expression: $craft_alt[i][j] - 0.5 * $delay_time[k] * 299792 * /
1013const Function* Dataset_evalCoordExp(Dataset* pThis, const char* sExpression);
1014
1015
1016/ ** Get the coefficients for iterating over a 1-D slice of a regular (i.e.
1017 * non-ragged) dataset.
1018 *
1019 * This function dose not work for ragged datasets and merely returns NULL if
1020 * asked for iteration coefficients for such a set. In such a case use
1021 * Dataset_copySlice1D().
1022 *
1023 * /
1024const void* Dataset_slice1D(
1025 const Dataset* pThis, const char* sDs, const char* sCoord, int iCoordIdx,
1026 int* pCoeff
1027);
1028
1029/ ** Increment the reference count on any array objects that are part of
1030 * a data space.
1031 *
1032 * This is useful in instances where the underlying data arrays are going
1033 * to be represented by an organizational structure other than datasets
1034 * and DataSets since Das array objects only free data memory if their
1035 * reference count is zero.
1036 *
1037 * @param pThis
1038 * /
1039void DataSpace_incAryRef(Dataset* pThis);
1040
1041/ * Need a way to trigger callbacks from datasets changing, not just
1042 packets changing. It could be useful to work on items from the
1043 dataset level instead of just the packet level * /
1044 bool DataSpace_stream(Dataset* pThis); * /
1045
1046
1047
1048/ ** Indicate the physical degrees of freedom for a dataset by denoting a
1049 * complete list of coordinate sets.
1050 *
1051 * A list of coordinates over which an entire dataset is defined is called
1052 * a span. Datasets may have 1-N spans.
1053 * /
1054int DataSpace_addSpan(const char* sDsId, const char** lCoords, size_t nCoords);
1055*/
1056
1057#ifdef __cplusplus
1058}
1059#endif
1060
1061#endif /* _das_dataset_h */
Encoding/Decoding arrays to and from buffers.
bool DasDs_cubicCoords(const DasDs *pThis, const DasDim **pCoords)
Get coordinate dimensions that satisfy the cubic dataset condition.
DAS_API DasDs * DasDs_copy(const DasDs *pThis)
Copy a dataset object.
DAS_API size_t DasDs_memIndexed(const DasDs *pThis)
The apparent memory usage of all arrays in the dataset.
#define VARIDX_MAX
Max index count for the model.
Definition generator.h:55
int DasErrCode
return code type 0 indicates success, negative integer indicates failure
Definition defs.h:184
Dynamic recursive ragged arrays.
Definition array.h:271
DAS_API size_t DasDs_clearRagged0(DasDs *pThis)
Clear any arrays that are ragged in index 0.
Buffer class to handle accumulating byte streams.
Definition buffer.h:47
Reading and writing array data to buffers.
Definition codec.h:45
Base structure for Stream Header Items.
Definition descriptor.h:74
Das Physical Dimensions.
Definition dimension.h:133
Das Datasets.
Definition dataset.h:156
DAS_API DasErrCode DasDs_encodeHdr(DasDs *pThis, DasBuf *pBuf)
Encode the dataset header as a das3 <dataset> XML element.
DAS_API size_t DasDs_numDims(const DasDs *pThis, enum dim_type dmt)
Get the number of physical dimensions in this dataset.
DAS_API DasErrCode DasDs_replaceAry(DasDs *pThis, const char *sOldId, DasAry *pNew)
Swap a storage array in a dataset for a replacement.
DAS_API DasDim * DasDs_makeDim(DasDs *pThis, enum dim_type dType, const char *sDim, const char *sId)
Make a new dimension within this dataset.
DAS_API DasCodec * DasDs_addStringCodec(DasDs *pThis, const char *sAryId, const char *sSemantic, const char *sEncType, int nItemTerm, ubyte uTerm, int nNumItems, bool bRead)
Define a packet data encoder for a fixed number of variable length items in each packet.
DAS_API DasCodec * DasDs_getCodecFor(const DasDs *pThis, const char *sAryId, int *pItems)
Get the codec for a named array.
DAS_API DasDs * new_DasDs(const char *sId, const char *sGroupId, int nRank)
Create a new dataset object.
DAS_API size_t DasDs_memUsed(const DasDs *pThis)
Get the currently used memory of all arrays in the dataset.
DAS_API void del_DasDs(DasDs *pThis)
Delete a Data object, cleaning up it's memory.
DAS_API char * DasDs_toStr(const DasDs *pThis, char *sBuf, int nLen)
Print a string representation of this dataset.
DAS_API size_t DasDs_memOwned(const DasDs *pThis)
Get the currently allocated memory of all arrays in the dataset.
DAS_API int DasDs_recBytes(const DasDs *pThis)
Get the number of bytes in each record of this dataset when serialized.
DAS_API void DasDs_setMutable(DasDs *pThis, bool bChangeAllowed)
Lock/Unlock the dataset for changes.
DAS_API DasDim * DasDs_getDimById(DasDs *pThis, const char *sId)
Get a dimension by string id.
DAS_API DasErrCode DasDs_addAry(DasDs *pThis, DasAry *pAry)
Add an array to the dataset, stealing it's reference.
DAS_API DasDim * DasDs_getDim(DasDs *pThis, const char *sDim, enum dim_type dmt)
Get a dimension by it's basic kind.
DAS_API DasCodec * DasDs_addFixedCodec(DasDs *pThis, const char *sAryId, const char *sSemantic, const char *sEncType, int nItemBytes, int nNumItems, bool bRead)
Define a packet data encoded/decoder for fixed length items and arrays.
DAS_API DasErrCode DasDs_decodeData(DasDs *pThis, DasBuf *pBuf)
Decode one packet's worth of data into dataset memory.
DAS_API DasErrCode DasDs_encodeData(DasDs *pThis, DasBuf *pBuf, ptrdiff_t iIdx0)
Encode one record's worth of data from dataset memory.
DAS_API int DasDs_shape(const DasDs *pThis, ptrdiff_t *pShape)
Return current valid ranges for whole data set iteration.
DAS_API DasDim * DasDs_getDimByIdx(DasDs *pThis, size_t idx, enum dim_type vt)
Get a dimension by index.
DAS_API DasDs * new_DasDs_xml(DasBuf *pBuf, DasDesc *pParent, int nPktId)
Parse a das3 <dataset> XML element into a new dataset object.
DAS_API DasAry * DasDs_getAryById(DasDs *pThis, const char *sAryId)
Get a dataset array given it's identifier.
DAS_API DasErrCode DasDs_addDim(DasDs *pThis, DasDim *pDim)
Add a physical dimension to the dataset.
DAS_API ptrdiff_t DasDs_lengthIn(const DasDs *pThis, int nIdx, ptrdiff_t *pLoc)
Return the current max value index value + 1 for any partial index.
DAS_API DasCodec * DasDs_addCodecFrom(DasDs *pThis, const char *sAryId, const DasCodec *pOther, int nNumItems, bool bRead)
Add a new codec that initialized via some other codec.
void * pUser
User data pointer.
Definition dataset.h:229
#define DAS_MAX_ID_BUFSZ
The size of an char buffer large enough to hold valid object IDs.
Definition util.h:349