Skip to content

Commit 11108c9

Browse files
committed
add timeseries-specific function
1 parent 4f9c394 commit 11108c9

6 files changed

Lines changed: 258 additions & 12 deletions

File tree

src/Container.cpp

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,13 @@ namespace griddb {
6464

6565
mContainerInfo->timeSeriesProperties = NULL;
6666
mContainerInfo->triggerInfoList = NULL;
67-
mContainerInfo->dataAffinity = NULL;
67+
68+
if (containerInfo->dataAffinity) {
69+
Util::strdup(&mContainerInfo->dataAffinity,
70+
containerInfo->dataAffinity);
71+
} else {
72+
mContainerInfo->dataAffinity = NULL;
73+
}
6874

6975
if (mTypeList && mContainerInfo->columnInfoList) {
7076
for (int i = 0; i < mContainerInfo->columnCount; i++){
@@ -91,6 +97,10 @@ namespace griddb {
9197
if (mContainerInfo->name) {
9298
delete[] mContainerInfo->name;
9399
}
100+
if (mContainerInfo->dataAffinity) {
101+
delete[] mContainerInfo->dataAffinity;
102+
}
103+
94104
delete mContainerInfo;
95105
mContainerInfo = NULL;
96106
}
@@ -414,4 +424,89 @@ namespace griddb {
414424
void Container::put_rows(GSRow** listRow, int rowCount) {
415425
this->multi_put(listRow, rowCount);
416426
}
427+
428+
/**
429+
* @brief Support query within specific time range
430+
*
431+
* @param startKey start time
432+
* @param finishKey end time
433+
* @return Query* Query object to get data
434+
*/
435+
Query* Container::query_by_time_series_range(GSTimestamp* startTime,
436+
GSTimestamp* endTime, GSQueryOrder order) {
437+
GSQuery *pQuery;
438+
GSResult ret = gsQueryByTimeSeriesOrderedRange(mContainer, startTime,
439+
endTime, (GSQueryOrder) order, &pQuery);
440+
if (!GS_SUCCEEDED(ret)) {
441+
throw GSException(mContainer, ret);
442+
}
443+
444+
try {
445+
Query* queryObj = new Query(pQuery, mContainerInfo, mRow);
446+
return queryObj;
447+
} catch(bad_alloc& ba) {
448+
gsCloseQuery(&pQuery);
449+
throw GSException(mContainer, "Memory allocation error");
450+
}
451+
}
452+
453+
/**
454+
* @brief Performs an aggregation operation based on the specified start and end times.
455+
*
456+
* @param startTime
457+
* @param endTime
458+
* @param aggregation
459+
* @param column
460+
* @return AggregationResult*
461+
*/
462+
AggregationResult* Container::aggregate_time_series(GSTimestamp* startTime,
463+
GSTimestamp* endTime, GSAggregation aggregation, const char* column) {
464+
GSAggregationResult *pAggResult;
465+
GSResult ret = gsAggregateTimeSeries(mContainer, *startTime,
466+
*endTime, column, aggregation, &pAggResult);
467+
if (!GS_SUCCEEDED(ret)) {
468+
throw GSException(mContainer, ret);
469+
}
470+
try {
471+
AggregationResult* aggObj = new AggregationResult(pAggResult);
472+
return aggObj;
473+
} catch(bad_alloc& ba) {
474+
gsCloseAggregationResult(&pAggResult);
475+
throw GSException(mContainer, "Memory allocation error");
476+
}
477+
}
478+
479+
/**
480+
* @brief Creates a query to take a sampling of Rows within a specific range.
481+
*
482+
* @param startTime
483+
* @param endTime
484+
* @param columnSet
485+
* @param columnCount
486+
* @param mode
487+
* @param interval
488+
* @param intervalUnit
489+
* @return Query*
490+
*/
491+
Query* Container::query_by_time_series_sampling(GSTimestamp* startTime,
492+
GSTimestamp* endTime, const GSChar *const *columnSet,
493+
size_t columnCount, GSInterpolationMode mode, int32_t interval,
494+
GSTimeUnit intervalUnit) {
495+
GSQuery *pQuery;
496+
GSResult ret = gsQueryByTimeSeriesSampling(mContainer, *startTime,
497+
*endTime, columnSet, columnCount, mode, interval, intervalUnit, &pQuery);
498+
499+
if (!GS_SUCCEEDED(ret)) {
500+
throw GSException(mContainer, ret);
501+
}
502+
503+
try {
504+
Query* queryObj = new Query(pQuery, mContainerInfo, mRow);
505+
return queryObj;
506+
} catch(bad_alloc& ba) {
507+
gsCloseQuery(&pQuery);
508+
throw GSException(mContainer, "Memory allocation error");
509+
}
510+
}
511+
417512
}

src/Container.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ class Container {
5959
int getColumnCount();
6060
GSRow* getGSRowPtr();
6161
void put_rows(GSRow** listRow, int rowCount);
62+
Query* query_by_time_series_range(GSTimestamp* startTime, GSTimestamp* endTime,
63+
GSQueryOrder order = GS_ORDER_ASCENDING);
64+
AggregationResult* aggregate_time_series(GSTimestamp* startTime,
65+
GSTimestamp* endTime, GSAggregation aggregation, const char* column = NULL);
66+
Query* query_by_time_series_sampling(GSTimestamp* startTime,
67+
GSTimestamp* endTime, const GSChar *const *columnSet, size_t columnCount,
68+
GSInterpolationMode mode, int32_t interval, GSTimeUnit intervalUnit);
6269

6370
private:
6471
Container(GSContainer *container, GSContainerInfo* containerInfo);

src/ContainerInfo.cpp

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,25 @@ namespace griddb {
2424
*/
2525
ContainerInfo::ContainerInfo(GSContainerInfo *containerInfo) {
2626
assert(containerInfo != NULL);
27+
const char* dataAffinity = NULL;
28+
dataAffinity = containerInfo->dataAffinity;
29+
ExpirationInfo* info = NULL;
30+
if (containerInfo->timeSeriesProperties != NULL){
31+
try {
32+
info = new ExpirationInfo(containerInfo->timeSeriesProperties->rowExpirationTime,
33+
containerInfo->timeSeriesProperties->rowExpirationTimeUnit,
34+
containerInfo->timeSeriesProperties->expirationDivisionCount);
35+
} catch (bad_alloc& ba) {
36+
throw GSException("Memory allocation error");
37+
}
38+
}
39+
2740
init(containerInfo->name, containerInfo->type,
2841
containerInfo->columnInfoList, containerInfo->columnCount,
29-
containerInfo->rowKeyAssigned, NULL);
42+
containerInfo->rowKeyAssigned, info, dataAffinity);
43+
if (info) {
44+
delete info;
45+
}
3046
//Assign values from argument to mContainer
3147
GSTimeSeriesProperties* gsProps = NULL;
3248
GSTriggerInfo* triggerInfoList = NULL;
@@ -40,11 +56,6 @@ namespace griddb {
4056
triggerInfoList = new GSTriggerInfo();
4157
}
4258

43-
if (containerInfo->dataAffinity) {
44-
Util::strdup(&mContainerInfo.dataAffinity, containerInfo->dataAffinity);
45-
} else {
46-
mContainerInfo.dataAffinity = NULL;
47-
}
4859
} catch (bad_alloc& ba) {
4960
//case allocation memory error
5061
if (gsProps) {
@@ -59,6 +70,12 @@ namespace griddb {
5970
throw GSException("Memory allocation error");
6071
}
6172

73+
if (containerInfo->dataAffinity) {
74+
Util::strdup(&mContainerInfo.dataAffinity, containerInfo->dataAffinity);
75+
} else {
76+
mContainerInfo.dataAffinity = NULL;
77+
}
78+
6279
if (containerInfo->timeSeriesProperties) {
6380
memcpy(gsProps, containerInfo->timeSeriesProperties, sizeof(GSTimeSeriesProperties));
6481
}
@@ -86,16 +103,18 @@ namespace griddb {
86103
* @param *expiration Stores the information about option of TimeSeries configuration
87104
*/
88105
ContainerInfo::ContainerInfo(const GSChar* name, const GSColumnInfo* props, int propsCount,
89-
GSContainerType type, bool row_key, ExpirationInfo* expiration) {
90-
init(name, type, props, propsCount, row_key, expiration);
106+
GSContainerType type, bool row_key, ExpirationInfo* expiration,
107+
const char* dataAffinity) {
108+
init(name, type, props, propsCount, row_key, expiration, dataAffinity);
91109
}
92110

93111
/**
94112
* Initialize values of Container Info object
95113
*/
96114
void ContainerInfo::init(const GSChar* name,
97115
GSContainerType type, const GSColumnInfo* props,
98-
int propsCount, bool rowKeyAssigned, ExpirationInfo* expiration) {
116+
int propsCount, bool rowKeyAssigned, ExpirationInfo* expiration,
117+
const char* dataAffinity) {
99118
GSColumnInfo* columnInfoList = NULL;
100119
GSChar* containerName = NULL;
101120
GSTimeSeriesProperties* timeProps = NULL;
@@ -152,6 +171,11 @@ namespace griddb {
152171
mExpInfo = NULL;
153172
mColumnInfoList.columnInfo = NULL;
154173
mColumnInfoList.size = 0;
174+
if (dataAffinity) {
175+
Util::strdup(&mContainerInfo.dataAffinity, dataAffinity);
176+
} else {
177+
mContainerInfo.dataAffinity = NULL;
178+
}
155179
}
156180

157181
ContainerInfo::~ContainerInfo() {
@@ -374,4 +398,33 @@ namespace griddb {
374398
return mExpInfo;
375399
}
376400

401+
/**
402+
* @brief Support set attribute ContainerInfo.dataAffinity
403+
*
404+
* @param affinity
405+
*/
406+
void ContainerInfo::set_affinity(const char* affinity) {
407+
if (mContainerInfo.dataAffinity) {
408+
delete[] mContainerInfo.dataAffinity;
409+
}
410+
if (affinity == NULL) {
411+
mContainerInfo.dataAffinity = NULL;
412+
} else {
413+
try {
414+
Util::strdup(&(mContainerInfo.dataAffinity), affinity);
415+
} catch (bad_alloc& ba) {
416+
throw GSException("Memory allocation error");
417+
}
418+
}
419+
}
420+
421+
/**
422+
* @brief Support get attribute ContainerInfo.dataAffinity
423+
*
424+
* @return const char*
425+
*/
426+
const char* ContainerInfo::get_affinity() {
427+
return mContainerInfo.dataAffinity;
428+
}
429+
377430
} /* namespace griddb */

src/ContainerInfo.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ class ContainerInfo {
5454
ContainerInfo(GSContainerInfo *containerInfo);
5555
ContainerInfo(const GSChar* name, const GSColumnInfo* props,
5656
int propsCount, GSContainerType type = GS_CONTAINER_COLLECTION,
57-
bool row_key = true, ExpirationInfo* expiration = NULL);
57+
bool row_key = true, ExpirationInfo* expiration = NULL,
58+
const char* dataAffinity = NULL);
5859
~ContainerInfo();
5960

6061
void set_name(GSChar* containerName);
@@ -69,10 +70,13 @@ class ContainerInfo {
6970
void set_expiration_info(ExpirationInfo* expirationInfo);
7071
bool get_row_key_assigned();
7172
GSContainerInfo* gs_info();
73+
void set_affinity(const char* affinity);
74+
const char* get_affinity();
7275

7376
private:
7477
void init(const GSChar* name, GSContainerType type, const GSColumnInfo* props,
75-
int propsCount, bool rowKeyAssigned, ExpirationInfo* expiration);
78+
int propsCount, bool rowKeyAssigned, ExpirationInfo* expiration,
79+
const char* dataAffinity);
7680
};
7781

7882
} /* namespace griddb */

src/griddb.i

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@
5050
%feature("new") griddb::Store::partition_info;
5151
%feature("new") griddb::StoreFactory::get_store;
5252
%feature("new") griddb::StoreFactory::get_instance;
53+
%feature("new") griddb::Container::query_by_time_series_range;
54+
%feature("new") griddb::Container::aggregate_time_series;
55+
%feature("new") griddb::Container::query_by_time_series_range;
56+
%feature("new") griddb::Container::aggregate_time_series;
57+
%feature("new") griddb::Container::query_by_time_series_sampling;
5358

5459
#if defined(SWIGPYTHON)
5560
%include "gstype_python.i"

src/gstype_python.i

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,30 @@ class TypeOption(IntEnum):
109109
return int(self.value)
110110
NULLABLE = 1 << 1
111111
NOT_NULL = 1 << 2
112+
113+
class QueryOrder(IntEnum):
114+
def __int__(self):
115+
return int(self.value)
116+
ASCENDING = 0
117+
DESCENDING = 1
118+
119+
class Aggregation(IntEnum):
120+
def __int__(self):
121+
return int(self.value)
122+
MINIMUM = 0
123+
MAXIMUM = 1
124+
TOTAL = 2
125+
AVERAGE = 3
126+
VARIANCE = 4
127+
STANDARD_DEVIATION = 5
128+
COUNT = 6
129+
WEIGHTED_AVERAGE = 7
130+
131+
class InterpolationMode(IntEnum):
132+
def __int__(self):
133+
return int(self.value)
134+
LINEAR_OR_PREVIOUS = 0
135+
EMPTY = 1
112136
}
113137

114138
%include <attribute.i>
@@ -2266,6 +2290,8 @@ static bool getRowFields(GSRow* row, int columnCount, GSType* typeList, bool tim
22662290

22672291
//Attribute ContainerInfo::columnInfoList
22682292
%attributeval(griddb::ContainerInfo, ColumnInfoList, column_info_list, get_column_info_list, set_column_info_list);
2293+
//Read and write attribute ContainerInfo::dataAffinity
2294+
%attribute(griddb::ContainerInfo, char*, dataAffinity, get_affinity, set_affinity);
22692295

22702296
/**
22712297
* Typemap for Container::multi_put
@@ -2717,3 +2743,59 @@ static bool checkNullField(GSRow* row, int32_t rowField) {
27172743
delete [] $1;
27182744
}
27192745
}
2746+
2747+
// Create typemap for Container::query_by_time_series_range
2748+
%typemap(in, fragment= "convertObjectToGSTimestamp") (GSTimestamp*)
2749+
(GSTimestamp timestamp) {
2750+
2751+
$1 = &timestamp;
2752+
if (!(convertObjectToGSTimestamp($input, $1))) {
2753+
%variable_fail(1, "String", "can not convert to GSTimestamp pointer based on input");
2754+
}
2755+
}
2756+
2757+
%typemap(typecheck) (GSTimestamp*) {
2758+
}
2759+
2760+
%typemap(in) (GSQueryOrder) {
2761+
int checkConvert = SWIG_AsVal_int($input, &$1);
2762+
if (!SWIG_IsOK(checkConvert)) {
2763+
PyErr_SetString(PyExc_ValueError, "Invalid value for GSQueryOrder value");
2764+
SWIG_fail;
2765+
}
2766+
}
2767+
%typemap(typecheck) (GSQueryOrder) {
2768+
}
2769+
2770+
// Create typemap for GSAggregation type
2771+
%typemap(in) (GSAggregation) {
2772+
int checkConvert = SWIG_AsVal_int($input, &$1);
2773+
if (!SWIG_IsOK(checkConvert)) {
2774+
PyErr_SetString(PyExc_ValueError, "Invalid value for GSAggregation value");
2775+
SWIG_fail;
2776+
}
2777+
}
2778+
%typemap(typecheck) (GSAggregation) {
2779+
}
2780+
2781+
// Create typemap for Container::query_by_time_series_sampling
2782+
%typemap(in, fragment="convertObjectToStringArray") (const GSChar *const *columnSet, size_t columnCount) {
2783+
if (!convertObjectToStringArray($input, &$1, &$2)) {
2784+
PyErr_SetString(PyExc_ValueError,
2785+
"Invalid value for const GSChar *const *columnSet, size_t columnCount");
2786+
SWIG_fail;
2787+
}
2788+
}
2789+
2790+
%typemap(freearg, fragment="cleanStringArray") (const GSChar *const *columnSet, size_t columnCount) {
2791+
cleanStringArray($1, $2);
2792+
}
2793+
2794+
// Create typemap for GSInterpolationMode type
2795+
%typemap(in) (GSInterpolationMode) {
2796+
int checkConvert = SWIG_AsVal_int($input, &$1);
2797+
if (!SWIG_IsOK(checkConvert)) {
2798+
PyErr_SetString(PyExc_ValueError, "Invalid value for GSInterpolationMode value");
2799+
SWIG_fail;
2800+
}
2801+
}

0 commit comments

Comments
 (0)