durable_rules 2.00.3 → 2.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/src/rules/events.c +127 -75
- data/src/rules/rete.c +84 -56
- data/src/rules/rete.h +3 -1
- data/src/rules/state.c +7 -4
- 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: 0adaaf5bd93fde23db48196c84cc4c19a6e54eab
|
4
|
+
data.tar.gz: f4a48336da9a8b928da8baf5b0288796b89820e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e23ee1d4cbf5e2b42e5054bb862c56b502473759e3d468b66c12e08b41a8dba35a96845c30c2a57d003a9f7cd0ed61653ac830dcf579a9013bb48c65b2e361d7
|
7
|
+
data.tar.gz: aaf8e986ee09e907c794145f2d9cd2052cf75a1e1c4493c38e750a3d32eefbb9e701cf3234b7bc4280d736c9c2b8b2dfeb537f8b45a8069483ccb2397878ae7a
|
data/src/rules/events.c
CHANGED
@@ -1403,12 +1403,82 @@ static unsigned int handleBetaMessage(ruleset *tree,
|
|
1403
1403
|
messageHash);
|
1404
1404
|
}
|
1405
1405
|
|
1406
|
+
static unsigned int isArrayMatch(ruleset *tree,
|
1407
|
+
jsonObject *messageObject,
|
1408
|
+
jsonProperty *currentProperty,
|
1409
|
+
alpha *arrayAlpha,
|
1410
|
+
unsigned char *propertyMatch);
|
1406
1411
|
|
1407
|
-
static unsigned int
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
+
static unsigned int isNextMatch(ruleset *tree,
|
1413
|
+
jsonObject *jo,
|
1414
|
+
alpha *currentAlpha,
|
1415
|
+
unsigned char *propertyMatch) {
|
1416
|
+
*propertyMatch = 0;
|
1417
|
+
if (currentAlpha->nextListOffset) {
|
1418
|
+
unsigned int *nextList = &tree->nextPool[currentAlpha->nextListOffset];
|
1419
|
+
for (unsigned int entry = 0; nextList[entry] != 0; ++entry) {
|
1420
|
+
node *listNode = &tree->nodePool[nextList[entry]];
|
1421
|
+
jsonProperty *currentProperty;
|
1422
|
+
unsigned int aresult = getObjectProperty(jo, listNode->value.a.expression.left.value.id.propertyNameHash, ¤tProperty);
|
1423
|
+
if (aresult == ERR_PROPERTY_NOT_FOUND) {
|
1424
|
+
*propertyMatch = 1;
|
1425
|
+
if (listNode->value.a.nextOffset || listNode->value.a.nextListOffset) {
|
1426
|
+
CHECK_RESULT(isNextMatch(tree,
|
1427
|
+
jo,
|
1428
|
+
&listNode->value.a,
|
1429
|
+
propertyMatch));
|
1430
|
+
}
|
1431
|
+
|
1432
|
+
if (*propertyMatch) {
|
1433
|
+
break;
|
1434
|
+
}
|
1435
|
+
|
1436
|
+
}
|
1437
|
+
}
|
1438
|
+
}
|
1439
|
+
|
1440
|
+
if (currentAlpha->nextOffset) {
|
1441
|
+
unsigned int *nextHashset = &tree->nextPool[currentAlpha->nextOffset];
|
1442
|
+
for(unsigned int propertyIndex = 0; propertyIndex < jo->propertiesLength; ++propertyIndex) {
|
1443
|
+
jsonProperty *currentProperty = &jo->properties[propertyIndex];
|
1444
|
+
for (unsigned int entry = currentProperty->hash & HASH_MASK; nextHashset[entry] != 0; entry = (entry + 1) % NEXT_BUCKET_LENGTH) {
|
1445
|
+
node *hashNode = &tree->nodePool[nextHashset[entry]];
|
1446
|
+
if (hashNode->value.a.expression.operator == OP_IALL || hashNode->value.a.expression.operator == OP_IANY) {
|
1447
|
+
CHECK_RESULT(isArrayMatch(tree,
|
1448
|
+
jo,
|
1449
|
+
currentProperty,
|
1450
|
+
&hashNode->value.a,
|
1451
|
+
propertyMatch));
|
1452
|
+
} else {
|
1453
|
+
CHECK_RESULT(isAlphaMatch(tree,
|
1454
|
+
&hashNode->value.a,
|
1455
|
+
jo,
|
1456
|
+
propertyMatch));
|
1457
|
+
}
|
1458
|
+
|
1459
|
+
if (*propertyMatch && (hashNode->value.a.nextOffset || hashNode->value.a.nextListOffset)) {
|
1460
|
+
CHECK_RESULT(isNextMatch(tree,
|
1461
|
+
jo,
|
1462
|
+
&hashNode->value.a,
|
1463
|
+
propertyMatch));
|
1464
|
+
|
1465
|
+
}
|
1466
|
+
|
1467
|
+
if (*propertyMatch) {
|
1468
|
+
break;
|
1469
|
+
}
|
1470
|
+
}
|
1471
|
+
}
|
1472
|
+
}
|
1473
|
+
|
1474
|
+
return RULES_OK;
|
1475
|
+
}
|
1476
|
+
|
1477
|
+
static unsigned int isArrayMatch(ruleset *tree,
|
1478
|
+
jsonObject *messageObject,
|
1479
|
+
jsonProperty *currentProperty,
|
1480
|
+
alpha *arrayAlpha,
|
1481
|
+
unsigned char *propertyMatch) {
|
1412
1482
|
unsigned int result = RULES_OK;
|
1413
1483
|
if (currentProperty->type != JSON_ARRAY) {
|
1414
1484
|
return RULES_OK;
|
@@ -1421,10 +1491,6 @@ static unsigned int handleAplhaArray(ruleset *tree,
|
|
1421
1491
|
result = readNextArrayValue(first, &first, &last, &type);
|
1422
1492
|
while (result == PARSE_OK) {
|
1423
1493
|
*propertyMatch = 0;
|
1424
|
-
unsigned short top = 1;
|
1425
|
-
alpha *stack[MAX_STACK_SIZE];
|
1426
|
-
stack[0] = arrayAlpha;
|
1427
|
-
alpha *currentAlpha;
|
1428
1494
|
if (type == JSON_OBJECT) {
|
1429
1495
|
char *next;
|
1430
1496
|
jo.propertiesLength = 0;
|
@@ -1450,75 +1516,61 @@ static unsigned int handleAplhaArray(ruleset *tree,
|
|
1450
1516
|
last - first + 1));
|
1451
1517
|
}
|
1452
1518
|
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
unsigned int
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
if (!exists) {
|
1471
|
-
if (top == MAX_STACK_SIZE) {
|
1472
|
-
return ERR_MAX_STACK_SIZE;
|
1473
|
-
}
|
1474
|
-
|
1475
|
-
stack[top] = &listNode->value.a;
|
1476
|
-
++top;
|
1519
|
+
if (arrayAlpha->nextListOffset) {
|
1520
|
+
unsigned int *nextList = &tree->nextPool[arrayAlpha->nextListOffset];
|
1521
|
+
for (unsigned int entry = 0; nextList[entry] != 0; ++entry) {
|
1522
|
+
node *listNode = &tree->nodePool[nextList[entry]];
|
1523
|
+
jsonProperty *currentProperty;
|
1524
|
+
unsigned int aresult = getObjectProperty(&jo, listNode->value.a.expression.left.value.id.propertyNameHash, ¤tProperty);
|
1525
|
+
if (aresult == ERR_PROPERTY_NOT_FOUND) {
|
1526
|
+
*propertyMatch = 1;
|
1527
|
+
if (listNode->value.a.nextOffset || listNode->value.a.nextListOffset) {
|
1528
|
+
CHECK_RESULT(isNextMatch(tree,
|
1529
|
+
&jo,
|
1530
|
+
&listNode->value.a,
|
1531
|
+
propertyMatch));
|
1532
|
+
}
|
1533
|
+
|
1534
|
+
if (*propertyMatch) {
|
1535
|
+
break;
|
1477
1536
|
}
|
1537
|
+
|
1478
1538
|
}
|
1479
1539
|
}
|
1540
|
+
}
|
1480
1541
|
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1499
|
-
&hashNode->value.a,
|
1500
|
-
&jo,
|
1501
|
-
&match));
|
1542
|
+
if (arrayAlpha->arrayListOffset) {
|
1543
|
+
unsigned int *nextHashset = &tree->nextPool[arrayAlpha->arrayListOffset];
|
1544
|
+
for(unsigned int propertyIndex = 0; propertyIndex < jo.propertiesLength; ++propertyIndex) {
|
1545
|
+
jsonProperty *currentProperty = &jo.properties[propertyIndex];
|
1546
|
+
for (unsigned int entry = currentProperty->hash & HASH_MASK; nextHashset[entry] != 0; entry = (entry + 1) % NEXT_BUCKET_LENGTH) {
|
1547
|
+
node *hashNode = &tree->nodePool[nextHashset[entry]];
|
1548
|
+
if (hashNode->value.a.expression.operator == OP_IALL || hashNode->value.a.expression.operator == OP_IANY) {
|
1549
|
+
CHECK_RESULT(isArrayMatch(tree,
|
1550
|
+
&jo,
|
1551
|
+
currentProperty,
|
1552
|
+
&hashNode->value.a,
|
1553
|
+
propertyMatch));
|
1554
|
+
} else {
|
1555
|
+
CHECK_RESULT(isAlphaMatch(tree,
|
1556
|
+
&hashNode->value.a,
|
1557
|
+
&jo,
|
1558
|
+
propertyMatch));
|
1559
|
+
}
|
1502
1560
|
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1561
|
+
if (*propertyMatch && hashNode->value.a.nextOffset) {
|
1562
|
+
CHECK_RESULT(isNextMatch(tree,
|
1563
|
+
&jo,
|
1564
|
+
&hashNode->value.a,
|
1565
|
+
propertyMatch));
|
1507
1566
|
|
1508
|
-
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
}
|
1567
|
+
}
|
1568
|
+
|
1569
|
+
if (*propertyMatch && (hashNode->value.a.nextOffset || hashNode->value.a.nextListOffset)) {
|
1570
|
+
break;
|
1571
|
+
}
|
1514
1572
|
}
|
1515
1573
|
}
|
1516
|
-
|
1517
|
-
// no next offset and no nextListOffest means we found a valid path
|
1518
|
-
if (!currentAlpha->nextOffset && !currentAlpha->nextListOffset) {
|
1519
|
-
*propertyMatch = 1;
|
1520
|
-
break;
|
1521
|
-
}
|
1522
1574
|
}
|
1523
1575
|
|
1524
1576
|
// OP_IANY, one element led a a valid path
|
@@ -1586,11 +1638,11 @@ static unsigned int handleAlpha(ruleset *tree,
|
|
1586
1638
|
} else {
|
1587
1639
|
unsigned char match = 0;
|
1588
1640
|
if (hashNode->value.a.expression.operator == OP_IALL || hashNode->value.a.expression.operator == OP_IANY) {
|
1589
|
-
CHECK_RESULT(
|
1590
|
-
|
1591
|
-
|
1592
|
-
|
1593
|
-
|
1641
|
+
CHECK_RESULT(isArrayMatch(tree,
|
1642
|
+
jo,
|
1643
|
+
currentProperty,
|
1644
|
+
&hashNode->value.a,
|
1645
|
+
&match));
|
1594
1646
|
} else {
|
1595
1647
|
CHECK_RESULT(isAlphaMatch(tree,
|
1596
1648
|
&hashNode->value.a,
|
data/src/rules/rete.c
CHANGED
@@ -156,6 +156,7 @@ static unsigned int storeAlpha(ruleset *tree,
|
|
156
156
|
return result;
|
157
157
|
}
|
158
158
|
|
159
|
+
(*newNode)->value.a.arrayListOffset = 0;
|
159
160
|
(*newNode)->value.a.nextListOffset = 0;
|
160
161
|
(*newNode)->value.a.betaListOffset = 0;
|
161
162
|
(*newNode)->value.a.nextOffset = 0;
|
@@ -189,6 +190,13 @@ static unsigned int allocateNext(ruleset *tree,
|
|
189
190
|
return RULES_OK;
|
190
191
|
}
|
191
192
|
|
193
|
+
static unsigned int ensureNextArrayHashset(ruleset *tree, node *newNode) {
|
194
|
+
if (!newNode->value.a.arrayListOffset) {
|
195
|
+
return allocateNext(tree, NEXT_BUCKET_LENGTH, &newNode->value.a.arrayListOffset);
|
196
|
+
}
|
197
|
+
|
198
|
+
return RULES_OK;
|
199
|
+
}
|
192
200
|
|
193
201
|
static unsigned int ensureNextHashset(ruleset *tree, node *newNode) {
|
194
202
|
if (!newNode->value.a.nextOffset) {
|
@@ -753,9 +761,14 @@ static unsigned int validateRuleset(char *rules) {
|
|
753
761
|
return (result == PARSE_END ? PARSE_OK: result);
|
754
762
|
}
|
755
763
|
|
756
|
-
static unsigned int linkAlpha(ruleset *tree,
|
764
|
+
static unsigned int linkAlpha(ruleset *tree,
|
765
|
+
char linkToArray,
|
757
766
|
unsigned int parentOffset,
|
758
767
|
unsigned int nextOffset) {
|
768
|
+
if (!nextOffset) {
|
769
|
+
return RULES_OK;
|
770
|
+
}
|
771
|
+
|
759
772
|
unsigned int entry;
|
760
773
|
node *parentAlpha = &tree->nodePool[parentOffset];
|
761
774
|
node *nextNode = &tree->nodePool[nextOffset];
|
@@ -785,10 +798,19 @@ static unsigned int linkAlpha(ruleset *tree,
|
|
785
798
|
|
786
799
|
parentNextList[entry] = nextOffset;
|
787
800
|
} else {
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
801
|
+
unsigned int *parentNext = NULL;
|
802
|
+
if ((parentAlpha->value.a.expression.operator == OP_IALL || parentAlpha->value.a.expression.operator == OP_IANY) && linkToArray) {
|
803
|
+
CHECK_RESULT(ensureNextArrayHashset(tree,
|
804
|
+
parentAlpha));
|
805
|
+
|
806
|
+
parentNext = &tree->nextPool[parentAlpha->value.a.arrayListOffset];
|
807
|
+
} else {
|
808
|
+
CHECK_RESULT(ensureNextHashset(tree,
|
809
|
+
parentAlpha));
|
810
|
+
|
811
|
+
parentNext = &tree->nextPool[parentAlpha->value.a.nextOffset];
|
812
|
+
}
|
813
|
+
|
792
814
|
unsigned int hash = nextNode->value.a.expression.left.value.id.propertyNameHash;
|
793
815
|
for (entry = hash & HASH_MASK; parentNext[entry] != 0; entry = (entry + 1) % NEXT_BUCKET_LENGTH) {
|
794
816
|
if ((entry + 1) % NEXT_BUCKET_LENGTH == (hash & HASH_MASK)) {
|
@@ -923,6 +945,7 @@ static unsigned int findAlpha(ruleset *tree,
|
|
923
945
|
unsigned int parentOffset,
|
924
946
|
unsigned char operator,
|
925
947
|
char *rule,
|
948
|
+
char linkToArray,
|
926
949
|
unsigned int betaOffset,
|
927
950
|
unsigned int *resultOffset) {
|
928
951
|
char *first;
|
@@ -1000,6 +1023,7 @@ static unsigned int findAlpha(ruleset *tree,
|
|
1000
1023
|
|
1001
1024
|
newAlpha->nameOffset = stringOffset;
|
1002
1025
|
newAlpha->type = NODE_ALPHA;
|
1026
|
+
newAlpha->value.a.stringOffset = stringOffset;
|
1003
1027
|
newAlpha->value.a.expression.left.type = JSON_MESSAGE_IDENTIFIER;
|
1004
1028
|
newAlpha->value.a.expression.left.value.id.propertyNameHash = hash;
|
1005
1029
|
newAlpha->value.a.expression.left.value.id.propertyNameOffset = newAlpha->nameOffset;
|
@@ -1014,27 +1038,23 @@ static unsigned int findAlpha(ruleset *tree,
|
|
1014
1038
|
type = JSON_IREGEX;
|
1015
1039
|
}
|
1016
1040
|
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
}
|
1035
|
-
//}
|
1036
|
-
|
1037
|
-
return linkAlpha(tree, parentOffset, *resultOffset);
|
1041
|
+
CHECK_RESULT(copyValue(tree,
|
1042
|
+
&newAlpha->value.a.expression.right,
|
1043
|
+
first,
|
1044
|
+
last,
|
1045
|
+
expressionOffset,
|
1046
|
+
&id,
|
1047
|
+
type));
|
1048
|
+
|
1049
|
+
if (type == JSON_IDENTIFIER || type == JSON_EXPRESSION) {
|
1050
|
+
expression *expr;
|
1051
|
+
GET_EXPRESSION(tree,
|
1052
|
+
betaOffset,
|
1053
|
+
expr);
|
1054
|
+
copyExpression(&newAlpha->value.a.expression, expr);
|
1055
|
+
}
|
1056
|
+
|
1057
|
+
return linkAlpha(tree, linkToArray, parentOffset, *resultOffset);
|
1038
1058
|
}
|
1039
1059
|
|
1040
1060
|
static unsigned int getSetting(unsigned int settingHash, char *rule, unsigned short *value) {
|
@@ -1077,6 +1097,7 @@ static unsigned int createForwardAlpha(ruleset *tree,
|
|
1077
1097
|
|
1078
1098
|
newAlpha->nameOffset = 0;
|
1079
1099
|
newAlpha->type = NODE_ALPHA;
|
1100
|
+
newAlpha->value.a.arrayListOffset = 0;
|
1080
1101
|
newAlpha->value.a.expression.left.type = JSON_MESSAGE_IDENTIFIER;
|
1081
1102
|
newAlpha->value.a.expression.left.value.id.propertyNameOffset = 0;
|
1082
1103
|
newAlpha->value.a.expression.left.value.id.propertyNameHash = HASH_FORWARD;
|
@@ -1089,6 +1110,7 @@ static unsigned int createForwardAlpha(ruleset *tree,
|
|
1089
1110
|
|
1090
1111
|
static unsigned int createAlpha(ruleset *tree,
|
1091
1112
|
char *rule,
|
1113
|
+
char linkToArray,
|
1092
1114
|
unsigned int betaOffset,
|
1093
1115
|
unsigned int nextOffset,
|
1094
1116
|
unsigned int *newOffset) {
|
@@ -1159,10 +1181,12 @@ static unsigned int createAlpha(ruleset *tree,
|
|
1159
1181
|
while (result == PARSE_OK) {
|
1160
1182
|
CHECK_RESULT(createAlpha(tree,
|
1161
1183
|
first,
|
1184
|
+
linkToArray,
|
1162
1185
|
betaOffset,
|
1163
1186
|
0,
|
1164
1187
|
&resultOffset));
|
1165
1188
|
|
1189
|
+
linkToArray = 0;
|
1166
1190
|
previousOffset = resultOffset;
|
1167
1191
|
result = readNextArrayValue(last,
|
1168
1192
|
&first,
|
@@ -1176,6 +1200,7 @@ static unsigned int createAlpha(ruleset *tree,
|
|
1176
1200
|
OP_END);
|
1177
1201
|
if (nextOffset != 0) {
|
1178
1202
|
return linkAlpha(tree,
|
1203
|
+
0,
|
1179
1204
|
previousOffset,
|
1180
1205
|
nextOffset);
|
1181
1206
|
}
|
@@ -1196,11 +1221,13 @@ static unsigned int createAlpha(ruleset *tree,
|
|
1196
1221
|
unsigned int single_offset = parentOffset;
|
1197
1222
|
CHECK_RESULT(createAlpha(tree,
|
1198
1223
|
first,
|
1224
|
+
linkToArray,
|
1199
1225
|
betaOffset,
|
1200
1226
|
0,
|
1201
1227
|
&single_offset));
|
1202
1228
|
|
1203
1229
|
CHECK_RESULT(linkAlpha(tree,
|
1230
|
+
0,
|
1204
1231
|
single_offset,
|
1205
1232
|
*newOffset));
|
1206
1233
|
|
@@ -1216,6 +1243,7 @@ static unsigned int createAlpha(ruleset *tree,
|
|
1216
1243
|
OP_END);
|
1217
1244
|
if (nextOffset != 0) {
|
1218
1245
|
return linkAlpha(tree,
|
1246
|
+
0,
|
1219
1247
|
*newOffset,
|
1220
1248
|
nextOffset);
|
1221
1249
|
}
|
@@ -1237,7 +1265,8 @@ static unsigned int createAlpha(ruleset *tree,
|
|
1237
1265
|
CHECK_RESULT(findAlpha(tree,
|
1238
1266
|
parentOffset,
|
1239
1267
|
operator,
|
1240
|
-
first,
|
1268
|
+
first,
|
1269
|
+
linkToArray,
|
1241
1270
|
betaOffset,
|
1242
1271
|
newOffset));
|
1243
1272
|
|
@@ -1254,38 +1283,19 @@ static unsigned int createAlpha(ruleset *tree,
|
|
1254
1283
|
|
1255
1284
|
CHECK_RESULT(createAlpha(tree,
|
1256
1285
|
first,
|
1286
|
+
1,
|
1257
1287
|
betaOffset,
|
1258
|
-
|
1288
|
+
0,
|
1259
1289
|
&inner_offset));
|
1260
1290
|
|
1261
1291
|
node *newAlpha = &tree->nodePool[inner_offset];
|
1262
1292
|
if (newAlpha->value.a.expression.right.type != JSON_IDENTIFIER && newAlpha->value.a.expression.right.type != JSON_EXPRESSION) {
|
1263
|
-
return linkAlpha(tree,
|
1293
|
+
return linkAlpha(tree,
|
1294
|
+
0,
|
1264
1295
|
*newOffset,
|
1265
1296
|
nextOffset);
|
1266
1297
|
} else {
|
1267
|
-
|
1268
|
-
node *oldAlpha = &tree->nodePool[*newOffset];
|
1269
|
-
expression *newExpression = NULL;
|
1270
|
-
unsigned int expressionOffset = 0;
|
1271
|
-
CHECK_RESULT(storeExpression(tree,
|
1272
|
-
&newExpression,
|
1273
|
-
&expressionOffset));
|
1274
|
-
|
1275
|
-
oldAlpha->value.a.expression.right.type = JSON_EXPRESSION;
|
1276
|
-
oldAlpha->value.a.expression.right.value.expressionOffset = expressionOffset;
|
1277
|
-
copyExpression(&newAlpha->value.a.expression, newExpression);
|
1278
|
-
|
1279
|
-
expression *betaExpression;
|
1280
|
-
GET_EXPRESSION(tree,
|
1281
|
-
betaOffset,
|
1282
|
-
betaExpression);
|
1283
|
-
|
1284
|
-
copyExpression(newExpression, betaExpression);
|
1285
|
-
|
1286
|
-
return linkAlpha(tree,
|
1287
|
-
*newOffset,
|
1288
|
-
nextOffset);
|
1298
|
+
return ERR_UNEXPECTED_TYPE;
|
1289
1299
|
}
|
1290
1300
|
}
|
1291
1301
|
|
@@ -1294,6 +1304,7 @@ static unsigned int createAlpha(ruleset *tree,
|
|
1294
1304
|
parentOffset,
|
1295
1305
|
operator,
|
1296
1306
|
first,
|
1307
|
+
linkToArray,
|
1297
1308
|
betaOffset,
|
1298
1309
|
newOffset);
|
1299
1310
|
} else {
|
@@ -1301,10 +1312,12 @@ static unsigned int createAlpha(ruleset *tree,
|
|
1301
1312
|
parentOffset,
|
1302
1313
|
operator,
|
1303
1314
|
first,
|
1315
|
+
linkToArray,
|
1304
1316
|
betaOffset,
|
1305
1317
|
newOffset));
|
1306
1318
|
|
1307
|
-
return linkAlpha(tree,
|
1319
|
+
return linkAlpha(tree,
|
1320
|
+
0,
|
1308
1321
|
*newOffset,
|
1309
1322
|
nextOffset);
|
1310
1323
|
}
|
@@ -1408,6 +1421,7 @@ static unsigned int createBeta(ruleset *tree,
|
|
1408
1421
|
&type));
|
1409
1422
|
CHECK_RESULT(createAlpha(tree,
|
1410
1423
|
first,
|
1424
|
+
0,
|
1411
1425
|
betaOffset,
|
1412
1426
|
betaOffset,
|
1413
1427
|
&resultOffset));
|
@@ -1626,11 +1640,15 @@ static void printBetaNode(ruleset *tree, node *betaNode, int level, unsigned int
|
|
1626
1640
|
}
|
1627
1641
|
}
|
1628
1642
|
|
1629
|
-
static void printAlphaNode(ruleset *tree, node *alphaNode, int level, unsigned int offset) {
|
1643
|
+
static void printAlphaNode(ruleset *tree, node *alphaNode, int level, char *prefix, unsigned int offset) {
|
1630
1644
|
for (int i = 0; i < level; ++ i) {
|
1631
1645
|
printf(" ");
|
1632
1646
|
}
|
1633
1647
|
|
1648
|
+
if (prefix) {
|
1649
|
+
printf("%s", prefix);
|
1650
|
+
}
|
1651
|
+
|
1634
1652
|
printf("-> alpha: name %s, offset %u\n", &tree->stringPool[alphaNode->nameOffset], offset);
|
1635
1653
|
|
1636
1654
|
for (int i = 0; i < level; ++ i) {
|
@@ -1640,11 +1658,20 @@ static void printAlphaNode(ruleset *tree, node *alphaNode, int level, unsigned i
|
|
1640
1658
|
printSimpleExpression(tree, &alphaNode->value.a.expression, 1, NULL);
|
1641
1659
|
|
1642
1660
|
printf("\n");
|
1661
|
+
if (alphaNode->value.a.arrayListOffset) {
|
1662
|
+
unsigned int *nextHashset = &tree->nextPool[alphaNode->value.a.arrayListOffset];
|
1663
|
+
for (unsigned int entry = 0; entry < NEXT_BUCKET_LENGTH; ++entry) {
|
1664
|
+
if (nextHashset[entry]) {
|
1665
|
+
printAlphaNode(tree, &tree->nodePool[nextHashset[entry]], level + 1, "Next Array ", nextHashset[entry]);
|
1666
|
+
}
|
1667
|
+
}
|
1668
|
+
}
|
1669
|
+
|
1643
1670
|
if (alphaNode->value.a.nextOffset) {
|
1644
1671
|
unsigned int *nextHashset = &tree->nextPool[alphaNode->value.a.nextOffset];
|
1645
1672
|
for (unsigned int entry = 0; entry < NEXT_BUCKET_LENGTH; ++entry) {
|
1646
1673
|
if (nextHashset[entry]) {
|
1647
|
-
printAlphaNode(tree, &tree->nodePool[nextHashset[entry]], level + 1, nextHashset[entry]);
|
1674
|
+
printAlphaNode(tree, &tree->nodePool[nextHashset[entry]], level + 1, "Next ", nextHashset[entry]);
|
1648
1675
|
}
|
1649
1676
|
}
|
1650
1677
|
}
|
@@ -1652,7 +1679,7 @@ static void printAlphaNode(ruleset *tree, node *alphaNode, int level, unsigned i
|
|
1652
1679
|
if (alphaNode->value.a.nextListOffset) {
|
1653
1680
|
unsigned int *nextList = &tree->nextPool[alphaNode->value.a.nextListOffset];
|
1654
1681
|
for (unsigned int entry = 0; nextList[entry] != 0; ++entry) {
|
1655
|
-
printAlphaNode(tree, &tree->nodePool[nextList[entry]], level + 1, nextList[entry]);
|
1682
|
+
printAlphaNode(tree, &tree->nodePool[nextList[entry]], level + 1, "Next List ", nextList[entry]);
|
1656
1683
|
}
|
1657
1684
|
}
|
1658
1685
|
|
@@ -1782,6 +1809,7 @@ static unsigned int createTree(ruleset *tree, char *rules) {
|
|
1782
1809
|
printAlphaNode(tree,
|
1783
1810
|
&tree->nodePool[NODE_M_OFFSET],
|
1784
1811
|
0,
|
1812
|
+
NULL,
|
1785
1813
|
NODE_M_OFFSET);
|
1786
1814
|
#endif
|
1787
1815
|
|
@@ -1845,7 +1873,7 @@ unsigned int createRuleset(unsigned int *handle, char *name, char *rules) {
|
|
1845
1873
|
newNode->nameOffset = stringOffset;
|
1846
1874
|
newNode->type = NODE_ALPHA;
|
1847
1875
|
newNode->value.a.expression.operator = OP_TYPE;
|
1848
|
-
|
1876
|
+
|
1849
1877
|
// will use random numbers for state stored event mids
|
1850
1878
|
srand(time(NULL));
|
1851
1879
|
CREATE_HANDLE(tree, handle);
|
data/src/rules/rete.h
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#include "state.h"
|
2
2
|
|
3
|
-
|
3
|
+
// #define _PRINT 1
|
4
4
|
|
5
5
|
#define OP_NOP 0
|
6
6
|
#define OP_LT 0x01
|
@@ -83,8 +83,10 @@ typedef struct expressionSequence {
|
|
83
83
|
|
84
84
|
typedef struct alpha {
|
85
85
|
expression expression;
|
86
|
+
unsigned int stringOffset;
|
86
87
|
unsigned int betaListOffset;
|
87
88
|
unsigned int nextListOffset;
|
89
|
+
unsigned int arrayListOffset;
|
88
90
|
unsigned int nextOffset;
|
89
91
|
} alpha;
|
90
92
|
|
data/src/rules/state.c
CHANGED
@@ -796,6 +796,9 @@ unsigned int ensureStateNode(void *tree,
|
|
796
796
|
sidHash,
|
797
797
|
nodeOffset);
|
798
798
|
|
799
|
+
if (rulesetTree->statePool.count > MAX_STATE_INDEX_LENGTH) {
|
800
|
+
return ERR_OUT_OF_MEMORY;
|
801
|
+
}
|
799
802
|
rulesetTree->reverseStateIndex[rulesetTree->statePool.count - 1] = nodeOffset;
|
800
803
|
stateNode *node = STATE_NODE(tree, nodeOffset);
|
801
804
|
node->offset = nodeOffset;
|
@@ -1118,7 +1121,7 @@ unsigned int getNextResult(void *tree,
|
|
1118
1121
|
static void insertSortProperties(jsonObject *jo, jsonProperty **properties) {
|
1119
1122
|
for (unsigned short i = 1; i < jo->propertiesLength; ++i) {
|
1120
1123
|
unsigned short ii = i;
|
1121
|
-
while (properties[ii]->hash < properties[ii - 1]->hash) {
|
1124
|
+
while (ii >= 1 && (properties[ii]->hash < properties[ii - 1]->hash)) {
|
1122
1125
|
jsonProperty *temp = properties[ii];
|
1123
1126
|
properties[ii] = properties[ii - 1];
|
1124
1127
|
properties[ii - 1] = temp;
|
@@ -1200,7 +1203,7 @@ unsigned int calculateId(jsonObject *jo) {
|
|
1200
1203
|
|
1201
1204
|
unsigned int candidate = HASH_ID % MAX_OBJECT_PROPERTIES;
|
1202
1205
|
while (jo->propertyIndex[candidate] != 0) {
|
1203
|
-
candidate = candidate + 1 % MAX_OBJECT_PROPERTIES;
|
1206
|
+
candidate = (candidate + 1) % MAX_OBJECT_PROPERTIES;
|
1204
1207
|
}
|
1205
1208
|
|
1206
1209
|
// Index intentionally offset by 1 to enable getObject
|
@@ -1234,7 +1237,7 @@ static unsigned int fixupIds(jsonObject *jo, char generateId) {
|
|
1234
1237
|
|
1235
1238
|
unsigned int candidate = HASH_SID % MAX_OBJECT_PROPERTIES;
|
1236
1239
|
while (jo->propertyIndex[candidate] != 0) {
|
1237
|
-
candidate = candidate + 1 % MAX_OBJECT_PROPERTIES;
|
1240
|
+
candidate = (candidate + 1) % MAX_OBJECT_PROPERTIES;
|
1238
1241
|
}
|
1239
1242
|
|
1240
1243
|
// Index intentionally offset by 1 to enable getObject
|
@@ -1294,7 +1297,7 @@ unsigned int setObjectProperty(jsonObject *jo,
|
|
1294
1297
|
|
1295
1298
|
unsigned int candidate = hash % MAX_OBJECT_PROPERTIES;
|
1296
1299
|
while (jo->propertyIndex[candidate] != 0) {
|
1297
|
-
candidate = candidate + 1 % MAX_OBJECT_PROPERTIES;
|
1300
|
+
candidate = (candidate + 1) % MAX_OBJECT_PROPERTIES;
|
1298
1301
|
}
|
1299
1302
|
|
1300
1303
|
// Index intentionally offset by 1 to enable getObject
|
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: 2.
|
4
|
+
version: 2.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jesus Ruiz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-07-
|
11
|
+
date: 2019-07-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|