durable_rules 0.34.13 → 0.34.14
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 +9 -3
- data/librb/engine.rb +6 -6
- data/src/rules/Makefile +4 -3
- data/src/rules/events.c +13 -0
- data/src/rules/json.h +1 -0
- data/src/rules/net.c +90 -241
- data/src/rules/regex.c +1240 -0
- data/src/rules/regex.h +20 -0
- data/src/rules/rete.c +107 -26
- data/src/rules/rete.h +12 -0
- data/src/rules/rules.h +9 -1
- data/src/rulesrb/rules.c +6 -5
- metadata +4 -2
data/src/rules/regex.h
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
#define REGEX_PARSE_OK 0
|
3
|
+
#define REGEX_PARSE_END 100
|
4
|
+
|
5
|
+
unsigned int validateRegex(char *first,
|
6
|
+
char *last);
|
7
|
+
|
8
|
+
unsigned int compileRegex(void *tree,
|
9
|
+
char *first,
|
10
|
+
char *last,
|
11
|
+
unsigned short *vocabularyLength,
|
12
|
+
unsigned short *statesLength,
|
13
|
+
unsigned int *regexStateMachineOffset);
|
14
|
+
|
15
|
+
unsigned char evaluateRegex(void *tree,
|
16
|
+
char *first,
|
17
|
+
unsigned short length,
|
18
|
+
unsigned short vocabularyLength,
|
19
|
+
unsigned short statesLength,
|
20
|
+
unsigned int regexStateMachineOffset);
|
data/src/rules/rete.c
CHANGED
@@ -6,6 +6,7 @@
|
|
6
6
|
#include "rules.h"
|
7
7
|
#include "net.h"
|
8
8
|
#include "json.h"
|
9
|
+
#include "regex.h"
|
9
10
|
|
10
11
|
#define HASH_ALL 193486302 // all
|
11
12
|
#define HASH_ANY 193486381 // any
|
@@ -20,6 +21,7 @@
|
|
20
21
|
#define HASH_GTE 2087883433 // $gte
|
21
22
|
#define HASH_EQ 193419647 // $eq
|
22
23
|
#define HASH_NEQ 2087890573 // $neq
|
24
|
+
#define HASH_MT 193419914 // $mt
|
23
25
|
#define HASH_EX 193419654 // $ex
|
24
26
|
#define HASH_NEX 2087890580 // $nex
|
25
27
|
#define HASH_OR 193419978 // $or
|
@@ -290,13 +292,14 @@ static unsigned int ensureBetaList(ruleset *tree, node *newNode) {
|
|
290
292
|
return RULES_OK;
|
291
293
|
}
|
292
294
|
|
293
|
-
static
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
295
|
+
static unsigned int copyValue(ruleset *tree,
|
296
|
+
jsonValue *right,
|
297
|
+
char *first,
|
298
|
+
char *last,
|
299
|
+
unsigned int idiomOffset,
|
300
|
+
reference *ref,
|
301
|
+
unsigned char type) {
|
302
|
+
unsigned int result = RULES_OK;
|
300
303
|
right->type = type;
|
301
304
|
unsigned int leftLength;
|
302
305
|
char temp;
|
@@ -313,7 +316,7 @@ static void copyValue(ruleset *tree,
|
|
313
316
|
break;
|
314
317
|
case JSON_STRING:
|
315
318
|
leftLength = last - first;
|
316
|
-
storeString(tree, first, &right->value.stringOffset, leftLength);
|
319
|
+
result = storeString(tree, first, &right->value.stringOffset, leftLength);
|
317
320
|
break;
|
318
321
|
case JSON_INT:
|
319
322
|
temp = last[1];
|
@@ -335,7 +338,23 @@ static void copyValue(ruleset *tree,
|
|
335
338
|
}
|
336
339
|
right->value.b = leftb;
|
337
340
|
break;
|
341
|
+
case JSON_REGEX:
|
342
|
+
leftLength = last - first;
|
343
|
+
result = storeString(tree, first, &right->value.regex.stringOffset, leftLength);
|
344
|
+
if (result != RULES_OK) {
|
345
|
+
return result;
|
346
|
+
}
|
347
|
+
|
348
|
+
result = compileRegex(tree,
|
349
|
+
first,
|
350
|
+
last,
|
351
|
+
&right->value.regex.vocabularyLength,
|
352
|
+
&right->value.regex.statesLength,
|
353
|
+
&right->value.regex.stateMachineOffset);
|
354
|
+
break;
|
338
355
|
}
|
356
|
+
|
357
|
+
return result;
|
339
358
|
}
|
340
359
|
|
341
360
|
static unsigned char compareValue(ruleset *tree,
|
@@ -364,10 +383,18 @@ static unsigned char compareValue(ruleset *tree,
|
|
364
383
|
case JSON_EVENT_IDIOM:
|
365
384
|
return 0;
|
366
385
|
case JSON_STRING:
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
386
|
+
{
|
387
|
+
char *rightString;
|
388
|
+
if (right->type == JSON_REGEX) {
|
389
|
+
rightString = &tree->stringPool[right->value.regex.stringOffset];
|
390
|
+
} else {
|
391
|
+
rightString = &tree->stringPool[right->value.stringOffset];
|
392
|
+
}
|
393
|
+
|
394
|
+
leftLength = last - first;
|
395
|
+
unsigned int rightLength = strlen(rightString);
|
396
|
+
return (leftLength == rightLength ? !strncmp(rightString, first, rightLength): 0);
|
397
|
+
}
|
371
398
|
case JSON_INT:
|
372
399
|
temp = last[1];
|
373
400
|
last[1] = '\0';
|
@@ -560,6 +587,9 @@ static unsigned int validateExpression(char *rule) {
|
|
560
587
|
case HASH_NEX:
|
561
588
|
operator = OP_NEX;
|
562
589
|
break;
|
590
|
+
case HASH_MT:
|
591
|
+
operator = OP_MT;
|
592
|
+
break;
|
563
593
|
case HASH_LT:
|
564
594
|
operator = OP_LT;
|
565
595
|
break;
|
@@ -610,6 +640,17 @@ static unsigned int validateExpression(char *rule) {
|
|
610
640
|
return result;
|
611
641
|
}
|
612
642
|
|
643
|
+
if (operator == OP_MT) {
|
644
|
+
if (type != JSON_STRING) {
|
645
|
+
return ERR_UNEXPECTED_TYPE;
|
646
|
+
}
|
647
|
+
|
648
|
+
result = validateRegex(first, last);
|
649
|
+
if (result != PARSE_OK) {
|
650
|
+
return result;
|
651
|
+
}
|
652
|
+
}
|
653
|
+
|
613
654
|
if (type == JSON_ARRAY) {
|
614
655
|
return ERR_UNEXPECTED_TYPE;
|
615
656
|
}
|
@@ -807,42 +848,62 @@ static unsigned int linkAlpha(ruleset *tree,
|
|
807
848
|
return RULES_OK;
|
808
849
|
}
|
809
850
|
|
810
|
-
static unsigned
|
851
|
+
static unsigned int readReference(ruleset *tree, char *rule, unsigned char *idiomType, reference *ref) {
|
811
852
|
char *first;
|
812
853
|
char *last;
|
813
854
|
unsigned char type;
|
814
855
|
unsigned int hash;
|
815
|
-
unsigned
|
856
|
+
unsigned int result;
|
857
|
+
*idiomType = JSON_EVENT_PROPERTY;
|
816
858
|
|
817
859
|
ref->idOffset = 0;
|
818
860
|
readNextName(rule, &first, &last, &hash);
|
819
861
|
if (hash != HASH_S) {
|
820
|
-
storeString(tree, first, &ref->idOffset, last - first);
|
862
|
+
result = storeString(tree, first, &ref->idOffset, last - first);
|
863
|
+
if (result != RULES_OK) {
|
864
|
+
return result;
|
865
|
+
}
|
866
|
+
|
821
867
|
readNextString(last, &first, &last, &hash);
|
822
868
|
ref->hash = hash;
|
823
|
-
storeString(tree, first, &ref->nameOffset, last - first);
|
869
|
+
result = storeString(tree, first, &ref->nameOffset, last - first);
|
870
|
+
if (result != RULES_OK) {
|
871
|
+
return result;
|
872
|
+
}
|
824
873
|
} else {
|
825
|
-
|
874
|
+
*idiomType = JSON_STATE_PROPERTY;
|
826
875
|
if (readNextString(last, &first, &last, &hash) == PARSE_OK) {
|
827
876
|
ref->hash = hash;
|
828
|
-
storeString(tree, first, &ref->nameOffset, last - first);
|
877
|
+
result = storeString(tree, first, &ref->nameOffset, last - first);
|
878
|
+
if (result != RULES_OK) {
|
879
|
+
return result;
|
880
|
+
}
|
829
881
|
}
|
830
882
|
else {
|
831
883
|
readNextValue(last, &first, &last, &type);
|
832
|
-
|
884
|
+
result = readNextName(first, &first, &last, &hash);
|
833
885
|
while (result == PARSE_OK) {
|
834
886
|
switch (hash) {
|
835
887
|
case HASH_NAME:
|
836
888
|
readNextString(last, &first, &last, &hash);
|
837
889
|
ref->hash = hash;
|
838
|
-
storeString(tree, first, &ref->nameOffset, last - first);
|
890
|
+
result = storeString(tree, first, &ref->nameOffset, last - first);
|
891
|
+
if (result != RULES_OK) {
|
892
|
+
return result;
|
893
|
+
}
|
839
894
|
break;
|
840
895
|
case HASH_ID:
|
841
896
|
readNextValue(last, &first, &last, &type);
|
842
897
|
if (type == JSON_STRING) {
|
843
|
-
storeString(tree, first, &ref->idOffset, last - first);
|
898
|
+
result = storeString(tree, first, &ref->idOffset, last - first);
|
899
|
+
if (result != RULES_OK) {
|
900
|
+
return result;
|
901
|
+
}
|
844
902
|
} else{
|
845
|
-
storeString(tree, first, &ref->idOffset, last - first + 1);
|
903
|
+
result = storeString(tree, first, &ref->idOffset, last - first + 1);
|
904
|
+
if (result != RULES_OK) {
|
905
|
+
return result;
|
906
|
+
}
|
846
907
|
}
|
847
908
|
|
848
909
|
break;
|
@@ -856,7 +917,7 @@ static unsigned char readReference(ruleset *tree, char *rule, reference *ref) {
|
|
856
917
|
}
|
857
918
|
}
|
858
919
|
|
859
|
-
return
|
920
|
+
return RULES_OK;
|
860
921
|
}
|
861
922
|
|
862
923
|
static unsigned int readIdiom(ruleset *tree, char *rule, unsigned char *idiomType, unsigned int *idiomOffset, reference *ref) {
|
@@ -884,7 +945,10 @@ static unsigned int readIdiom(ruleset *tree, char *rule, unsigned char *idiomTyp
|
|
884
945
|
}
|
885
946
|
|
886
947
|
if (operator == OP_NOP) {
|
887
|
-
|
948
|
+
result = readReference(tree, rule, idiomType, ref);
|
949
|
+
if (result != RULES_OK) {
|
950
|
+
return result;
|
951
|
+
}
|
888
952
|
} else {
|
889
953
|
idiom *newIdiom = NULL;
|
890
954
|
result = storeIdiom(tree, &newIdiom, idiomOffset);
|
@@ -1001,13 +1065,21 @@ static unsigned int findAlpha(ruleset *tree,
|
|
1001
1065
|
newAlpha->type = NODE_ALPHA;
|
1002
1066
|
newAlpha->value.a.hash = hash;
|
1003
1067
|
newAlpha->value.a.operator = operator;
|
1004
|
-
|
1068
|
+
if (operator == OP_MT) {
|
1069
|
+
type = JSON_REGEX;
|
1070
|
+
}
|
1071
|
+
|
1072
|
+
result = copyValue(tree, &newAlpha->value.a.right, first, last, idiomOffset, &ref, type);
|
1073
|
+
if (result != RULES_OK) {
|
1074
|
+
return result;
|
1075
|
+
}
|
1076
|
+
|
1005
1077
|
if (type == JSON_EVENT_PROPERTY || type == JSON_EVENT_IDIOM) {
|
1006
1078
|
result = appendTerm(expr, *resultOffset);
|
1007
1079
|
if (result != RULES_OK) {
|
1008
1080
|
return result;
|
1009
1081
|
}
|
1010
|
-
}
|
1082
|
+
}
|
1011
1083
|
|
1012
1084
|
return linkAlpha(tree, parentOffset, *resultOffset);
|
1013
1085
|
}
|
@@ -1097,6 +1169,9 @@ static unsigned int createAlpha(ruleset *tree,
|
|
1097
1169
|
case HASH_NEX:
|
1098
1170
|
operator = OP_NEX;
|
1099
1171
|
break;
|
1172
|
+
case HASH_MT:
|
1173
|
+
operator = OP_MT;
|
1174
|
+
break;
|
1100
1175
|
case HASH_LT:
|
1101
1176
|
operator = OP_LT;
|
1102
1177
|
break;
|
@@ -1642,6 +1717,10 @@ static unsigned int createTree(ruleset *tree, char *rules) {
|
|
1642
1717
|
result = createBeta(tree, first, OP_ALL, actionOffset, NULL, &betaPath);
|
1643
1718
|
break;
|
1644
1719
|
}
|
1720
|
+
if (result != RULES_OK) {
|
1721
|
+
return result;
|
1722
|
+
}
|
1723
|
+
|
1645
1724
|
result = readNextName(last, &first, &last, &hash);
|
1646
1725
|
}
|
1647
1726
|
|
@@ -1682,6 +1761,8 @@ unsigned int createRuleset(void **handle, char *name, char *rules, unsigned int
|
|
1682
1761
|
tree->idiomOffset = 0;
|
1683
1762
|
tree->joinPool = NULL;
|
1684
1763
|
tree->joinOffset = 0;
|
1764
|
+
tree->regexStateMachinePool = NULL;
|
1765
|
+
tree->regexStateMachineOffset = 0;
|
1685
1766
|
tree->actionCount = 0;
|
1686
1767
|
tree->bindingsList = NULL;
|
1687
1768
|
tree->stateLength = 0;
|
data/src/rules/rete.h
CHANGED
@@ -20,6 +20,7 @@
|
|
20
20
|
#define OP_DIV 0x11
|
21
21
|
#define OP_TYPE 0x12
|
22
22
|
#define OP_NOT 0x13
|
23
|
+
#define OP_MT 0x14
|
23
24
|
|
24
25
|
#define NODE_ALPHA 0
|
25
26
|
#define NODE_BETA_CONNECTOR 1
|
@@ -32,6 +33,13 @@ typedef struct reference {
|
|
32
33
|
unsigned int idOffset;
|
33
34
|
} reference;
|
34
35
|
|
36
|
+
typedef struct regexReference {
|
37
|
+
unsigned int stringOffset;
|
38
|
+
unsigned int stateMachineOffset;
|
39
|
+
unsigned short statesLength;
|
40
|
+
unsigned short vocabularyLength;
|
41
|
+
} regexReference;
|
42
|
+
|
35
43
|
typedef struct jsonValue {
|
36
44
|
unsigned char type;
|
37
45
|
union {
|
@@ -40,6 +48,7 @@ typedef struct jsonValue {
|
|
40
48
|
unsigned char b;
|
41
49
|
unsigned int stringOffset;
|
42
50
|
unsigned int idiomOffset;
|
51
|
+
regexReference regex;
|
43
52
|
reference property;
|
44
53
|
} value;
|
45
54
|
} jsonValue;
|
@@ -102,6 +111,7 @@ typedef struct node {
|
|
102
111
|
} value;
|
103
112
|
} node;
|
104
113
|
|
114
|
+
|
105
115
|
typedef struct ruleset {
|
106
116
|
unsigned int nameOffset;
|
107
117
|
node *nodePool;
|
@@ -116,6 +126,8 @@ typedef struct ruleset {
|
|
116
126
|
unsigned int idiomOffset;
|
117
127
|
join *joinPool;
|
118
128
|
unsigned int joinOffset;
|
129
|
+
char *regexStateMachinePool;
|
130
|
+
unsigned int regexStateMachineOffset;
|
119
131
|
unsigned int actionCount;
|
120
132
|
void *bindingsList;
|
121
133
|
unsigned int *stateBuckets;
|
data/src/rules/rules.h
CHANGED
@@ -39,6 +39,13 @@
|
|
39
39
|
#define ERR_STALE_STATE 404
|
40
40
|
#define ERR_PROPERTY_NOT_FOUND 405
|
41
41
|
#define ERR_MAX_PROPERTY_NAME_LENGTH 406
|
42
|
+
#define ERR_PARSE_REGEX 501
|
43
|
+
#define ERR_REGEX_MAX_TRANSITIONS 502
|
44
|
+
#define ERR_REGEX_MAX_STATES 503
|
45
|
+
#define ERR_REGEX_QUEUE_FULL 504
|
46
|
+
#define ERR_REGEX_LIST_FULL 505
|
47
|
+
#define ERR_REGEX_SET_FULL 506
|
48
|
+
#define ERR_REGEX_CONFLICT 507
|
42
49
|
|
43
50
|
#define NEXT_BUCKET_LENGTH 512
|
44
51
|
#define NEXT_LIST_LENGTH 32
|
@@ -69,7 +76,8 @@ unsigned int deleteClient(void *handle);
|
|
69
76
|
unsigned int bindRuleset(void *handle,
|
70
77
|
char *host,
|
71
78
|
unsigned int port,
|
72
|
-
char *password
|
79
|
+
char *password,
|
80
|
+
unsigned char db);
|
73
81
|
|
74
82
|
unsigned int complete(void *rulesBinding,
|
75
83
|
unsigned int replyCount);
|
data/src/rulesrb/rules.c
CHANGED
@@ -67,16 +67,17 @@ static VALUE rbDeleteClient(VALUE self, VALUE handle) {
|
|
67
67
|
return Qnil;
|
68
68
|
}
|
69
69
|
|
70
|
-
static VALUE rbBindRuleset(VALUE self, VALUE handle, VALUE host, VALUE port, VALUE password) {
|
70
|
+
static VALUE rbBindRuleset(VALUE self, VALUE handle, VALUE host, VALUE port, VALUE password, VALUE db) {
|
71
71
|
Check_Type(handle, T_FIXNUM);
|
72
72
|
Check_Type(host, T_STRING);
|
73
73
|
Check_Type(port, T_FIXNUM);
|
74
|
-
|
74
|
+
Check_Type(db, T_FIXNUM);
|
75
|
+
|
75
76
|
unsigned int result;
|
76
77
|
if (TYPE(password) == T_STRING) {
|
77
|
-
result = bindRuleset((void *)FIX2LONG(handle), RSTRING_PTR(host), FIX2INT(port), RSTRING_PTR(password));
|
78
|
+
result = bindRuleset((void *)FIX2LONG(handle), RSTRING_PTR(host), FIX2INT(port), RSTRING_PTR(password), FIX2INT(db));
|
78
79
|
} else if (TYPE(password) == T_NIL) {
|
79
|
-
result = bindRuleset((void *)FIX2LONG(handle), RSTRING_PTR(host), FIX2INT(port), NULL);
|
80
|
+
result = bindRuleset((void *)FIX2LONG(handle), RSTRING_PTR(host), FIX2INT(port), NULL, FIX2INT(db));
|
80
81
|
} else {
|
81
82
|
rb_raise(rb_eTypeError, "Wrong argument type for password");
|
82
83
|
}
|
@@ -654,7 +655,7 @@ void Init_rules() {
|
|
654
655
|
rb_define_singleton_method(rulesModule, "delete_ruleset", rbDeleteRuleset, 1);
|
655
656
|
rb_define_singleton_method(rulesModule, "create_client", rbCreateClient, 2);
|
656
657
|
rb_define_singleton_method(rulesModule, "delete_client", rbDeleteClient, 1);
|
657
|
-
rb_define_singleton_method(rulesModule, "bind_ruleset", rbBindRuleset,
|
658
|
+
rb_define_singleton_method(rulesModule, "bind_ruleset", rbBindRuleset, 5);
|
658
659
|
rb_define_singleton_method(rulesModule, "complete", rbComplete, 2);
|
659
660
|
rb_define_singleton_method(rulesModule, "assert_event", rbAssertEvent, 2);
|
660
661
|
rb_define_singleton_method(rulesModule, "queue_assert_event", rbQueueAssertEvent, 4);
|
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.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jesus Ruiz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -79,10 +79,12 @@ files:
|
|
79
79
|
- src/rules/events.c
|
80
80
|
- src/rules/json.c
|
81
81
|
- src/rules/net.c
|
82
|
+
- src/rules/regex.c
|
82
83
|
- src/rules/rete.c
|
83
84
|
- src/rules/state.c
|
84
85
|
- src/rules/json.h
|
85
86
|
- src/rules/net.h
|
87
|
+
- src/rules/regex.h
|
86
88
|
- src/rules/rete.h
|
87
89
|
- src/rules/rules.h
|
88
90
|
- src/rules/state.h
|