durable_rules 0.34.35 → 0.34.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/librb/durable.rb +28 -35
- data/librb/engine.rb +1 -0
- data/src/rules/events.c +161 -12
- data/src/rules/rete.c +128 -24
- data/src/rules/rete.h +2 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 47e6483313e3fe7047cb09fea58da4f5bf3c0c25
|
|
4
|
+
data.tar.gz: fcc1f99df7b9cb4b932af7bb9eb749265c82dfa4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 32bbe82822555390ca0a164945fb9a1ec6017f14a8f492e2fe5b9e1d6830ae7bc6a5c31e0b9e47017839c9f85cea0b6201875d9c43363acc4e9e845598243783
|
|
7
|
+
data.tar.gz: 1214ab05cdd4ebc38344378394fb7f4cb979b9921a8975701c4389aefc0f6df3d8a7c4b89ef2bbe6e6b3f4909426f2b53c06d10951c1abc8f63fb7a770a5a994
|
data/librb/durable.rb
CHANGED
|
@@ -175,12 +175,13 @@ module Durable
|
|
|
175
175
|
attr_reader :__type, :__op
|
|
176
176
|
attr_accessor :__name
|
|
177
177
|
|
|
178
|
-
def initialize(type, left = nil)
|
|
178
|
+
def initialize(type, left = nil, op = nil, right = nil, definitions = nil, name = nil)
|
|
179
179
|
@__type = type
|
|
180
180
|
@left = left
|
|
181
|
-
@
|
|
182
|
-
@
|
|
183
|
-
@
|
|
181
|
+
@__op = op
|
|
182
|
+
@right = right
|
|
183
|
+
@definitions = definitions
|
|
184
|
+
@__name = name
|
|
184
185
|
end
|
|
185
186
|
|
|
186
187
|
def definition(parent_name=nil)
|
|
@@ -190,7 +191,7 @@ module Durable
|
|
|
190
191
|
new_definition = {@__op => @definitions}
|
|
191
192
|
else
|
|
192
193
|
if not @left
|
|
193
|
-
raise ArgumentError, "Property for #{@__op} not defined"
|
|
194
|
+
raise ArgumentError, "Property for #{@__type} and #{@__op} not defined"
|
|
194
195
|
end
|
|
195
196
|
righ_definition = @right
|
|
196
197
|
if (@right.kind_of? Expression) || (@right.kind_of? Arithmetic)
|
|
@@ -216,63 +217,51 @@ module Durable
|
|
|
216
217
|
end
|
|
217
218
|
|
|
218
219
|
def ==(other)
|
|
219
|
-
@
|
|
220
|
-
@right = other
|
|
221
|
-
self
|
|
220
|
+
Expression.new(@__type, @left, :$eq, other, @definitions, @__name)
|
|
222
221
|
end
|
|
223
222
|
|
|
224
223
|
def !=(other)
|
|
225
|
-
@
|
|
226
|
-
@right = other
|
|
227
|
-
self
|
|
224
|
+
Expression.new(@__type, @left, :$neq, other, @definitions, @__name)
|
|
228
225
|
end
|
|
229
226
|
|
|
230
227
|
def <(other)
|
|
231
|
-
@
|
|
232
|
-
@right = other
|
|
233
|
-
self
|
|
228
|
+
Expression.new(@__type, @left, :$lt, other, @definitions, @__name)
|
|
234
229
|
end
|
|
235
230
|
|
|
236
231
|
def <=(other)
|
|
237
|
-
@
|
|
238
|
-
@right = other
|
|
239
|
-
self
|
|
232
|
+
Expression.new(@__type, @left, :$lte, other, @definitions, @__name)
|
|
240
233
|
end
|
|
241
234
|
|
|
242
235
|
def >(other)
|
|
243
|
-
@
|
|
244
|
-
@right = other
|
|
245
|
-
self
|
|
236
|
+
Expression.new(@__type, @left, :$gt, other, @definitions, @__name)
|
|
246
237
|
end
|
|
247
238
|
|
|
248
239
|
def >=(other)
|
|
249
|
-
@
|
|
250
|
-
@right = other
|
|
251
|
-
self
|
|
240
|
+
Expression.new(@__type, @left, :$gte, other, @definitions, @__name)
|
|
252
241
|
end
|
|
253
242
|
|
|
254
243
|
def matches(other)
|
|
255
|
-
@
|
|
256
|
-
@right = other
|
|
257
|
-
self
|
|
244
|
+
Expression.new(@__type, @left, :$mt, other, @definitions, @__name)
|
|
258
245
|
end
|
|
259
246
|
|
|
260
247
|
def imatches(other)
|
|
261
|
-
@
|
|
262
|
-
|
|
263
|
-
|
|
248
|
+
Expression.new(@__type, @left, :$imt, other, @definitions, @__name)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def allItems(other)
|
|
252
|
+
Expression.new(@__type, @left, :$iall, other, @definitions, @__name)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def anyItem(other)
|
|
256
|
+
Expression.new(@__type, @left, :$iany, other, @definitions, @__name)
|
|
264
257
|
end
|
|
265
258
|
|
|
266
259
|
def -@
|
|
267
|
-
@
|
|
268
|
-
@right = 1
|
|
269
|
-
self
|
|
260
|
+
Expression.new(@__type, @left, :$nex, 1, @definitions, @__name)
|
|
270
261
|
end
|
|
271
262
|
|
|
272
263
|
def +@
|
|
273
|
-
@
|
|
274
|
-
@right = 1
|
|
275
|
-
self
|
|
264
|
+
Expression.new(@__type, @left, :$ex, 1, @definitions, @__name)
|
|
276
265
|
end
|
|
277
266
|
|
|
278
267
|
def |(other)
|
|
@@ -440,6 +429,10 @@ module Durable
|
|
|
440
429
|
Expression.new(:$m)
|
|
441
430
|
end
|
|
442
431
|
|
|
432
|
+
def item
|
|
433
|
+
Expression.new(:$i, :$i)
|
|
434
|
+
end
|
|
435
|
+
|
|
443
436
|
def c
|
|
444
437
|
Closure.new()
|
|
445
438
|
end
|
data/librb/engine.rb
CHANGED
data/src/rules/events.c
CHANGED
|
@@ -45,6 +45,8 @@
|
|
|
45
45
|
#define OP_NIL_STRING 0x0701
|
|
46
46
|
#define OP_NIL_NIL 0x0707
|
|
47
47
|
|
|
48
|
+
#define HASH_I 1622948014 //$i
|
|
49
|
+
|
|
48
50
|
typedef struct actionContext {
|
|
49
51
|
void *rulesBinding;
|
|
50
52
|
redisReply *reply;
|
|
@@ -727,13 +729,12 @@ static unsigned int isMatch(ruleset *tree,
|
|
|
727
729
|
unsigned char alphaOp = currentAlpha->operator;
|
|
728
730
|
unsigned char propertyType = currentProperty->type;
|
|
729
731
|
unsigned int result = RULES_OK;
|
|
730
|
-
|
|
731
732
|
*propertyMatch = 0;
|
|
732
733
|
if (alphaOp == OP_EX) {
|
|
733
734
|
*propertyMatch = 1;
|
|
734
735
|
return RULES_OK;
|
|
735
736
|
}
|
|
736
|
-
|
|
737
|
+
|
|
737
738
|
rehydrateProperty(currentProperty, message);
|
|
738
739
|
jsonProperty rightValue;
|
|
739
740
|
jsonProperty *rightProperty = &rightValue;
|
|
@@ -929,6 +930,142 @@ static unsigned int isMatch(ruleset *tree,
|
|
|
929
930
|
return result;
|
|
930
931
|
}
|
|
931
932
|
|
|
933
|
+
static unsigned int isArrayMatch(ruleset *tree,
|
|
934
|
+
char *sid,
|
|
935
|
+
char *message,
|
|
936
|
+
jsonObject *messageObject,
|
|
937
|
+
jsonProperty *currentProperty,
|
|
938
|
+
alpha *arrayAlpha,
|
|
939
|
+
unsigned char *propertyMatch,
|
|
940
|
+
void **rulesBinding) {
|
|
941
|
+
*propertyMatch = 0;
|
|
942
|
+
unsigned int result = RULES_OK;
|
|
943
|
+
if (currentProperty->type != JSON_ARRAY) {
|
|
944
|
+
return RULES_OK;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
char *first = currentProperty->valueString;
|
|
948
|
+
char *last;
|
|
949
|
+
unsigned char type;
|
|
950
|
+
jsonObject jo;
|
|
951
|
+
result = readNextArrayValue(first, &first, &last, &type);
|
|
952
|
+
while (result == PARSE_OK) {
|
|
953
|
+
unsigned short top = 1;
|
|
954
|
+
alpha *stack[MAX_STACK_SIZE];
|
|
955
|
+
stack[0] = arrayAlpha;
|
|
956
|
+
alpha *currentAlpha;
|
|
957
|
+
if (type == JSON_OBJECT) {
|
|
958
|
+
char *next;
|
|
959
|
+
jo.propertiesLength = 0;
|
|
960
|
+
result = constructObject(first,
|
|
961
|
+
"$i",
|
|
962
|
+
NULL,
|
|
963
|
+
JSON_OBJECT_SEQUENCED,
|
|
964
|
+
0,
|
|
965
|
+
&jo,
|
|
966
|
+
&next);
|
|
967
|
+
if (result != RULES_OK) {
|
|
968
|
+
return result;
|
|
969
|
+
}
|
|
970
|
+
} else {
|
|
971
|
+
jo.propertiesLength = 1;
|
|
972
|
+
jo.properties[0].hash = HASH_I;
|
|
973
|
+
jo.properties[0].type = type;
|
|
974
|
+
jo.properties[0].isMaterial = 0;
|
|
975
|
+
jo.properties[0].valueString = first;
|
|
976
|
+
jo.properties[0].valueLength = last - first;
|
|
977
|
+
jo.properties[0].nameLength = 2;
|
|
978
|
+
strcpy(jo.properties[0].name, "$i");
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
while (top) {
|
|
982
|
+
--top;
|
|
983
|
+
currentAlpha = stack[top];
|
|
984
|
+
if (currentAlpha->nextListOffset) {
|
|
985
|
+
unsigned int *nextList = &tree->nextPool[currentAlpha->nextListOffset];
|
|
986
|
+
for (unsigned int entry = 0; nextList[entry] != 0; ++entry) {
|
|
987
|
+
node *listNode = &tree->nodePool[nextList[entry]];
|
|
988
|
+
char exists = 0;
|
|
989
|
+
for(unsigned int propertyIndex = 0; propertyIndex < jo.propertiesLength; ++propertyIndex) {
|
|
990
|
+
if (listNode->value.a.hash == jo.properties[propertyIndex].hash) {
|
|
991
|
+
exists = 1;
|
|
992
|
+
break;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
if (!exists) {
|
|
997
|
+
if (top == MAX_STACK_SIZE) {
|
|
998
|
+
return ERR_MAX_STACK_SIZE;
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
stack[top] = &listNode->value.a;
|
|
1002
|
+
++top;
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
if (currentAlpha->nextOffset) {
|
|
1008
|
+
unsigned int *nextHashset = &tree->nextPool[currentAlpha->nextOffset];
|
|
1009
|
+
for(unsigned int propertyIndex = 0; propertyIndex < jo.propertiesLength; ++propertyIndex) {
|
|
1010
|
+
jsonProperty *currentProperty = &jo.properties[propertyIndex];
|
|
1011
|
+
for (unsigned int entry = currentProperty->hash & HASH_MASK; nextHashset[entry] != 0; entry = (entry + 1) % NEXT_BUCKET_LENGTH) {
|
|
1012
|
+
node *hashNode = &tree->nodePool[nextHashset[entry]];
|
|
1013
|
+
if (currentProperty->hash == hashNode->value.a.hash) {
|
|
1014
|
+
unsigned char match = 0;
|
|
1015
|
+
if (hashNode->value.a.operator == OP_IALL || hashNode->value.a.operator == OP_IANY) {
|
|
1016
|
+
result = isArrayMatch(tree,
|
|
1017
|
+
sid,
|
|
1018
|
+
message,
|
|
1019
|
+
messageObject,
|
|
1020
|
+
currentProperty,
|
|
1021
|
+
&hashNode->value.a,
|
|
1022
|
+
&match,
|
|
1023
|
+
rulesBinding);
|
|
1024
|
+
} else {
|
|
1025
|
+
result = isMatch(tree,
|
|
1026
|
+
sid,
|
|
1027
|
+
message,
|
|
1028
|
+
messageObject,
|
|
1029
|
+
currentProperty,
|
|
1030
|
+
&hashNode->value.a,
|
|
1031
|
+
&match,
|
|
1032
|
+
rulesBinding);
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
if (result != RULES_OK) {
|
|
1036
|
+
return result;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
if (match) {
|
|
1040
|
+
if (top == MAX_STACK_SIZE) {
|
|
1041
|
+
return ERR_MAX_STACK_SIZE;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
stack[top] = &hashNode->value.a;
|
|
1045
|
+
++top;
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
if(currentAlpha->betaListOffset && currentAlpha != arrayAlpha) {
|
|
1053
|
+
*propertyMatch = 1;
|
|
1054
|
+
break;
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
if ((arrayAlpha->operator == OP_IALL && !*propertyMatch) ||
|
|
1059
|
+
(arrayAlpha->operator == OP_IANY && *propertyMatch)) {
|
|
1060
|
+
break;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
result = readNextArrayValue(last, &first, &last, &type);
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
return (result == PARSE_END ? RULES_OK: result);
|
|
1067
|
+
}
|
|
1068
|
+
|
|
932
1069
|
static unsigned int handleAlpha(ruleset *tree,
|
|
933
1070
|
char *sid,
|
|
934
1071
|
char *mid,
|
|
@@ -941,7 +1078,7 @@ static unsigned int handleAlpha(ruleset *tree,
|
|
|
941
1078
|
char **addKeys,
|
|
942
1079
|
unsigned int *addCount,
|
|
943
1080
|
char **removeCommand,
|
|
944
|
-
void **rulesBinding) {
|
|
1081
|
+
void **rulesBinding) {
|
|
945
1082
|
unsigned int result = ERR_EVENT_NOT_HANDLED;
|
|
946
1083
|
unsigned short top = 1;
|
|
947
1084
|
unsigned int entry;
|
|
@@ -965,7 +1102,6 @@ static unsigned int handleAlpha(ruleset *tree,
|
|
|
965
1102
|
|
|
966
1103
|
if (!exists) {
|
|
967
1104
|
if (top == MAX_STACK_SIZE) {
|
|
968
|
-
printf("exiting 1\n");
|
|
969
1105
|
return ERR_MAX_STACK_SIZE;
|
|
970
1106
|
}
|
|
971
1107
|
|
|
@@ -990,14 +1126,27 @@ static unsigned int handleAlpha(ruleset *tree,
|
|
|
990
1126
|
++top;
|
|
991
1127
|
} else {
|
|
992
1128
|
unsigned char match = 0;
|
|
993
|
-
unsigned int mresult =
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1129
|
+
unsigned int mresult = RULES_OK;
|
|
1130
|
+
if (hashNode->value.a.operator == OP_IALL || hashNode->value.a.operator == OP_IANY) {
|
|
1131
|
+
mresult = isArrayMatch(tree,
|
|
1132
|
+
sid,
|
|
1133
|
+
message,
|
|
1134
|
+
jo,
|
|
1135
|
+
currentProperty,
|
|
1136
|
+
&hashNode->value.a,
|
|
1137
|
+
&match,
|
|
1138
|
+
rulesBinding);
|
|
1139
|
+
} else {
|
|
1140
|
+
mresult = isMatch(tree,
|
|
1141
|
+
sid,
|
|
1142
|
+
message,
|
|
1143
|
+
jo,
|
|
1144
|
+
currentProperty,
|
|
1145
|
+
&hashNode->value.a,
|
|
1146
|
+
&match,
|
|
1147
|
+
rulesBinding);
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1001
1150
|
if (mresult != RULES_OK){
|
|
1002
1151
|
return mresult;
|
|
1003
1152
|
}
|
data/src/rules/rete.c
CHANGED
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
#define HASH_NEQ 2488026869 // $neq
|
|
22
22
|
#define HASH_MT 576092554 // $mt
|
|
23
23
|
#define HASH_IMT 1472564215 // $imt
|
|
24
|
+
#define HASH_IALL 3261766877 // $iall
|
|
25
|
+
#define HASH_IANY 3379504400 // $iany
|
|
24
26
|
#define HASH_EX 373481198 // $ex
|
|
25
27
|
#define HASH_NEX 2605470202 // $nex
|
|
26
28
|
#define HASH_OR 340911698 // $or
|
|
@@ -615,6 +617,12 @@ static unsigned int validateExpression(char *rule) {
|
|
|
615
617
|
case HASH_IMT:
|
|
616
618
|
operator = OP_IMT;
|
|
617
619
|
break;
|
|
620
|
+
case HASH_IALL:
|
|
621
|
+
operator = OP_IALL;
|
|
622
|
+
break;
|
|
623
|
+
case HASH_IANY:
|
|
624
|
+
operator = OP_IANY;
|
|
625
|
+
break;
|
|
618
626
|
case HASH_LT:
|
|
619
627
|
operator = OP_LT;
|
|
620
628
|
break;
|
|
@@ -665,6 +673,11 @@ static unsigned int validateExpression(char *rule) {
|
|
|
665
673
|
return result;
|
|
666
674
|
}
|
|
667
675
|
|
|
676
|
+
if (operator == OP_IALL || operator == OP_IANY) {
|
|
677
|
+
result = validateExpression(first);
|
|
678
|
+
return result;
|
|
679
|
+
}
|
|
680
|
+
|
|
668
681
|
if (operator == OP_MT || operator == OP_IMT) {
|
|
669
682
|
if (type != JSON_STRING) {
|
|
670
683
|
return ERR_UNEXPECTED_TYPE;
|
|
@@ -825,8 +838,7 @@ static unsigned int linkAlpha(ruleset *tree,
|
|
|
825
838
|
}
|
|
826
839
|
|
|
827
840
|
parentBetaList[entry] = nextOffset;
|
|
828
|
-
}
|
|
829
|
-
else if (nextNode->value.a.operator == OP_NEX) {
|
|
841
|
+
} else if (nextNode->value.a.operator == OP_NEX) {
|
|
830
842
|
result = ensureNextList(tree, parentAlpha);
|
|
831
843
|
if (result != RULES_OK) {
|
|
832
844
|
return result;
|
|
@@ -841,8 +853,7 @@ static unsigned int linkAlpha(ruleset *tree,
|
|
|
841
853
|
}
|
|
842
854
|
|
|
843
855
|
parentNextList[entry] = nextOffset;
|
|
844
|
-
}
|
|
845
|
-
else {
|
|
856
|
+
} else {
|
|
846
857
|
result = ensureNextHashset(tree, parentAlpha);
|
|
847
858
|
if (result != RULES_OK) {
|
|
848
859
|
return result;
|
|
@@ -896,8 +907,7 @@ static unsigned int readReference(ruleset *tree, char *rule, unsigned char *idio
|
|
|
896
907
|
if (result != RULES_OK) {
|
|
897
908
|
return result;
|
|
898
909
|
}
|
|
899
|
-
}
|
|
900
|
-
else {
|
|
910
|
+
} else {
|
|
901
911
|
readNextValue(last, &first, &last, &type);
|
|
902
912
|
result = readNextName(first, &first, &last, &hash);
|
|
903
913
|
while (result == PARSE_OK) {
|
|
@@ -1034,7 +1044,7 @@ static unsigned int findAlpha(ruleset *tree,
|
|
|
1034
1044
|
|
|
1035
1045
|
readNextName(rule, &firstName, &lastName, &hash);
|
|
1036
1046
|
readNextValue(lastName, &first, &last, &type);
|
|
1037
|
-
if (type == JSON_OBJECT) {
|
|
1047
|
+
if (type == JSON_OBJECT && operator != OP_IALL && operator != OP_IANY) {
|
|
1038
1048
|
result = readIdiom(tree, first, &type, &idiomOffset, &ref);
|
|
1039
1049
|
if (result != RULES_OK) {
|
|
1040
1050
|
return result;
|
|
@@ -1049,9 +1059,11 @@ static unsigned int findAlpha(ruleset *tree,
|
|
|
1049
1059
|
node *currentNode = &tree->nodePool[parentNext[entry]];
|
|
1050
1060
|
if (currentNode->value.a.hash == hash &&
|
|
1051
1061
|
currentNode->value.a.operator == operator) {
|
|
1052
|
-
if (
|
|
1053
|
-
|
|
1054
|
-
|
|
1062
|
+
if (operator != OP_IALL && operator != OP_IANY) {
|
|
1063
|
+
if (compareValue(tree, ¤tNode->value.a.right, first, last, &ref, type)) {
|
|
1064
|
+
*resultOffset = parentNext[entry];
|
|
1065
|
+
return RULES_OK;
|
|
1066
|
+
}
|
|
1055
1067
|
}
|
|
1056
1068
|
}
|
|
1057
1069
|
}
|
|
@@ -1061,11 +1073,13 @@ static unsigned int findAlpha(ruleset *tree,
|
|
|
1061
1073
|
parentNext = &tree->nextPool[parent->value.a.nextListOffset];
|
|
1062
1074
|
for (entry = 0; parentNext[entry] != 0; ++entry) {
|
|
1063
1075
|
node *currentNode = &tree->nodePool[parentNext[entry]];
|
|
1064
|
-
if (currentNode->value.a.hash == hash&&
|
|
1076
|
+
if (currentNode->value.a.hash == hash &&
|
|
1065
1077
|
currentNode->value.a.operator == operator) {
|
|
1066
|
-
if (
|
|
1067
|
-
|
|
1068
|
-
|
|
1078
|
+
if (operator != OP_IALL && operator != OP_IANY) {
|
|
1079
|
+
if (compareValue(tree, ¤tNode->value.a.right, first, last, &ref, type)) {
|
|
1080
|
+
*resultOffset = parentNext[entry];
|
|
1081
|
+
return RULES_OK;
|
|
1082
|
+
}
|
|
1069
1083
|
}
|
|
1070
1084
|
}
|
|
1071
1085
|
}
|
|
@@ -1095,17 +1109,21 @@ static unsigned int findAlpha(ruleset *tree,
|
|
|
1095
1109
|
type = JSON_IREGEX;
|
|
1096
1110
|
}
|
|
1097
1111
|
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
if (type == JSON_EVENT_PROPERTY || type == JSON_EVENT_IDIOM) {
|
|
1104
|
-
result = appendTerm(expr, *resultOffset);
|
|
1112
|
+
if (operator == OP_IANY || operator == OP_IALL) {
|
|
1113
|
+
type = JSON_NIL;
|
|
1114
|
+
} else {
|
|
1115
|
+
result = copyValue(tree, &newAlpha->value.a.right, first, last, idiomOffset, &ref, type);
|
|
1105
1116
|
if (result != RULES_OK) {
|
|
1106
1117
|
return result;
|
|
1107
1118
|
}
|
|
1108
|
-
|
|
1119
|
+
|
|
1120
|
+
if (type == JSON_EVENT_PROPERTY || type == JSON_EVENT_IDIOM) {
|
|
1121
|
+
result = appendTerm(expr, *resultOffset);
|
|
1122
|
+
if (result != RULES_OK) {
|
|
1123
|
+
return result;
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1109
1127
|
|
|
1110
1128
|
return linkAlpha(tree, parentOffset, *resultOffset);
|
|
1111
1129
|
}
|
|
@@ -1184,6 +1202,12 @@ static unsigned int createAlpha(ruleset *tree,
|
|
|
1184
1202
|
case HASH_IMT:
|
|
1185
1203
|
operator = OP_IMT;
|
|
1186
1204
|
break;
|
|
1205
|
+
case HASH_IALL:
|
|
1206
|
+
operator = OP_IALL;
|
|
1207
|
+
break;
|
|
1208
|
+
case HASH_IANY:
|
|
1209
|
+
operator = OP_IANY;
|
|
1210
|
+
break;
|
|
1187
1211
|
case HASH_LT:
|
|
1188
1212
|
operator = OP_LT;
|
|
1189
1213
|
break;
|
|
@@ -1268,6 +1292,23 @@ static unsigned int createAlpha(ruleset *tree,
|
|
|
1268
1292
|
readNextValue(last, &first, &last, &type);
|
|
1269
1293
|
}
|
|
1270
1294
|
|
|
1295
|
+
if (operator == OP_IANY || operator == OP_IALL) {
|
|
1296
|
+
unsigned int result = findAlpha(tree, parentOffset, operator, first, expr, newOffset);
|
|
1297
|
+
if (result != RULES_OK) {
|
|
1298
|
+
return result;
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
unsigned int inner_offset = *newOffset;
|
|
1302
|
+
readNextName(first, &first, &last, &hash);
|
|
1303
|
+
readNextValue(last, &first, &last, &type);
|
|
1304
|
+
result = createAlpha(tree, first, expr, nextOffset, &inner_offset);
|
|
1305
|
+
if (result != RULES_OK) {
|
|
1306
|
+
return result;
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
return linkAlpha(tree, *newOffset, nextOffset);
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1271
1312
|
if (nextOffset == 0) {
|
|
1272
1313
|
return findAlpha(tree, parentOffset, operator, first, expr, newOffset);
|
|
1273
1314
|
} else {
|
|
@@ -1662,6 +1703,66 @@ static unsigned int fixupQueries(ruleset *tree, unsigned int actionOffset, char*
|
|
|
1662
1703
|
return RULES_OK;
|
|
1663
1704
|
}
|
|
1664
1705
|
|
|
1706
|
+
#ifdef _PRINT
|
|
1707
|
+
|
|
1708
|
+
static void printActionNode(ruleset *tree, node *actionNode, int level) {
|
|
1709
|
+
for (int i = 0; i < level; ++ i) {
|
|
1710
|
+
printf(" ");
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
printf("-> action: name %s, count %d, cap %d, priority %d\n",
|
|
1714
|
+
&tree->stringPool[actionNode->nameOffset],
|
|
1715
|
+
actionNode->value.c.count,
|
|
1716
|
+
actionNode->value.c.cap,
|
|
1717
|
+
actionNode->value.c.priority);
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
static void printBetaNode(ruleset *tree, node *betaNode, int level) {
|
|
1721
|
+
for (int i = 0; i < level; ++ i) {
|
|
1722
|
+
printf(" ");
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
printf("-> beta: name %s, not %d\n", &tree->stringPool[betaNode->nameOffset], betaNode->value.b.not);
|
|
1726
|
+
node *currentNode = &tree->nodePool[betaNode->value.b.nextOffset];
|
|
1727
|
+
if (currentNode->type == NODE_ACTION) {
|
|
1728
|
+
printActionNode(tree, currentNode, level + 1);
|
|
1729
|
+
} else {
|
|
1730
|
+
printBetaNode(tree, currentNode, level + 1);
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
static void printAlphaNode(ruleset *tree, node *alphaNode, int level) {
|
|
1735
|
+
for (int i = 0; i < level; ++ i) {
|
|
1736
|
+
printf(" ");
|
|
1737
|
+
}
|
|
1738
|
+
|
|
1739
|
+
printf("-> alpha: name %s, operator %x\n", &tree->stringPool[alphaNode->nameOffset], alphaNode->value.a.operator);
|
|
1740
|
+
if (alphaNode->value.a.nextOffset) {
|
|
1741
|
+
unsigned int *nextHashset = &tree->nextPool[alphaNode->value.a.nextOffset];
|
|
1742
|
+
for (unsigned int entry = 0; entry < NEXT_BUCKET_LENGTH; ++entry) {
|
|
1743
|
+
if (nextHashset[entry]) {
|
|
1744
|
+
printAlphaNode(tree, &tree->nodePool[nextHashset[entry]], level + 1);
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
if (alphaNode->value.a.nextListOffset) {
|
|
1750
|
+
unsigned int *nextList = &tree->nextPool[alphaNode->value.a.nextListOffset];
|
|
1751
|
+
for (unsigned int entry = 0; nextList[entry] != 0; ++entry) {
|
|
1752
|
+
printAlphaNode(tree, &tree->nodePool[nextList[entry]], level + 1);
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
if (alphaNode->value.a.betaListOffset) {
|
|
1757
|
+
unsigned int *betaList = &tree->nextPool[alphaNode->value.a.betaListOffset];
|
|
1758
|
+
for (unsigned int entry = 0; betaList[entry] != 0; ++entry) {
|
|
1759
|
+
printBetaNode(tree, &tree->nodePool[betaList[entry]], level + 1);
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
#endif
|
|
1765
|
+
|
|
1665
1766
|
static unsigned int createTree(ruleset *tree, char *rules) {
|
|
1666
1767
|
char *first;
|
|
1667
1768
|
char *last;
|
|
@@ -1706,12 +1807,11 @@ static unsigned int createTree(ruleset *tree, char *rules) {
|
|
|
1706
1807
|
readNextValue(lastName, &first, &lastRuleValue, &type);
|
|
1707
1808
|
ruleAction->value.c.priority = 0;
|
|
1708
1809
|
ruleAction->value.c.count = 0;
|
|
1709
|
-
ruleAction->value.c.span = 0;
|
|
1710
1810
|
ruleAction->value.c.cap = 0;
|
|
1711
1811
|
getSetting(HASH_PRI, first, &ruleAction->value.c.priority);
|
|
1712
1812
|
getSetting(HASH_COUNT, first, &ruleAction->value.c.count);
|
|
1713
1813
|
getSetting(HASH_CAP, first, &ruleAction->value.c.cap);
|
|
1714
|
-
if (!ruleAction->value.c.count && !ruleAction->value.c.
|
|
1814
|
+
if (!ruleAction->value.c.count && !ruleAction->value.c.cap) {
|
|
1715
1815
|
ruleAction->value.c.count = 1;
|
|
1716
1816
|
}
|
|
1717
1817
|
|
|
@@ -1741,6 +1841,10 @@ static unsigned int createTree(ruleset *tree, char *rules) {
|
|
|
1741
1841
|
result = readNextName(lastRuleValue, &firstName, &lastName, &hash);
|
|
1742
1842
|
}
|
|
1743
1843
|
|
|
1844
|
+
#ifdef _PRINT
|
|
1845
|
+
printAlphaNode(tree, &tree->nodePool[NODE_M_OFFSET], 0);
|
|
1846
|
+
#endif
|
|
1847
|
+
|
|
1744
1848
|
return RULES_OK;
|
|
1745
1849
|
}
|
|
1746
1850
|
|
data/src/rules/rete.h
CHANGED
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
#define OP_NOT 0x13
|
|
23
23
|
#define OP_MT 0x14
|
|
24
24
|
#define OP_IMT 0x15
|
|
25
|
+
#define OP_IALL 0x16
|
|
26
|
+
#define OP_IANY 0x17
|
|
25
27
|
|
|
26
28
|
#define NODE_ALPHA 0
|
|
27
29
|
#define NODE_BETA_CONNECTOR 1
|
|
@@ -93,7 +95,6 @@ typedef struct betaConnector {
|
|
|
93
95
|
|
|
94
96
|
typedef struct action {
|
|
95
97
|
unsigned int index;
|
|
96
|
-
unsigned short span;
|
|
97
98
|
unsigned short count;
|
|
98
99
|
unsigned short cap;
|
|
99
100
|
unsigned short priority;
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: durable_rules
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.34.
|
|
4
|
+
version: 0.34.36
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jesus Ruiz
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-06-
|
|
11
|
+
date: 2017-06-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rake
|