durable_rules 2.00.3 → 2.0.4
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/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
|