Compare commits
556 Commits
T0413-MG-r
...
MG-determi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18edf17496 | ||
|
|
eeb7ab6272 | ||
|
|
5c0e41ed44 | ||
|
|
6df2db0d19 | ||
|
|
968584a8fc | ||
|
|
33add3ecd0 | ||
|
|
91b5092c71 | ||
|
|
c0f576c187 | ||
|
|
51fb4a6e7a | ||
|
|
cba183898a | ||
|
|
5f5fe7eb29 | ||
|
|
efa4378fb4 | ||
|
|
3c07a5dc04 | ||
|
|
e442963466 | ||
|
|
32fe4d94d9 | ||
|
|
94b66a4e81 | ||
|
|
61b9457718 | ||
|
|
159b30ba5f | ||
|
|
b67e5b9a6c | ||
|
|
79756ae6fb | ||
|
|
a54bcb9819 | ||
|
|
c16f948de9 | ||
|
|
2a7ed1ad82 | ||
|
|
5201db46d2 | ||
|
|
91550128a5 | ||
|
|
d5966101ad | ||
|
|
88487e2513 | ||
|
|
b10b1eb239 | ||
|
|
dca94f42bb | ||
|
|
39b40ecf00 | ||
|
|
baacc52a65 | ||
|
|
5273d319e2 | ||
|
|
23838b50ea | ||
|
|
d85fb94bc7 | ||
|
|
4d2036249e | ||
|
|
d23643d4ff | ||
|
|
e52ce1e363 | ||
|
|
1abfe28806 | ||
|
|
d17970f6d9 | ||
|
|
9e72c7cb54 | ||
|
|
528e30a9be | ||
|
|
bb7c7f7627 | ||
|
|
bab5e1386a | ||
|
|
3d954e7abc | ||
|
|
fa5c9a2568 | ||
|
|
c745f8c877 | ||
|
|
486231b1b9 | ||
|
|
43ad5855c4 | ||
|
|
24864ff7d2 | ||
|
|
8598f6edf4 | ||
|
|
e41073bc2c | ||
|
|
14e3e72565 | ||
|
|
1cee7ecb8a | ||
|
|
690a389563 | ||
|
|
9203616283 | ||
|
|
d198819bf1 | ||
|
|
3a8f01af79 | ||
|
|
7e6ec8bb26 | ||
|
|
6138d76690 | ||
|
|
25fdb1a1f0 | ||
|
|
2de1d6c359 | ||
|
|
0364311dd0 | ||
|
|
9235515dab | ||
|
|
b83fb287ad | ||
|
|
70dc19dfdb | ||
|
|
b685a21171 | ||
|
|
4db83b8159 | ||
|
|
dd8dd4f6c4 | ||
|
|
fa1ddfea12 | ||
|
|
a815ec9617 | ||
|
|
78528bd609 | ||
|
|
6239f4fc3e | ||
|
|
c5eb3ff2c0 | ||
|
|
9f71ce0f78 | ||
|
|
589dd36bf2 | ||
|
|
57e7169203 | ||
|
|
bb3b053375 | ||
|
|
a96f489756 | ||
|
|
e909e7d2d8 | ||
|
|
2d91a7fd1e | ||
|
|
1d18f1197f | ||
|
|
edeebf46ec | ||
|
|
1148fe9aad | ||
|
|
c92c795b1a | ||
|
|
0fee412f92 | ||
|
|
7596e85358 | ||
|
|
014836ca3c | ||
|
|
68654b5a19 | ||
|
|
4d96bf5006 | ||
|
|
9bb70eb0b9 | ||
|
|
7076788dd5 | ||
|
|
ee4be9aa5b | ||
|
|
96a2ad4b63 | ||
|
|
84509fa477 | ||
|
|
19b5fe3caf | ||
|
|
74db669e23 | ||
|
|
599802033f | ||
|
|
6dd57426f8 | ||
|
|
3c9f0c48e9 | ||
|
|
9a1258a708 | ||
|
|
c55ca836a4 | ||
|
|
5674ef4016 | ||
|
|
77c2afc9e7 | ||
|
|
27292dd921 | ||
|
|
e4f1fd8647 | ||
|
|
4608af9d00 | ||
|
|
50e72a7c28 | ||
|
|
17a104677d | ||
|
|
a6add80fc9 | ||
|
|
5d3eaf6a55 | ||
|
|
a13f260236 | ||
|
|
1f778ba5f3 | ||
|
|
787987168c | ||
|
|
7b4b1ba8ed | ||
|
|
bb1e8aa164 | ||
|
|
27a1311966 | ||
|
|
30ff6487f2 | ||
|
|
119da2d7a7 | ||
|
|
fa972813d2 | ||
|
|
951b058116 | ||
|
|
d0cad6e6ba | ||
|
|
6138277972 | ||
|
|
2f77eb96ff | ||
|
|
d7bc93c55f | ||
|
|
039d5f51d3 | ||
|
|
cebe6f62fa | ||
|
|
6834ce01fe | ||
|
|
4c5cd1f847 | ||
|
|
f9e2a66961 | ||
|
|
d5700ab5ff | ||
|
|
b0aaba6765 | ||
|
|
e1f18f3733 | ||
|
|
c90b38faf0 | ||
|
|
acbf3c764c | ||
|
|
37df41796f | ||
|
|
f04e1cda4b | ||
|
|
f28ba89584 | ||
|
|
60485311c8 | ||
|
|
36a1c43851 | ||
|
|
bae8c084b1 | ||
|
|
2898120eeb | ||
|
|
d62a45752a | ||
|
|
c5ee6ffbc2 | ||
|
|
5ef08f841a | ||
|
|
59c7d81ae8 | ||
|
|
03c095e780 | ||
|
|
b542e49b3e | ||
|
|
ddb30f49ea | ||
|
|
d920d7c293 | ||
|
|
6b0168cb3d | ||
|
|
03cf264b76 | ||
|
|
9448e23dc9 | ||
|
|
eafccaea84 | ||
|
|
0c4f591b3c | ||
|
|
534e365271 | ||
|
|
281ae158ec | ||
|
|
39c9c215b1 | ||
|
|
f6e78ce6da | ||
|
|
3cf79f5bbf | ||
|
|
6a31c49432 | ||
|
|
fea92f4829 | ||
|
|
1703cd039d | ||
|
|
ca2351124b | ||
|
|
5784c0d473 | ||
|
|
8ebc704819 | ||
|
|
5939fb2b0c | ||
|
|
ee64684b0b | ||
|
|
1e4c02f8a5 | ||
|
|
8353228ba7 | ||
|
|
332afadf21 | ||
|
|
acc655f4fd | ||
|
|
12e7a261aa | ||
|
|
1c3bb969e9 | ||
|
|
e5437080c5 | ||
|
|
17090dd8ac | ||
|
|
281cebd386 | ||
|
|
f89a2bbf42 | ||
|
|
85b8ce9101 | ||
|
|
6bb40a7f49 | ||
|
|
1707ee648e | ||
|
|
07f34838bd | ||
|
|
b6f8b5e130 | ||
|
|
58243f4a26 | ||
|
|
d06132cb33 | ||
|
|
f063c1b1ad | ||
|
|
5347c06d76 | ||
|
|
4634ac484a | ||
|
|
a5dc818e19 | ||
|
|
4cb3b064c4 | ||
|
|
23171e76b6 | ||
|
|
6fd64d31f2 | ||
|
|
87111b2f89 | ||
|
|
b5c7078c7d | ||
|
|
925835b080 | ||
|
|
ce788f5f65 | ||
|
|
b8186bea2e | ||
|
|
3c4856dcb7 | ||
|
|
b4d6dc0930 | ||
|
|
817161a915 | ||
|
|
58eb2caf0f | ||
|
|
ecda71168c | ||
|
|
8e1f83acc9 | ||
|
|
f910cb770c | ||
|
|
38d0b89b04 | ||
|
|
a2a6a3855b | ||
|
|
e9f0360fb3 | ||
|
|
fe4955447e | ||
|
|
1631c20df2 | ||
|
|
947baedbe6 | ||
|
|
c6447eb48b | ||
|
|
7e84744d07 | ||
|
|
c0d03888f4 | ||
|
|
efb3c8d03d | ||
|
|
95dbc022c0 | ||
|
|
a40403e3ce | ||
|
|
14c9e68456 | ||
|
|
68b26275a3 | ||
|
|
5012824e05 | ||
|
|
a12a1ea358 | ||
|
|
2891041468 | ||
|
|
cc5ee6a496 | ||
|
|
f57f30c8cf | ||
|
|
462daf3a2b | ||
|
|
2009fefc8a | ||
|
|
eb3f96d1f6 | ||
|
|
80e0e439b7 | ||
|
|
351258ace8 | ||
|
|
74d3663821 | ||
|
|
264b233053 | ||
|
|
2ceaf59767 | ||
|
|
eb0b3141d5 | ||
|
|
c0bee760bf | ||
|
|
ff2f8031a9 | ||
|
|
094d4f282d | ||
|
|
3dd2657320 | ||
|
|
6fe474282a | ||
|
|
7fc0fb6520 | ||
|
|
3f4f66b57f | ||
|
|
063e297e1e | ||
|
|
2998f92595 | ||
|
|
86b1688192 | ||
|
|
f629de7e60 | ||
|
|
b737e53456 | ||
|
|
1bdc32ba5d | ||
|
|
10ca68bb2a | ||
|
|
bfbd8538d4 | ||
|
|
3e0e17d469 | ||
|
|
b57f91fcfc | ||
|
|
066a96c0ae | ||
|
|
1ae6b71c5f | ||
|
|
21870a0e7e | ||
|
|
cbe15e7f44 | ||
|
|
65a7ba01da | ||
|
|
7a2bbd4bb3 | ||
|
|
589e0e098b | ||
|
|
41d4185156 | ||
|
|
599c0a641f | ||
|
|
1fb49c4865 | ||
|
|
df1485aeec | ||
|
|
b2e1056389 | ||
|
|
e4c9411e63 | ||
|
|
a0bc1371dd | ||
|
|
21ad5d4328 | ||
|
|
8e3ab1ad0f | ||
|
|
cccf32e79d | ||
|
|
22bd60c613 | ||
|
|
8059a3e653 | ||
|
|
a7f4c98bea | ||
|
|
483f4d04bd | ||
|
|
3e7aef432f | ||
|
|
10ea9c773e | ||
|
|
b782271be8 | ||
|
|
a8ffcfa046 | ||
|
|
7b78665cd8 | ||
|
|
4abaf27765 | ||
|
|
ea2806bd57 | ||
|
|
c8dbaf5979 | ||
|
|
17049ada09 | ||
|
|
1b619f51b2 | ||
|
|
537855a0b2 | ||
|
|
5822b44b15 | ||
|
|
bf01c58ed9 | ||
|
|
89a5566f3f | ||
|
|
29452f8774 | ||
|
|
60ad05acff | ||
|
|
4f593c7fca | ||
|
|
770ea1189a | ||
|
|
695bb343f1 | ||
|
|
12b4ec1589 | ||
|
|
b33d2c3940 | ||
|
|
477acad1f6 | ||
|
|
ddca2b40f5 | ||
|
|
4817be0add | ||
|
|
3fb7e5378d | ||
|
|
1d88893715 | ||
|
|
bd2c30fddc | ||
|
|
06e6ead4d2 | ||
|
|
728b37080d | ||
|
|
48a531aac1 | ||
|
|
914fc1a656 | ||
|
|
1d1c182c2d | ||
|
|
c6e19ec09f | ||
|
|
693dab78d2 | ||
|
|
69eca9b043 | ||
|
|
5aeaad198b | ||
|
|
b23f88c607 | ||
|
|
4fd8bdce4c | ||
|
|
265b203b00 | ||
|
|
661e5185d8 | ||
|
|
7348ad6800 | ||
|
|
6c00d146f2 | ||
|
|
ced84e17b6 | ||
|
|
834ce5f51a | ||
|
|
bb1308acc7 | ||
|
|
e1f31d3d02 | ||
|
|
339cd9b84e | ||
|
|
7deac4ac8b | ||
|
|
fec887a67c | ||
|
|
f3a3a4ed87 | ||
|
|
ec65187442 | ||
|
|
079c0495c3 | ||
|
|
90cfed2ada | ||
|
|
8716b8e992 | ||
|
|
a277541354 | ||
|
|
b01564f179 | ||
|
|
d9bb4e2e46 | ||
|
|
05d0aee494 | ||
|
|
aabec99a8e | ||
|
|
d277dd49a3 | ||
|
|
18f9d19b18 | ||
|
|
530eed5c6d | ||
|
|
12f4e0068a | ||
|
|
e8976e0f1c | ||
|
|
6eb52581eb | ||
|
|
8606e69fd6 | ||
|
|
c7b045bffc | ||
|
|
b66cc66503 | ||
|
|
0e4719018a | ||
|
|
0ebd52aac3 | ||
|
|
6c971b856e | ||
|
|
6cb293688d | ||
|
|
16709dff6c | ||
|
|
95dd3481c0 | ||
|
|
47c0c629c7 | ||
|
|
636c551047 | ||
|
|
72384b2b71 | ||
|
|
a9b1ff9bea | ||
|
|
e40bc32624 | ||
|
|
bd21bc82b7 | ||
|
|
9c1680e82c | ||
|
|
1a78c3695d | ||
|
|
10196f3d7d | ||
|
|
2c86fefbb5 | ||
|
|
df689dccd5 | ||
|
|
6033fbe9bd | ||
|
|
519a204424 | ||
|
|
3fc5e57fef | ||
|
|
906933d2b3 | ||
|
|
e9a937ad6d | ||
|
|
6dc2cdfae4 | ||
|
|
69ea410406 | ||
|
|
24a576c8e9 | ||
|
|
d417ffee6e | ||
|
|
f868b51483 | ||
|
|
26dc73c809 | ||
|
|
9119c89eba | ||
|
|
4e7ea34ae9 | ||
|
|
d7d291217b | ||
|
|
42facfacbc | ||
|
|
bd1e848363 | ||
|
|
0ffb58b764 | ||
|
|
9551b6973a | ||
|
|
f7ef5f50a4 | ||
|
|
046cd80054 | ||
|
|
9e678f8cbe | ||
|
|
69e4f1784b | ||
|
|
d04e23805d | ||
|
|
7e82cc6550 | ||
|
|
18b801a722 | ||
|
|
7e81a95b81 | ||
|
|
0a23eb11ae | ||
|
|
8ea281649a | ||
|
|
da68f86fc9 | ||
|
|
738b5fb8d8 | ||
|
|
b45ae403e6 | ||
|
|
d744711e5e | ||
|
|
8d87e38c64 | ||
|
|
086fc47769 | ||
|
|
5abcb5081d | ||
|
|
9534dfb6ed | ||
|
|
e2112faff0 | ||
|
|
6913feacc7 | ||
|
|
4e604de9d7 | ||
|
|
e628b5ba6e | ||
|
|
5da32c1bff | ||
|
|
ccca46370d | ||
|
|
e33fa5f9c0 | ||
|
|
721eefe263 | ||
|
|
be9ed7e879 | ||
|
|
482798295e | ||
|
|
d58a1cbb58 | ||
|
|
8dc3153fde | ||
|
|
b94e50bf1c | ||
|
|
9f855676cb | ||
|
|
f560293657 | ||
|
|
2afc1b99f6 | ||
|
|
5a8bda2531 | ||
|
|
0138d277d4 | ||
|
|
09cfca35f8 | ||
|
|
09c58501f1 | ||
|
|
945bbfdc49 | ||
|
|
45ef069372 | ||
|
|
e51954fc94 | ||
|
|
7776160836 | ||
|
|
ae280fd8db | ||
|
|
fb5a2ed4b6 | ||
|
|
6cfec787dc | ||
|
|
13c9bf76af | ||
|
|
2e1a717dcb | ||
|
|
ad32db5168 | ||
|
|
a37755ce43 | ||
|
|
a928c158da | ||
|
|
ac230d0c2d | ||
|
|
d80ff745eb | ||
|
|
d6a6d280dd | ||
|
|
4004e94ca1 | ||
|
|
36afc6c5f3 | ||
|
|
3c9a46f823 | ||
|
|
f994b68ad5 | ||
|
|
3b336e3e0b | ||
|
|
715162e205 | ||
|
|
e016c74e4b | ||
|
|
15911b64dc | ||
|
|
cbf826e0c3 | ||
|
|
644a3a0b2a | ||
|
|
8cd9f696cf | ||
|
|
90a093bd95 | ||
|
|
542a324c96 | ||
|
|
cd03e13443 | ||
|
|
be91126134 | ||
|
|
03cb007339 | ||
|
|
524acb17a1 | ||
|
|
50f6e348dc | ||
|
|
839d45b3f8 | ||
|
|
560eb04f67 | ||
|
|
a3ecc52429 | ||
|
|
e8a1d15a55 | ||
|
|
1abee1ed3a | ||
|
|
5af3d0ff68 | ||
|
|
62a628c51f | ||
|
|
883f9c7ed3 | ||
|
|
b459639968 | ||
|
|
11c0dde11c | ||
|
|
2f3fa656d9 | ||
|
|
7bf40eb5d2 | ||
|
|
7e44434cdf | ||
|
|
2a0b0d969f | ||
|
|
13ea35af2d | ||
|
|
8a99670301 | ||
|
|
c4555f5448 | ||
|
|
999b3ef79f | ||
|
|
30413a7b4f | ||
|
|
1def0c9104 | ||
|
|
782c377f5d | ||
|
|
cc27a04139 | ||
|
|
b71345655f | ||
|
|
ccdd58b336 | ||
|
|
50b6afd73d | ||
|
|
59105f68bd | ||
|
|
8de31092ad | ||
|
|
5c93f81881 | ||
|
|
6d4fe5cdd5 | ||
|
|
7b5263d300 | ||
|
|
e8a41e4457 | ||
|
|
27f09e1c0a | ||
|
|
6dd9d32721 | ||
|
|
276e09d7d3 | ||
|
|
92dfc93b20 | ||
|
|
06f761bdf9 | ||
|
|
50ddd59450 | ||
|
|
60da033010 | ||
|
|
ee555b0c0d | ||
|
|
e8e4cd7f97 | ||
|
|
ad4c80af13 | ||
|
|
9c6bf4b1b8 | ||
|
|
cc56ac3dd8 | ||
|
|
dee885d69c | ||
|
|
bbed7a2397 | ||
|
|
e8810a4152 | ||
|
|
25eb2c147a | ||
|
|
b3914c6b5d | ||
|
|
d913a67e16 | ||
|
|
f950a91732 | ||
|
|
f6d5f576d5 | ||
|
|
dc5eb4befd | ||
|
|
593f7a3499 | ||
|
|
77a0d7b8fa | ||
|
|
c240b5b564 | ||
|
|
866ed45562 | ||
|
|
1598cb24ea | ||
|
|
35d789c56b | ||
|
|
16715d5005 | ||
|
|
a9f5f45b3d | ||
|
|
2e0dd19bac | ||
|
|
f807b495ab | ||
|
|
3f3c55a4aa | ||
|
|
435af8b833 | ||
|
|
cc1c1513ef | ||
|
|
fae407d3fe | ||
|
|
42c245df8a | ||
|
|
e4852cc5e3 | ||
|
|
2caf0e617e | ||
|
|
90d4ebdb1e | ||
|
|
151812da1a | ||
|
|
1e10b9cb77 | ||
|
|
c44dbdda86 | ||
|
|
46b1783618 | ||
|
|
e866526c7a | ||
|
|
28413fd626 | ||
|
|
c0bd59bb09 | ||
|
|
a84ffe86c1 | ||
|
|
8f5b88f24a | ||
|
|
afbf672915 | ||
|
|
10c8256ec9 | ||
|
|
b19cd4f5d1 | ||
|
|
8fc9298832 | ||
|
|
9966ba1d52 | ||
|
|
b7bbd026de | ||
|
|
855c2ea9ca | ||
|
|
adc355a22a | ||
|
|
bff9cf07de | ||
|
|
60d742a2dc | ||
|
|
a0fb3fc463 | ||
|
|
f23e2e12c4 | ||
|
|
87e00f4fef | ||
|
|
f7b764607d | ||
|
|
200ce5f45e | ||
|
|
a0705746cb | ||
|
|
4e36b646df | ||
|
|
ec909ced57 | ||
|
|
7e9175052a | ||
|
|
3c85319701 | ||
|
|
76f0d5873b | ||
|
|
03cc568e39 | ||
|
|
bc0c944910 | ||
|
|
42f6118c00 | ||
|
|
b10255a12f | ||
|
|
c68ed8d94e | ||
|
|
d5b02eafb1 | ||
|
|
1580c46abc | ||
|
|
367cb44983 | ||
|
|
77bda187d2 | ||
|
|
57806544cd | ||
|
|
7bff678cd9 | ||
|
|
647388792a | ||
|
|
b42ee31c1d |
@@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
Language: Cpp
|
Language: Cpp
|
||||||
BasedOnStyle: Google
|
BasedOnStyle: Google
|
||||||
Standard: "C++11"
|
Standard: "c++20"
|
||||||
UseTab: Never
|
UseTab: Never
|
||||||
DerivePointerAlignment: false
|
DerivePointerAlignment: false
|
||||||
PointerAlignment: Right
|
PointerAlignment: Right
|
||||||
ColumnLimit : 80
|
ColumnLimit : 120
|
||||||
IncludeBlocks: Preserve
|
IncludeBlocks: Preserve
|
||||||
...
|
...
|
||||||
|
|||||||
20
.clang-tidy
20
.clang-tidy
@@ -1,7 +1,12 @@
|
|||||||
---
|
---
|
||||||
Checks: '*,
|
Checks: '*,
|
||||||
|
-abseil-string-find-str-contains,
|
||||||
|
-altera-id-dependent-backward-branch,
|
||||||
|
-altera-struct-pack-align,
|
||||||
|
-altera-unroll-loops,
|
||||||
-android-*,
|
-android-*,
|
||||||
-cert-err58-cpp,
|
-cert-err58-cpp,
|
||||||
|
-cert-str34-c,
|
||||||
-cppcoreguidelines-avoid-c-arrays,
|
-cppcoreguidelines-avoid-c-arrays,
|
||||||
-cppcoreguidelines-avoid-goto,
|
-cppcoreguidelines-avoid-goto,
|
||||||
-cppcoreguidelines-avoid-magic-numbers,
|
-cppcoreguidelines-avoid-magic-numbers,
|
||||||
@@ -26,6 +31,7 @@ Checks: '*,
|
|||||||
-fuchsia-virtual-inheritance,
|
-fuchsia-virtual-inheritance,
|
||||||
-google-explicit-constructor,
|
-google-explicit-constructor,
|
||||||
-google-readability-*,
|
-google-readability-*,
|
||||||
|
-google-runtime-references,
|
||||||
-hicpp-avoid-c-arrays,
|
-hicpp-avoid-c-arrays,
|
||||||
-hicpp-avoid-goto,
|
-hicpp-avoid-goto,
|
||||||
-hicpp-braces-around-statements,
|
-hicpp-braces-around-statements,
|
||||||
@@ -34,15 +40,17 @@ Checks: '*,
|
|||||||
-hicpp-no-assembler,
|
-hicpp-no-assembler,
|
||||||
-hicpp-no-malloc,
|
-hicpp-no-malloc,
|
||||||
-hicpp-use-equals-default,
|
-hicpp-use-equals-default,
|
||||||
|
-hicpp-use-nullptr,
|
||||||
-hicpp-vararg,
|
-hicpp-vararg,
|
||||||
-llvm-header-guard,
|
-llvm-header-guard,
|
||||||
|
-llvm-include-order,
|
||||||
-llvmlibc-callee-namespace,
|
-llvmlibc-callee-namespace,
|
||||||
-llvmlibc-implementation-in-namespace,
|
-llvmlibc-implementation-in-namespace,
|
||||||
-llvmlibc-restrict-system-libc-headers,
|
-llvmlibc-restrict-system-libc-headers,
|
||||||
-misc-non-private-member-variables-in-classes,
|
-misc-non-private-member-variables-in-classes,
|
||||||
-misc-unused-parameters,
|
|
||||||
-modernize-avoid-c-arrays,
|
-modernize-avoid-c-arrays,
|
||||||
-modernize-concat-nested-namespaces,
|
-modernize-concat-nested-namespaces,
|
||||||
|
-modernize-loop-convert,
|
||||||
-modernize-pass-by-value,
|
-modernize-pass-by-value,
|
||||||
-modernize-use-equals-default,
|
-modernize-use-equals-default,
|
||||||
-modernize-use-nodiscard,
|
-modernize-use-nodiscard,
|
||||||
@@ -50,11 +58,16 @@ Checks: '*,
|
|||||||
-performance-unnecessary-value-param,
|
-performance-unnecessary-value-param,
|
||||||
-readability-braces-around-statements,
|
-readability-braces-around-statements,
|
||||||
-readability-else-after-return,
|
-readability-else-after-return,
|
||||||
|
-readability-function-cognitive-complexity,
|
||||||
-readability-implicit-bool-conversion,
|
-readability-implicit-bool-conversion,
|
||||||
-readability-magic-numbers,
|
-readability-magic-numbers,
|
||||||
-readability-named-parameter'
|
-readability-named-parameter,
|
||||||
|
-misc-no-recursion,
|
||||||
|
-concurrency-mt-unsafe,
|
||||||
|
-bugprone-easily-swappable-parameters'
|
||||||
|
|
||||||
WarningsAsErrors: ''
|
WarningsAsErrors: ''
|
||||||
HeaderFilterRegex: ''
|
HeaderFilterRegex: 'src/.*'
|
||||||
AnalyzeTemporaryDtors: false
|
AnalyzeTemporaryDtors: false
|
||||||
FormatStyle: none
|
FormatStyle: none
|
||||||
CheckOptions:
|
CheckOptions:
|
||||||
@@ -79,4 +92,3 @@ CheckOptions:
|
|||||||
- key: modernize-use-nullptr.NullMacros
|
- key: modernize-use-nullptr.NullMacros
|
||||||
value: 'NULL'
|
value: 'NULL'
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ exec 1>&2
|
|||||||
tmpdir=$(mktemp -d repo-XXXXXXXX)
|
tmpdir=$(mktemp -d repo-XXXXXXXX)
|
||||||
trap "rm -rf $tmpdir" EXIT INT
|
trap "rm -rf $tmpdir" EXIT INT
|
||||||
|
|
||||||
modified_files=$(git diff --cached --name-only --diff-filter=AM $against | sed -nE "/.*\.(cpp|cc|cxx|c|h|hpp|lcp)$/p")
|
modified_files=$(git diff --cached --name-only --diff-filter=AM $against | sed -nE "/.*\.(cpp|cc|cxx|c|h|hpp)$/p")
|
||||||
|
FAIL=0
|
||||||
for file in $modified_files; do
|
for file in $modified_files; do
|
||||||
echo "Checking $file..."
|
echo "Checking $file..."
|
||||||
|
|
||||||
@@ -23,21 +24,13 @@ for file in $modified_files; do
|
|||||||
|
|
||||||
git checkout-index --prefix="$tmpdir/" -- $file
|
git checkout-index --prefix="$tmpdir/" -- $file
|
||||||
|
|
||||||
echo "Running clang-format..."
|
# Do not break header checker
|
||||||
$project_folder/tools/git-clang-format $tmpdir/$file
|
echo "Running header checker..."
|
||||||
code=$?
|
$project_folder/tools/header-checker.py $tmpdir/$file $file --amend-year
|
||||||
|
CODE=$?
|
||||||
if [ $code -ne 0 ]; then
|
if [ $CODE -ne 0 ]; then
|
||||||
break
|
FAIL=1
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Running clang-tidy..."
|
|
||||||
$project_folder/tools/git-clang-tidy $tmpdir/$file
|
|
||||||
code=$?
|
|
||||||
|
|
||||||
if [ $code -ne 0 ]; then
|
|
||||||
break
|
|
||||||
fi
|
fi
|
||||||
done;
|
done;
|
||||||
|
|
||||||
return $code
|
return ${FAIL}
|
||||||
|
|||||||
34
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
34
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: "[BUG] "
|
||||||
|
labels: bug
|
||||||
|
assignees: gitbuda, antonio2368
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
**Memgraph version**
|
||||||
|
Which version did you use?
|
||||||
|
|
||||||
|
**Environment**
|
||||||
|
Some information about the environment you are using Memgraph on: operating
|
||||||
|
system, how do you connect, with or without docker, which driver etc.
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Run the following query '...'
|
||||||
|
2. Click on '....'
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Logs**
|
||||||
|
If applicable, add logs of Memgraph, CLI output or screenshots to help explain
|
||||||
|
your problem.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
||||||
11
.github/pull_request_template.md
vendored
Normal file
11
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
[master < Epic] PR
|
||||||
|
- [ ] Check, and update documentation if necessary
|
||||||
|
- [ ] Update [changelog](https://docs.memgraph.com/memgraph/changelog)
|
||||||
|
- [ ] Write E2E tests
|
||||||
|
- [ ] Compare the [benchmarking results](https://bench-graph.memgraph.com/) between the master branch and the Epic branch
|
||||||
|
- [ ] Provide the full content or a guide for the final git message
|
||||||
|
|
||||||
|
[master < Task] PR
|
||||||
|
- [ ] Check, and update documentation if necessary
|
||||||
|
- [ ] Update [changelog](https://docs.memgraph.com/memgraph/changelog)
|
||||||
|
- [ ] Provide the full content or a guide for the final git message
|
||||||
82
.github/workflows/daily_benchmark.yaml
vendored
Normal file
82
.github/workflows/daily_benchmark.yaml
vendored
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
name: Daily Benchmark
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 1 * * *"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release_benchmarks:
|
||||||
|
name: "Release benchmarks"
|
||||||
|
runs-on: [self-hosted, Linux, X64, Diff, Gen7]
|
||||||
|
env:
|
||||||
|
THREADS: 24
|
||||||
|
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||||
|
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Set up repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
# Number of commits to fetch. `0` indicates all history for all
|
||||||
|
# branches and tags. (default: 1)
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Build release binaries
|
||||||
|
run: |
|
||||||
|
# Activate toolchain.
|
||||||
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
# Initialize dependencies.
|
||||||
|
./init
|
||||||
|
|
||||||
|
# Build only memgraph release binaries.
|
||||||
|
cd build
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=release ..
|
||||||
|
make -j$THREADS
|
||||||
|
|
||||||
|
- name: Run macro benchmarks
|
||||||
|
run: |
|
||||||
|
cd tests/macro_benchmark
|
||||||
|
./harness QuerySuite MemgraphRunner \
|
||||||
|
--groups aggregation 1000_create unwind_create dense_expand match \
|
||||||
|
--no-strict
|
||||||
|
|
||||||
|
- name: Get branch name (merge)
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
shell: bash
|
||||||
|
run: echo "BRANCH_NAME=$(echo ${GITHUB_REF#refs/heads/} | tr / -)" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Get branch name (pull request)
|
||||||
|
if: github.event_name == 'pull_request'
|
||||||
|
shell: bash
|
||||||
|
run: echo "BRANCH_NAME=$(echo ${GITHUB_HEAD_REF} | tr / -)" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Upload macro benchmark results
|
||||||
|
run: |
|
||||||
|
cd tools/bench-graph-client
|
||||||
|
virtualenv -p python3 ve3
|
||||||
|
source ve3/bin/activate
|
||||||
|
pip install -r requirements.txt
|
||||||
|
./main.py --benchmark-name "macro_benchmark" \
|
||||||
|
--benchmark-results-path "../../tests/macro_benchmark/.harness_summary" \
|
||||||
|
--github-run-id "${{ github.run_id }}" \
|
||||||
|
--github-run-number "${{ github.run_number }}" \
|
||||||
|
--head-branch-name "${{ env.BRANCH_NAME }}"
|
||||||
|
|
||||||
|
- name: Run mgbench
|
||||||
|
run: |
|
||||||
|
cd tests/mgbench
|
||||||
|
./benchmark.py --num-workers-for-benchmark 12 --export-results benchmark_result.json pokec/medium/*/*
|
||||||
|
|
||||||
|
- name: Upload mgbench results
|
||||||
|
run: |
|
||||||
|
cd tools/bench-graph-client
|
||||||
|
virtualenv -p python3 ve3
|
||||||
|
source ve3/bin/activate
|
||||||
|
pip install -r requirements.txt
|
||||||
|
./main.py --benchmark-name "mgbench" \
|
||||||
|
--benchmark-results-path "../../tests/mgbench/benchmark_result.json" \
|
||||||
|
--github-run-id "${{ github.run_id }}" \
|
||||||
|
--github-run-number "${{ github.run_number }}" \
|
||||||
|
--head-branch-name "${{ env.BRANCH_NAME }}"
|
||||||
269
.github/workflows/diff.yaml
vendored
269
.github/workflows/diff.yaml
vendored
@@ -1,21 +1,32 @@
|
|||||||
name: Diff
|
name: Diff
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.head_ref || github.sha }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
pull_request:
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- 'docs/**'
|
- "docs/**"
|
||||||
- '*.md'
|
- "**/*.md"
|
||||||
|
- ".clang-format"
|
||||||
|
- "CODEOWNERS"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
community_build:
|
community_build:
|
||||||
name: "Community build"
|
name: "Community build"
|
||||||
runs-on: [self-hosted, General, Linux, X64, Debian10]
|
runs-on: [self-hosted, Linux, X64, Diff]
|
||||||
env:
|
env:
|
||||||
THREADS: 24
|
THREADS: 24
|
||||||
|
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||||
|
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Number of commits to fetch. `0` indicates all history for all
|
# Number of commits to fetch. `0` indicates all history for all
|
||||||
# branches and tags. (default: 1)
|
# branches and tags. (default: 1)
|
||||||
@@ -24,7 +35,7 @@ jobs:
|
|||||||
- name: Build community binaries
|
- name: Build community binaries
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Initialize dependencies.
|
# Initialize dependencies.
|
||||||
./init
|
./init
|
||||||
@@ -37,57 +48,83 @@ jobs:
|
|||||||
- name: Run unit tests
|
- name: Run unit tests
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Run unit tests.
|
# Run unit tests.
|
||||||
cd build
|
cd build
|
||||||
ctest -R memgraph__unit --output-on-failure
|
ctest -R memgraph__unit --output-on-failure -j$THREADS
|
||||||
|
|
||||||
- name: Run stress test
|
code_analysis:
|
||||||
run: |
|
name: "Code analysis"
|
||||||
cd tests/stress
|
runs-on: [self-hosted, Linux, X64, Diff]
|
||||||
./continuous_integration
|
|
||||||
|
|
||||||
coverage_build:
|
|
||||||
name: "Coverage build"
|
|
||||||
runs-on: [self-hosted, General, Linux, X64, Debian10]
|
|
||||||
env:
|
env:
|
||||||
THREADS: 24
|
THREADS: 24
|
||||||
|
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||||
|
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Number of commits to fetch. `0` indicates all history for all
|
# Number of commits to fetch. `0` indicates all history for all
|
||||||
# branches and tags. (default: 1)
|
# branches and tags. (default: 1)
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Build coverage binaries
|
# This is also needed if we want do to comparison against other branches
|
||||||
|
# See https://github.community/t/checkout-code-fails-when-it-runs-lerna-run-test-since-master/17920
|
||||||
|
- name: Fetch all history for all tags and branches
|
||||||
|
run: git fetch
|
||||||
|
|
||||||
|
- name: Initialize deps
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Initialize dependencies.
|
# Initialize dependencies.
|
||||||
./init
|
./init
|
||||||
|
|
||||||
# Build coverage binaries.
|
- name: Set base branch
|
||||||
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
|
run: |
|
||||||
|
echo "BASE_BRANCH=origin/${{ github.base_ref }}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Set base branch # if we manually dispatch or push to master
|
||||||
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
|
run: |
|
||||||
|
echo "BASE_BRANCH=origin/master" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Python code analysis
|
||||||
|
run: |
|
||||||
|
CHANGED_FILES=$(git diff -U0 ${{ env.BASE_BRANCH }}... --name-only)
|
||||||
|
for file in ${CHANGED_FILES}; do
|
||||||
|
echo ${file}
|
||||||
|
if [[ ${file} == *.py ]]; then
|
||||||
|
python3 -m black --check --diff ${file}
|
||||||
|
python3 -m isort --check-only --diff ${file}
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Build combined ASAN, UBSAN and coverage binaries
|
||||||
|
run: |
|
||||||
|
# Activate toolchain.
|
||||||
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
cd build
|
cd build
|
||||||
cmake -DTEST_COVERAGE=ON ..
|
cmake -DTEST_COVERAGE=ON -DASAN=ON -DUBSAN=ON ..
|
||||||
make -j$THREADS memgraph__unit
|
make -j$THREADS memgraph__unit
|
||||||
|
|
||||||
- name: Run unit tests
|
- name: Run unit tests
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Run unit tests.
|
# Run unit tests. It is restricted to 2 threads intentionally, because higher concurrency makes the timing related tests unstable.
|
||||||
cd build
|
cd build
|
||||||
ctest -R memgraph__unit --output-on-failure
|
LSAN_OPTIONS=suppressions=$PWD/../tools/lsan.supp UBSAN_OPTIONS=halt_on_error=1 ctest -R memgraph__unit --output-on-failure -j2
|
||||||
|
|
||||||
- name: Compute code coverage
|
- name: Compute code coverage
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Compute code coverage.
|
# Compute code coverage.
|
||||||
cd tools/github
|
cd tools/github
|
||||||
@@ -98,20 +135,42 @@ jobs:
|
|||||||
tar -czf code_coverage.tar.gz coverage.json html report.json summary.rmu
|
tar -czf code_coverage.tar.gz coverage.json html report.json summary.rmu
|
||||||
|
|
||||||
- name: Save code coverage
|
- name: Save code coverage
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: "Code coverage"
|
name: "Code coverage"
|
||||||
path: tools/github/generated/code_coverage.tar.gz
|
path: tools/github/generated/code_coverage.tar.gz
|
||||||
|
|
||||||
|
- name: Set base branch
|
||||||
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
|
run: |
|
||||||
|
echo "BASE_BRANCH=origin/${{ github.base_ref }}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Set base branch # if we manually dispatch or push to master
|
||||||
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
|
run: |
|
||||||
|
echo "BASE_BRANCH=origin/master" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Run clang-tidy
|
||||||
|
run: |
|
||||||
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
# Restrict clang-tidy results only to the modified parts
|
||||||
|
git diff -U0 ${{ env.BASE_BRANCH }}... -- src | ./tools/github/clang-tidy/clang-tidy-diff.py -p 1 -j $THREADS -extra-arg="-DMG_CLANG_TIDY_CHECK" -path build | tee ./build/clang_tidy_output.txt
|
||||||
|
|
||||||
|
# Fail if any warning is reported
|
||||||
|
! cat ./build/clang_tidy_output.txt | ./tools/github/clang-tidy/grep_error_lines.sh > /dev/null
|
||||||
|
|
||||||
debug_build:
|
debug_build:
|
||||||
name: "Debug build"
|
name: "Debug build"
|
||||||
runs-on: [self-hosted, General, Linux, X64, Debian10]
|
runs-on: [self-hosted, Linux, X64, Diff]
|
||||||
env:
|
env:
|
||||||
THREADS: 24
|
THREADS: 24
|
||||||
|
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||||
|
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Number of commits to fetch. `0` indicates all history for all
|
# Number of commits to fetch. `0` indicates all history for all
|
||||||
# branches and tags. (default: 1)
|
# branches and tags. (default: 1)
|
||||||
@@ -120,7 +179,7 @@ jobs:
|
|||||||
- name: Build debug binaries
|
- name: Build debug binaries
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Initialize dependencies.
|
# Initialize dependencies.
|
||||||
./init
|
./init
|
||||||
@@ -130,86 +189,44 @@ jobs:
|
|||||||
cmake ..
|
cmake ..
|
||||||
make -j$THREADS
|
make -j$THREADS
|
||||||
|
|
||||||
- name: Run leftover CTest tests
|
- name: Run simulation tests
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Run leftover CTest tests (all except unit and benchmark tests).
|
# Run simulation tests.
|
||||||
cd build
|
cd build
|
||||||
ctest -E "(memgraph__unit|memgraph__benchmark)" --output-on-failure
|
ctest -R memgraph__simulation --output-on-failure -j$THREADS
|
||||||
|
|
||||||
- name: Run drivers tests
|
- name: Run single benchmark test
|
||||||
run: |
|
|
||||||
./tests/drivers/run.sh
|
|
||||||
|
|
||||||
- name: Run integration tests
|
|
||||||
run: |
|
|
||||||
cd tests/integration
|
|
||||||
for name in *; do
|
|
||||||
if [ ! -d $name ]; then continue; fi
|
|
||||||
pushd $name >/dev/null
|
|
||||||
echo "Running: $name"
|
|
||||||
if [ -x prepare.sh ]; then
|
|
||||||
./prepare.sh
|
|
||||||
fi
|
|
||||||
if [ -x runner.py ]; then
|
|
||||||
./runner.py
|
|
||||||
elif [ -x runner.sh ]; then
|
|
||||||
./runner.sh
|
|
||||||
fi
|
|
||||||
echo
|
|
||||||
popd >/dev/null
|
|
||||||
done
|
|
||||||
|
|
||||||
- name: Run cppcheck and clang-format
|
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Run cppcheck and clang-format.
|
# Run simulation tests.
|
||||||
cd tools/github
|
cd tests/mgbench
|
||||||
./cppcheck_and_clang_format diff
|
./benchmark.py accesscontrol/small --num-workers-for-import 1 --test-system-arg "split-file splitfiles/accesscontrol_small.shard_configuration bolt-num-workers 1"
|
||||||
|
|
||||||
- name: Save cppcheck and clang-format errors
|
|
||||||
uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: "Code coverage"
|
|
||||||
path: tools/github/cppcheck_and_clang_format.txt
|
|
||||||
|
|
||||||
release_build:
|
release_build:
|
||||||
name: "Release build"
|
name: "Release build"
|
||||||
runs-on: [self-hosted, General, Linux, X64, Debian10]
|
runs-on: [self-hosted, Linux, X64, Diff]
|
||||||
env:
|
env:
|
||||||
THREADS: 24
|
THREADS: 24
|
||||||
|
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||||
|
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Number of commits to fetch. `0` indicates all history for all
|
# Number of commits to fetch. `0` indicates all history for all
|
||||||
# branches and tags. (default: 1)
|
# branches and tags. (default: 1)
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Set up parent
|
|
||||||
run: |
|
|
||||||
# Remove parent folder (if it exists).
|
|
||||||
cd ..
|
|
||||||
if [ -d parent ]; then
|
|
||||||
rm -rf parent
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Copy untouched repository to parent folder.
|
|
||||||
cp -r memgraph parent
|
|
||||||
|
|
||||||
# Checkout previous commit
|
|
||||||
cd parent
|
|
||||||
git checkout HEAD~1
|
|
||||||
|
|
||||||
- name: Build release binaries
|
- name: Build release binaries
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Initialize dependencies.
|
# Initialize dependencies.
|
||||||
./init
|
./init
|
||||||
@@ -219,72 +236,38 @@ jobs:
|
|||||||
cmake -DCMAKE_BUILD_TYPE=release ..
|
cmake -DCMAKE_BUILD_TYPE=release ..
|
||||||
make -j$THREADS
|
make -j$THREADS
|
||||||
|
|
||||||
- name: Build parent binaries
|
- name: Run unit tests
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Initialize dependencies.
|
# Run unit tests.
|
||||||
cd ../parent
|
|
||||||
./init
|
|
||||||
|
|
||||||
# Build parent binaries.
|
|
||||||
cd build
|
cd build
|
||||||
cmake -DCMAKE_BUILD_TYPE=release ..
|
ctest -R memgraph__unit --output-on-failure -j$THREADS
|
||||||
make -j$THREADS memgraph memgraph__macro_benchmark
|
|
||||||
|
|
||||||
- name: Run macro benchmark tests
|
- name: Run simulation tests
|
||||||
run: |
|
run: |
|
||||||
cd tests/macro_benchmark
|
# Activate toolchain.
|
||||||
./harness QuerySuite MemgraphRunner \
|
source /opt/toolchain-v4/activate
|
||||||
--groups aggregation 1000_create unwind_create dense_expand match \
|
|
||||||
--no-strict
|
|
||||||
|
|
||||||
- name: Run parent macro benchmark tests
|
# Run simulation tests.
|
||||||
|
cd build
|
||||||
|
ctest -R memgraph__simulation --output-on-failure -j$THREADS
|
||||||
|
|
||||||
|
- name: Run single benchmark test
|
||||||
run: |
|
run: |
|
||||||
cd ../parent/tests/macro_benchmark
|
# Activate toolchain.
|
||||||
./harness QuerySuite MemgraphRunner \
|
source /opt/toolchain-v4/activate
|
||||||
--groups aggregation 1000_create unwind_create dense_expand match \
|
|
||||||
--no-strict
|
|
||||||
|
|
||||||
- name: Compute macro benchmark summary
|
# Run simulation tests.
|
||||||
|
cd tests/mgbench
|
||||||
|
./benchmark.py accesscontrol/small --num-workers-for-import 1 --test-system-arg "split-file splitfiles/accesscontrol_small.shard_configuration bolt-num-workers 1"
|
||||||
|
|
||||||
|
- name: Run e2e tests
|
||||||
run: |
|
run: |
|
||||||
./tools/github/macro_benchmark_summary \
|
# TODO(gitbuda): Setup mgclient and pymgclient properly.
|
||||||
--current tests/macro_benchmark/.harness_summary \
|
cd tests
|
||||||
--previous ../parent/tests/macro_benchmark/.harness_summary \
|
./setup.sh
|
||||||
--output macro_benchmark_summary.txt
|
|
||||||
|
|
||||||
- name: Save macro benchmark summary
|
|
||||||
uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: "Macro benchmark summary"
|
|
||||||
path: macro_benchmark_summary.txt
|
|
||||||
|
|
||||||
- name: Run GQL Behave tests
|
|
||||||
run: |
|
|
||||||
cd tests/gql_behave
|
|
||||||
./continuous_integration
|
|
||||||
|
|
||||||
- name: Save quality assurance status
|
|
||||||
uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: "GQL Behave Status"
|
|
||||||
path: |
|
|
||||||
tests/gql_behave/gql_behave_status.csv
|
|
||||||
tests/gql_behave/gql_behave_status.html
|
|
||||||
|
|
||||||
- name: Run stress test (plain)
|
|
||||||
run: |
|
|
||||||
cd tests/stress
|
|
||||||
./continuous_integration
|
|
||||||
|
|
||||||
- name: Run stress test (SSL)
|
|
||||||
run: |
|
|
||||||
cd tests/stress
|
|
||||||
./continuous_integration --use-ssl
|
|
||||||
|
|
||||||
- name: Run durability test
|
|
||||||
run: |
|
|
||||||
cd tests/stress
|
|
||||||
source ve3/bin/activate
|
source ve3/bin/activate
|
||||||
python3 durability --num-steps 5
|
cd e2e
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../../libs/mgclient/lib python runner.py --workloads-root-directory ./distributed_queries
|
||||||
|
|||||||
46
.github/workflows/full_clang_tidy.yaml
vendored
Normal file
46
.github/workflows/full_clang_tidy.yaml
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
name: Run clang-tidy on the full codebase
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
clang_tidy_check:
|
||||||
|
name: "Clang-tidy check"
|
||||||
|
runs-on: [self-hosted, Linux, X64, Ubuntu20.04]
|
||||||
|
env:
|
||||||
|
THREADS: 24
|
||||||
|
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||||
|
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Set up repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
# Number of commits to fetch. `0` indicates all history for all
|
||||||
|
# branches and tags. (default: 1)
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Build debug binaries
|
||||||
|
run: |
|
||||||
|
# Activate toolchain.
|
||||||
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
# Initialize dependencies.
|
||||||
|
./init
|
||||||
|
|
||||||
|
# Build debug binaries.
|
||||||
|
|
||||||
|
cd build
|
||||||
|
cmake ..
|
||||||
|
make -j$THREADS
|
||||||
|
|
||||||
|
- name: Run clang-tidy
|
||||||
|
run: |
|
||||||
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
# The results are also written to standard output in order to retain them in the logs
|
||||||
|
./tools/github/clang-tidy/run-clang-tidy.py -p build -j $THREADS -extra-arg="-DMG_CLANG_TIDY_CHECK" -clang-tidy-binary=/opt/toolchain-v4/bin/clang-tidy "$PWD/src/*" |
|
||||||
|
tee ./build/full_clang_tidy_output.txt
|
||||||
|
|
||||||
|
- name: Summarize clang-tidy results
|
||||||
|
run: cat ./build/full_clang_tidy_output.txt | ./tools/github/clang-tidy/count_errors.sh
|
||||||
178
.github/workflows/package_all.yaml
vendored
Normal file
178
.github/workflows/package_all.yaml
vendored
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
name: Package All
|
||||||
|
|
||||||
|
# TODO(gitbuda): Cleanup docker container if GHA job was canceled.
|
||||||
|
|
||||||
|
on: workflow_dispatch
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
centos-7:
|
||||||
|
runs-on: [self-hosted, DockerMgBuild, X64]
|
||||||
|
timeout-minutes: 60
|
||||||
|
steps:
|
||||||
|
- name: "Set up repository"
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # Required because of release/get_version.py
|
||||||
|
- name: "Build package"
|
||||||
|
run: |
|
||||||
|
./release/package/run.sh package centos-7
|
||||||
|
- name: "Upload package"
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: centos-7
|
||||||
|
path: build/output/centos-7/memgraph*.rpm
|
||||||
|
|
||||||
|
centos-9:
|
||||||
|
runs-on: [self-hosted, DockerMgBuild, X64]
|
||||||
|
timeout-minutes: 60
|
||||||
|
steps:
|
||||||
|
- name: "Set up repository"
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # Required because of release/get_version.py
|
||||||
|
- name: "Build package"
|
||||||
|
run: |
|
||||||
|
./release/package/run.sh package centos-9
|
||||||
|
- name: "Upload package"
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: centos-9
|
||||||
|
path: build/output/centos-9/memgraph*.rpm
|
||||||
|
|
||||||
|
debian-10:
|
||||||
|
runs-on: [self-hosted, DockerMgBuild, X64]
|
||||||
|
timeout-minutes: 60
|
||||||
|
steps:
|
||||||
|
- name: "Set up repository"
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # Required because of release/get_version.py
|
||||||
|
- name: "Build package"
|
||||||
|
run: |
|
||||||
|
./release/package/run.sh package debian-10
|
||||||
|
- name: "Upload package"
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: debian-10
|
||||||
|
path: build/output/debian-10/memgraph*.deb
|
||||||
|
|
||||||
|
debian-11:
|
||||||
|
runs-on: [self-hosted, DockerMgBuild, X64]
|
||||||
|
timeout-minutes: 60
|
||||||
|
steps:
|
||||||
|
- name: "Set up repository"
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # Required because of release/get_version.py
|
||||||
|
- name: "Build package"
|
||||||
|
run: |
|
||||||
|
./release/package/run.sh package debian-11
|
||||||
|
- name: "Upload package"
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: debian-11
|
||||||
|
path: build/output/debian-11/memgraph*.deb
|
||||||
|
|
||||||
|
docker:
|
||||||
|
runs-on: [self-hosted, DockerMgBuild, X64]
|
||||||
|
timeout-minutes: 60
|
||||||
|
steps:
|
||||||
|
- name: "Set up repository"
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # Required because of release/get_version.py
|
||||||
|
- name: "Build package"
|
||||||
|
run: |
|
||||||
|
cd release/package
|
||||||
|
./run.sh package debian-11 --for-docker
|
||||||
|
./run.sh docker
|
||||||
|
- name: "Upload package"
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: docker
|
||||||
|
path: build/output/docker/memgraph*.tar.gz
|
||||||
|
|
||||||
|
ubuntu-1804:
|
||||||
|
runs-on: [self-hosted, DockerMgBuild, X64]
|
||||||
|
timeout-minutes: 60
|
||||||
|
steps:
|
||||||
|
- name: "Set up repository"
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # Required because of release/get_version.py
|
||||||
|
- name: "Build package"
|
||||||
|
run: |
|
||||||
|
./release/package/run.sh package ubuntu-18.04
|
||||||
|
- name: "Upload package"
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ubuntu-1804
|
||||||
|
path: build/output/ubuntu-18.04/memgraph*.deb
|
||||||
|
|
||||||
|
ubuntu-2004:
|
||||||
|
runs-on: [self-hosted, DockerMgBuild, X64]
|
||||||
|
timeout-minutes: 60
|
||||||
|
steps:
|
||||||
|
- name: "Set up repository"
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # Required because of release/get_version.py
|
||||||
|
- name: "Build package"
|
||||||
|
run: |
|
||||||
|
./release/package/run.sh package ubuntu-20.04
|
||||||
|
- name: "Upload package"
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ubuntu-2004
|
||||||
|
path: build/output/ubuntu-20.04/memgraph*.deb
|
||||||
|
|
||||||
|
ubuntu-2204:
|
||||||
|
runs-on: [self-hosted, DockerMgBuild, X64]
|
||||||
|
timeout-minutes: 60
|
||||||
|
steps:
|
||||||
|
- name: "Set up repository"
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # Required because of release/get_version.py
|
||||||
|
- name: "Build package"
|
||||||
|
run: |
|
||||||
|
./release/package/run.sh package ubuntu-22.04
|
||||||
|
- name: "Upload package"
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: ubuntu-2204
|
||||||
|
path: build/output/ubuntu-22.04/memgraph*.deb
|
||||||
|
|
||||||
|
debian-11-platform:
|
||||||
|
runs-on: [self-hosted, DockerMgBuild, X64]
|
||||||
|
timeout-minutes: 60
|
||||||
|
steps:
|
||||||
|
- name: "Set up repository"
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # Required because of release/get_version.py
|
||||||
|
- name: "Build package"
|
||||||
|
run: |
|
||||||
|
./release/package/run.sh package debian-11 --for-platform
|
||||||
|
- name: "Upload package"
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: debian-11-platform
|
||||||
|
path: build/output/debian-11/memgraph*.deb
|
||||||
|
|
||||||
|
debian-11-arm:
|
||||||
|
runs-on: [self-hosted, DockerMgBuild, ARM64, strange]
|
||||||
|
timeout-minutes: 60
|
||||||
|
steps:
|
||||||
|
- name: "Set up repository"
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # Required because of release/get_version.py
|
||||||
|
- name: "Build package"
|
||||||
|
run: |
|
||||||
|
./release/package/run.sh package debian-11-arm
|
||||||
|
- name: "Upload package"
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: debian-11-arm
|
||||||
|
path: build/output/debian-11-arm/memgraph*.deb
|
||||||
@@ -1,18 +1,23 @@
|
|||||||
name: Release CentOS
|
name: Release CentOS 8
|
||||||
|
|
||||||
on: [workflow_dispatch]
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 1 * * *"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
community_build:
|
community_build:
|
||||||
name: "Community build"
|
name: "Community build"
|
||||||
runs-on: [self-hosted, General, Linux, X64, CentOS7]
|
runs-on: [self-hosted, Linux, X64, CentOS8]
|
||||||
env:
|
env:
|
||||||
THREADS: 24
|
THREADS: 24
|
||||||
|
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||||
|
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||||
timeout-minutes: 960
|
timeout-minutes: 960
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Number of commits to fetch. `0` indicates all history for all
|
# Number of commits to fetch. `0` indicates all history for all
|
||||||
# branches and tags. (default: 1)
|
# branches and tags. (default: 1)
|
||||||
@@ -21,7 +26,7 @@ jobs:
|
|||||||
- name: Build community binaries
|
- name: Build community binaries
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Initialize dependencies.
|
# Initialize dependencies.
|
||||||
./init
|
./init
|
||||||
@@ -31,51 +36,26 @@ jobs:
|
|||||||
cmake -DCMAKE_BUILD_TYPE=release -DMG_ENTERPRISE=OFF ..
|
cmake -DCMAKE_BUILD_TYPE=release -DMG_ENTERPRISE=OFF ..
|
||||||
make -j$THREADS
|
make -j$THREADS
|
||||||
|
|
||||||
- name: Create community RPM package
|
|
||||||
run: |
|
|
||||||
# Activate toolchain.
|
|
||||||
source /opt/toolchain-v2/activate
|
|
||||||
|
|
||||||
# Create community RPM package.
|
|
||||||
cd build
|
|
||||||
mkdir output && cd output
|
|
||||||
cpack -G RPM --config ../CPackConfig.cmake
|
|
||||||
rpmlint memgraph*.rpm
|
|
||||||
|
|
||||||
- name: Save community RPM package
|
|
||||||
uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: "Community RPM package"
|
|
||||||
path: build/output/memgraph*.rpm
|
|
||||||
|
|
||||||
- name: Run unit tests
|
- name: Run unit tests
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Run unit tests.
|
# Run unit tests.
|
||||||
cd build
|
cd build
|
||||||
ctest -R memgraph__unit --output-on-failure
|
ctest -R memgraph__unit --output-on-failure
|
||||||
|
|
||||||
- name: Run stress test (plain)
|
|
||||||
run: |
|
|
||||||
cd tests/stress
|
|
||||||
./continuous_integration
|
|
||||||
|
|
||||||
- name: Run stress test (large)
|
|
||||||
run: |
|
|
||||||
cd tests/stress
|
|
||||||
./continuous_integration --large-dataset
|
|
||||||
|
|
||||||
coverage_build:
|
coverage_build:
|
||||||
name: "Coverage build"
|
name: "Coverage build"
|
||||||
runs-on: [self-hosted, General, Linux, X64, CentOS7]
|
runs-on: [self-hosted, Linux, X64, CentOS8]
|
||||||
env:
|
env:
|
||||||
THREADS: 24
|
THREADS: 24
|
||||||
|
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||||
|
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Number of commits to fetch. `0` indicates all history for all
|
# Number of commits to fetch. `0` indicates all history for all
|
||||||
# branches and tags. (default: 1)
|
# branches and tags. (default: 1)
|
||||||
@@ -84,7 +64,7 @@ jobs:
|
|||||||
- name: Build coverage binaries
|
- name: Build coverage binaries
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Initialize dependencies.
|
# Initialize dependencies.
|
||||||
./init
|
./init
|
||||||
@@ -97,7 +77,7 @@ jobs:
|
|||||||
- name: Run unit tests
|
- name: Run unit tests
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Run unit tests.
|
# Run unit tests.
|
||||||
cd build
|
cd build
|
||||||
@@ -106,7 +86,7 @@ jobs:
|
|||||||
- name: Compute code coverage
|
- name: Compute code coverage
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Compute code coverage.
|
# Compute code coverage.
|
||||||
cd tools/github
|
cd tools/github
|
||||||
@@ -117,20 +97,22 @@ jobs:
|
|||||||
tar -czf code_coverage.tar.gz coverage.json html report.json summary.rmu
|
tar -czf code_coverage.tar.gz coverage.json html report.json summary.rmu
|
||||||
|
|
||||||
- name: Save code coverage
|
- name: Save code coverage
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: "Code coverage"
|
name: "Code coverage"
|
||||||
path: tools/github/generated/code_coverage.tar.gz
|
path: tools/github/generated/code_coverage.tar.gz
|
||||||
|
|
||||||
debug_build:
|
debug_build:
|
||||||
name: "Debug build"
|
name: "Debug build"
|
||||||
runs-on: [self-hosted, General, Linux, X64, CentOS7]
|
runs-on: [self-hosted, Linux, X64, CentOS8]
|
||||||
env:
|
env:
|
||||||
THREADS: 24
|
THREADS: 24
|
||||||
|
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||||
|
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Number of commits to fetch. `0` indicates all history for all
|
# Number of commits to fetch. `0` indicates all history for all
|
||||||
# branches and tags. (default: 1)
|
# branches and tags. (default: 1)
|
||||||
@@ -139,7 +121,7 @@ jobs:
|
|||||||
- name: Build debug binaries
|
- name: Build debug binaries
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Initialize dependencies.
|
# Initialize dependencies.
|
||||||
./init
|
./init
|
||||||
@@ -152,7 +134,7 @@ jobs:
|
|||||||
- name: Run leftover CTest tests
|
- name: Run leftover CTest tests
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Run leftover CTest tests (all except unit and benchmark tests).
|
# Run leftover CTest tests (all except unit and benchmark tests).
|
||||||
cd build
|
cd build
|
||||||
@@ -184,28 +166,30 @@ jobs:
|
|||||||
- name: Run cppcheck and clang-format
|
- name: Run cppcheck and clang-format
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Run cppcheck and clang-format.
|
# Run cppcheck and clang-format.
|
||||||
cd tools/github
|
cd tools/github
|
||||||
./cppcheck_and_clang_format diff
|
./cppcheck_and_clang_format diff
|
||||||
|
|
||||||
- name: Save cppcheck and clang-format errors
|
- name: Save cppcheck and clang-format errors
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: "Code coverage"
|
name: "Code coverage"
|
||||||
path: tools/github/cppcheck_and_clang_format.txt
|
path: tools/github/cppcheck_and_clang_format.txt
|
||||||
|
|
||||||
release_build:
|
release_build:
|
||||||
name: "Release build"
|
name: "Release build"
|
||||||
runs-on: [self-hosted, General, Linux, X64, CentOS7]
|
runs-on: [self-hosted, Linux, X64, CentOS8]
|
||||||
env:
|
env:
|
||||||
THREADS: 24
|
THREADS: 24
|
||||||
|
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||||
|
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||||
timeout-minutes: 960
|
timeout-minutes: 960
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Number of commits to fetch. `0` indicates all history for all
|
# Number of commits to fetch. `0` indicates all history for all
|
||||||
# branches and tags. (default: 1)
|
# branches and tags. (default: 1)
|
||||||
@@ -214,7 +198,7 @@ jobs:
|
|||||||
- name: Build release binaries
|
- name: Build release binaries
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Initialize dependencies.
|
# Initialize dependencies.
|
||||||
./init
|
./init
|
||||||
@@ -227,16 +211,21 @@ jobs:
|
|||||||
- name: Create enterprise RPM package
|
- name: Create enterprise RPM package
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
cd build
|
||||||
|
|
||||||
|
# create mgconsole
|
||||||
|
# we use the -B to force the build
|
||||||
|
make -j$THREADS -B mgconsole
|
||||||
|
|
||||||
# Create enterprise RPM package.
|
# Create enterprise RPM package.
|
||||||
cd build
|
|
||||||
mkdir output && cd output
|
mkdir output && cd output
|
||||||
cpack -G RPM --config ../CPackConfig.cmake
|
cpack -G RPM --config ../CPackConfig.cmake
|
||||||
rpmlint memgraph*.rpm
|
rpmlint memgraph*.rpm
|
||||||
|
|
||||||
- name: Save enterprise RPM package
|
- name: Save enterprise RPM package
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: "Enterprise RPM package"
|
name: "Enterprise RPM package"
|
||||||
path: build/output/memgraph*.rpm
|
path: build/output/memgraph*.rpm
|
||||||
@@ -244,7 +233,7 @@ jobs:
|
|||||||
- name: Run micro benchmark tests
|
- name: Run micro benchmark tests
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Run micro benchmark tests.
|
# Run micro benchmark tests.
|
||||||
cd build
|
cd build
|
||||||
@@ -273,13 +262,31 @@ jobs:
|
|||||||
./continuous_integration
|
./continuous_integration
|
||||||
|
|
||||||
- name: Save quality assurance status
|
- name: Save quality assurance status
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: "GQL Behave Status"
|
name: "GQL Behave Status"
|
||||||
path: |
|
path: |
|
||||||
tests/gql_behave/gql_behave_status.csv
|
tests/gql_behave/gql_behave_status.csv
|
||||||
tests/gql_behave/gql_behave_status.html
|
tests/gql_behave/gql_behave_status.html
|
||||||
|
|
||||||
|
- name: Run unit tests
|
||||||
|
run: |
|
||||||
|
# Activate toolchain.
|
||||||
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
# Run unit tests.
|
||||||
|
cd build
|
||||||
|
ctest -R memgraph__unit --output-on-failure
|
||||||
|
|
||||||
|
- name: Run e2e tests
|
||||||
|
run: |
|
||||||
|
# TODO(gitbuda): Setup mgclient and pymgclient properly.
|
||||||
|
cd tests
|
||||||
|
./setup.sh
|
||||||
|
source ve3/bin/activate
|
||||||
|
cd e2e
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../../libs/mgclient/lib python runner.py --workloads-root-directory .
|
||||||
|
|
||||||
- name: Run stress test (plain)
|
- name: Run stress test (plain)
|
||||||
run: |
|
run: |
|
||||||
cd tests/stress
|
cd tests/stress
|
||||||
356
.github/workflows/release_debian10.yaml
vendored
Normal file
356
.github/workflows/release_debian10.yaml
vendored
Normal file
@@ -0,0 +1,356 @@
|
|||||||
|
name: Release Debian 10
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 1 * * *"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
community_build:
|
||||||
|
name: "Community build"
|
||||||
|
runs-on: [self-hosted, Linux, X64, Debian10]
|
||||||
|
env:
|
||||||
|
THREADS: 24
|
||||||
|
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||||
|
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||||
|
timeout-minutes: 960
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Set up repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
# Number of commits to fetch. `0` indicates all history for all
|
||||||
|
# branches and tags. (default: 1)
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Build community binaries
|
||||||
|
run: |
|
||||||
|
# Activate toolchain.
|
||||||
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
# Initialize dependencies.
|
||||||
|
./init
|
||||||
|
|
||||||
|
# Build community binaries.
|
||||||
|
cd build
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=release -DMG_ENTERPRISE=OFF ..
|
||||||
|
make -j$THREADS
|
||||||
|
|
||||||
|
- name: Run unit tests
|
||||||
|
run: |
|
||||||
|
# Activate toolchain.
|
||||||
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
# Run unit tests.
|
||||||
|
cd build
|
||||||
|
ctest -R memgraph__unit --output-on-failure
|
||||||
|
|
||||||
|
coverage_build:
|
||||||
|
name: "Coverage build"
|
||||||
|
runs-on: [self-hosted, Linux, X64, Debian10]
|
||||||
|
env:
|
||||||
|
THREADS: 24
|
||||||
|
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||||
|
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Set up repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
# Number of commits to fetch. `0` indicates all history for all
|
||||||
|
# branches and tags. (default: 1)
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Build coverage binaries
|
||||||
|
run: |
|
||||||
|
# Activate toolchain.
|
||||||
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
# Initialize dependencies.
|
||||||
|
./init
|
||||||
|
|
||||||
|
# Build coverage binaries.
|
||||||
|
cd build
|
||||||
|
cmake -DTEST_COVERAGE=ON ..
|
||||||
|
make -j$THREADS memgraph__unit
|
||||||
|
|
||||||
|
- name: Run unit tests
|
||||||
|
run: |
|
||||||
|
# Activate toolchain.
|
||||||
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
# Run unit tests.
|
||||||
|
cd build
|
||||||
|
ctest -R memgraph__unit --output-on-failure
|
||||||
|
|
||||||
|
- name: Compute code coverage
|
||||||
|
run: |
|
||||||
|
# Activate toolchain.
|
||||||
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
# Compute code coverage.
|
||||||
|
cd tools/github
|
||||||
|
./coverage_convert
|
||||||
|
|
||||||
|
# Package code coverage.
|
||||||
|
cd generated
|
||||||
|
tar -czf code_coverage.tar.gz coverage.json html report.json summary.rmu
|
||||||
|
|
||||||
|
- name: Save code coverage
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: "Code coverage"
|
||||||
|
path: tools/github/generated/code_coverage.tar.gz
|
||||||
|
|
||||||
|
debug_build:
|
||||||
|
name: "Debug build"
|
||||||
|
runs-on: [self-hosted, Linux, X64, Debian10]
|
||||||
|
env:
|
||||||
|
THREADS: 24
|
||||||
|
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||||
|
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Set up repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
# Number of commits to fetch. `0` indicates all history for all
|
||||||
|
# branches and tags. (default: 1)
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Build debug binaries
|
||||||
|
run: |
|
||||||
|
# Activate toolchain.
|
||||||
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
# Initialize dependencies.
|
||||||
|
./init
|
||||||
|
|
||||||
|
# Build debug binaries.
|
||||||
|
cd build
|
||||||
|
cmake ..
|
||||||
|
make -j$THREADS
|
||||||
|
|
||||||
|
- name: Run leftover CTest tests
|
||||||
|
run: |
|
||||||
|
# Activate toolchain.
|
||||||
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
# Run leftover CTest tests (all except unit and benchmark tests).
|
||||||
|
cd build
|
||||||
|
ctest -E "(memgraph__unit|memgraph__benchmark)" --output-on-failure
|
||||||
|
|
||||||
|
- name: Run drivers tests
|
||||||
|
run: |
|
||||||
|
./tests/drivers/run.sh
|
||||||
|
|
||||||
|
- name: Run integration tests
|
||||||
|
run: |
|
||||||
|
cd tests/integration
|
||||||
|
for name in *; do
|
||||||
|
if [ ! -d $name ]; then continue; fi
|
||||||
|
pushd $name >/dev/null
|
||||||
|
echo "Running: $name"
|
||||||
|
if [ -x prepare.sh ]; then
|
||||||
|
./prepare.sh
|
||||||
|
fi
|
||||||
|
if [ -x runner.py ]; then
|
||||||
|
./runner.py
|
||||||
|
elif [ -x runner.sh ]; then
|
||||||
|
./runner.sh
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
popd >/dev/null
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Run cppcheck and clang-format
|
||||||
|
run: |
|
||||||
|
# Activate toolchain.
|
||||||
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
# Run cppcheck and clang-format.
|
||||||
|
cd tools/github
|
||||||
|
./cppcheck_and_clang_format diff
|
||||||
|
|
||||||
|
- name: Save cppcheck and clang-format errors
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: "Code coverage"
|
||||||
|
path: tools/github/cppcheck_and_clang_format.txt
|
||||||
|
|
||||||
|
release_build:
|
||||||
|
name: "Release build"
|
||||||
|
runs-on: [self-hosted, Linux, X64, Debian10]
|
||||||
|
env:
|
||||||
|
THREADS: 24
|
||||||
|
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||||
|
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||||
|
timeout-minutes: 960
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Set up repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
# Number of commits to fetch. `0` indicates all history for all
|
||||||
|
# branches and tags. (default: 1)
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Build release binaries
|
||||||
|
run: |
|
||||||
|
# Activate toolchain.
|
||||||
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
# Initialize dependencies.
|
||||||
|
./init
|
||||||
|
|
||||||
|
# Build release binaries.
|
||||||
|
cd build
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=release ..
|
||||||
|
make -j$THREADS
|
||||||
|
|
||||||
|
- name: Create enterprise DEB package
|
||||||
|
run: |
|
||||||
|
# Activate toolchain.
|
||||||
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
cd build
|
||||||
|
|
||||||
|
# create mgconsole
|
||||||
|
# we use the -B to force the build
|
||||||
|
make -j$THREADS -B mgconsole
|
||||||
|
|
||||||
|
# Create enterprise DEB package.
|
||||||
|
mkdir output && cd output
|
||||||
|
cpack -G DEB --config ../CPackConfig.cmake
|
||||||
|
|
||||||
|
- name: Save enterprise DEB package
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: "Enterprise DEB package"
|
||||||
|
path: build/output/memgraph*.deb
|
||||||
|
|
||||||
|
- name: Run micro benchmark tests
|
||||||
|
run: |
|
||||||
|
# Activate toolchain.
|
||||||
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
# Run micro benchmark tests.
|
||||||
|
cd build
|
||||||
|
# The `eval` benchmark needs a large stack limit.
|
||||||
|
ulimit -s 262144
|
||||||
|
ctest -R memgraph__benchmark -V
|
||||||
|
|
||||||
|
- name: Run macro benchmark tests
|
||||||
|
run: |
|
||||||
|
cd tests/macro_benchmark
|
||||||
|
./harness QuerySuite MemgraphRunner \
|
||||||
|
--groups aggregation 1000_create unwind_create dense_expand match \
|
||||||
|
--no-strict
|
||||||
|
|
||||||
|
- name: Run parallel macro benchmark tests
|
||||||
|
run: |
|
||||||
|
cd tests/macro_benchmark
|
||||||
|
./harness QueryParallelSuite MemgraphRunner \
|
||||||
|
--groups aggregation_parallel create_parallel bfs_parallel \
|
||||||
|
--num-database-workers 9 --num-clients-workers 30 \
|
||||||
|
--no-strict
|
||||||
|
|
||||||
|
- name: Run GQL Behave tests
|
||||||
|
run: |
|
||||||
|
cd tests/gql_behave
|
||||||
|
./continuous_integration
|
||||||
|
|
||||||
|
- name: Save quality assurance status
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: "GQL Behave Status"
|
||||||
|
path: |
|
||||||
|
tests/gql_behave/gql_behave_status.csv
|
||||||
|
tests/gql_behave/gql_behave_status.html
|
||||||
|
|
||||||
|
- name: Run unit tests
|
||||||
|
run: |
|
||||||
|
# Activate toolchain.
|
||||||
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
# Run unit tests.
|
||||||
|
cd build
|
||||||
|
ctest -R memgraph__unit --output-on-failure
|
||||||
|
|
||||||
|
- name: Run e2e tests
|
||||||
|
run: |
|
||||||
|
# TODO(gitbuda): Setup mgclient and pymgclient properly.
|
||||||
|
cd tests
|
||||||
|
./setup.sh
|
||||||
|
source ve3/bin/activate
|
||||||
|
cd e2e
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../../libs/mgclient/lib python runner.py --workloads-root-directory .
|
||||||
|
|
||||||
|
- name: Run stress test (plain)
|
||||||
|
run: |
|
||||||
|
cd tests/stress
|
||||||
|
./continuous_integration
|
||||||
|
|
||||||
|
- name: Run stress test (SSL)
|
||||||
|
run: |
|
||||||
|
cd tests/stress
|
||||||
|
./continuous_integration --use-ssl
|
||||||
|
|
||||||
|
- name: Run stress test (large)
|
||||||
|
run: |
|
||||||
|
cd tests/stress
|
||||||
|
./continuous_integration --large-dataset
|
||||||
|
|
||||||
|
- name: Run durability test (plain)
|
||||||
|
run: |
|
||||||
|
cd tests/stress
|
||||||
|
source ve3/bin/activate
|
||||||
|
python3 durability --num-steps 5
|
||||||
|
|
||||||
|
- name: Run durability test (large)
|
||||||
|
run: |
|
||||||
|
cd tests/stress
|
||||||
|
source ve3/bin/activate
|
||||||
|
python3 durability --num-steps 20
|
||||||
|
|
||||||
|
release_jepsen_test:
|
||||||
|
name: "Release Jepsen Test"
|
||||||
|
runs-on: [self-hosted, Linux, X64, Debian10, JepsenControl]
|
||||||
|
env:
|
||||||
|
THREADS: 24
|
||||||
|
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||||
|
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||||
|
timeout-minutes: 60
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Set up repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
# Number of commits to fetch. `0` indicates all history for all
|
||||||
|
# branches and tags. (default: 1)
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Build release binaries
|
||||||
|
run: |
|
||||||
|
# Activate toolchain.
|
||||||
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
# Initialize dependencies.
|
||||||
|
./init
|
||||||
|
|
||||||
|
# Build only memgraph release binary.
|
||||||
|
cd build
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=release ..
|
||||||
|
make -j$THREADS memgraph
|
||||||
|
|
||||||
|
- name: Run Jepsen tests
|
||||||
|
run: |
|
||||||
|
cd tests/jepsen
|
||||||
|
./run.sh test --binary ../../build/memgraph --run-args "test-all --node-configs resources/node-config.edn" --ignore-run-stdout-logs --ignore-run-stderr-logs
|
||||||
|
|
||||||
|
- name: Save Jepsen report
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
if: ${{ always() }}
|
||||||
|
with:
|
||||||
|
name: "Jepsen Report"
|
||||||
|
path: tests/jepsen/Jepsen.tar.gz
|
||||||
69
.github/workflows/release_docker.yaml
vendored
Normal file
69
.github/workflows/release_docker.yaml
vendored
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
name: Publish Docker images
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: "Memgraph binary version to publish on DockerHub."
|
||||||
|
required: true
|
||||||
|
force_release:
|
||||||
|
type: boolean
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker_publish:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
DOCKER_ORGANIZATION_NAME: memgraph
|
||||||
|
DOCKER_REPOSITORY_NAME: memgraph
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
id: buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
|
||||||
|
- name: Log in to Docker Hub
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Download memgraph binary
|
||||||
|
run: |
|
||||||
|
cd release/docker
|
||||||
|
curl -L https://download.memgraph.com/memgraph/v${{ github.event.inputs.version }}/debian-11/memgraph_${{ github.event.inputs.version }}-1_amd64.deb > memgraph-amd64.deb
|
||||||
|
curl -L https://download.memgraph.com/memgraph/v${{ github.event.inputs.version }}/debian-11-aarch64/memgraph_${{ github.event.inputs.version }}-1_arm64.deb > memgraph-arm64.deb
|
||||||
|
|
||||||
|
- name: Check if specified version is already pushed
|
||||||
|
run: |
|
||||||
|
EXISTS=$(docker manifest inspect $DOCKER_ORGANIZATION_NAME/$DOCKER_REPOSITORY_NAME:${{ github.event.inputs.version }} > /dev/null; echo $?)
|
||||||
|
echo $EXISTS
|
||||||
|
if [[ ${EXISTS} -eq 0 ]]; then
|
||||||
|
echo 'The specified version has been already released to DockerHub.'
|
||||||
|
if [[ ${{ github.event.inputs.force_release }} = true ]]; then
|
||||||
|
echo 'Forcing the release!'
|
||||||
|
else
|
||||||
|
echo 'Stopping the release!'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo 'All good the specified version has not been release to DockerHub.'
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Build & push docker images
|
||||||
|
run: |
|
||||||
|
cd release/docker
|
||||||
|
docker buildx build \
|
||||||
|
--build-arg BINARY_NAME="memgraph-" \
|
||||||
|
--build-arg EXTENSION="deb" \
|
||||||
|
--platform linux/amd64,linux/arm64 \
|
||||||
|
--tag $DOCKER_ORGANIZATION_NAME/$DOCKER_REPOSITORY_NAME:${{ github.event.inputs.version }} \
|
||||||
|
--tag $DOCKER_ORGANIZATION_NAME/$DOCKER_REPOSITORY_NAME:latest \
|
||||||
|
--file memgraph_deb.dockerfile \
|
||||||
|
--push .
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
name: Release
|
name: Release Ubuntu 20.04
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@@ -8,14 +8,16 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
community_build:
|
community_build:
|
||||||
name: "Community build"
|
name: "Community build"
|
||||||
runs-on: [self-hosted, General, Linux, X64, Debian10]
|
runs-on: [self-hosted, Linux, X64, Ubuntu20.04]
|
||||||
env:
|
env:
|
||||||
THREADS: 24
|
THREADS: 24
|
||||||
|
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||||
|
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||||
timeout-minutes: 960
|
timeout-minutes: 960
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Number of commits to fetch. `0` indicates all history for all
|
# Number of commits to fetch. `0` indicates all history for all
|
||||||
# branches and tags. (default: 1)
|
# branches and tags. (default: 1)
|
||||||
@@ -24,7 +26,7 @@ jobs:
|
|||||||
- name: Build community binaries
|
- name: Build community binaries
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Initialize dependencies.
|
# Initialize dependencies.
|
||||||
./init
|
./init
|
||||||
@@ -34,50 +36,26 @@ jobs:
|
|||||||
cmake -DCMAKE_BUILD_TYPE=release -DMG_ENTERPRISE=OFF ..
|
cmake -DCMAKE_BUILD_TYPE=release -DMG_ENTERPRISE=OFF ..
|
||||||
make -j$THREADS
|
make -j$THREADS
|
||||||
|
|
||||||
- name: Create community DEB package
|
|
||||||
run: |
|
|
||||||
# Activate toolchain.
|
|
||||||
source /opt/toolchain-v2/activate
|
|
||||||
|
|
||||||
# Create community DEB package.
|
|
||||||
cd build
|
|
||||||
mkdir output && cd output
|
|
||||||
cpack -G DEB --config ../CPackConfig.cmake
|
|
||||||
|
|
||||||
- name: Save community DEB package
|
|
||||||
uses: actions/upload-artifact@v2
|
|
||||||
with:
|
|
||||||
name: "Community DEB package"
|
|
||||||
path: build/output/memgraph*.deb
|
|
||||||
|
|
||||||
- name: Run unit tests
|
- name: Run unit tests
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Run unit tests.
|
# Run unit tests.
|
||||||
cd build
|
cd build
|
||||||
ctest -R memgraph__unit --output-on-failure
|
ctest -R memgraph__unit --output-on-failure
|
||||||
|
|
||||||
- name: Run stress test (plain)
|
|
||||||
run: |
|
|
||||||
cd tests/stress
|
|
||||||
./continuous_integration
|
|
||||||
|
|
||||||
- name: Run stress test (large)
|
|
||||||
run: |
|
|
||||||
cd tests/stress
|
|
||||||
./continuous_integration --large-dataset
|
|
||||||
|
|
||||||
coverage_build:
|
coverage_build:
|
||||||
name: "Coverage build"
|
name: "Coverage build"
|
||||||
runs-on: [self-hosted, General, Linux, X64, Debian10]
|
runs-on: [self-hosted, Linux, X64, Ubuntu20.04]
|
||||||
env:
|
env:
|
||||||
THREADS: 24
|
THREADS: 24
|
||||||
|
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||||
|
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Number of commits to fetch. `0` indicates all history for all
|
# Number of commits to fetch. `0` indicates all history for all
|
||||||
# branches and tags. (default: 1)
|
# branches and tags. (default: 1)
|
||||||
@@ -86,7 +64,7 @@ jobs:
|
|||||||
- name: Build coverage binaries
|
- name: Build coverage binaries
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Initialize dependencies.
|
# Initialize dependencies.
|
||||||
./init
|
./init
|
||||||
@@ -99,7 +77,7 @@ jobs:
|
|||||||
- name: Run unit tests
|
- name: Run unit tests
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Run unit tests.
|
# Run unit tests.
|
||||||
cd build
|
cd build
|
||||||
@@ -108,7 +86,7 @@ jobs:
|
|||||||
- name: Compute code coverage
|
- name: Compute code coverage
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Compute code coverage.
|
# Compute code coverage.
|
||||||
cd tools/github
|
cd tools/github
|
||||||
@@ -119,20 +97,22 @@ jobs:
|
|||||||
tar -czf code_coverage.tar.gz coverage.json html report.json summary.rmu
|
tar -czf code_coverage.tar.gz coverage.json html report.json summary.rmu
|
||||||
|
|
||||||
- name: Save code coverage
|
- name: Save code coverage
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: "Code coverage"
|
name: "Code coverage"
|
||||||
path: tools/github/generated/code_coverage.tar.gz
|
path: tools/github/generated/code_coverage.tar.gz
|
||||||
|
|
||||||
debug_build:
|
debug_build:
|
||||||
name: "Debug build"
|
name: "Debug build"
|
||||||
runs-on: [self-hosted, General, Linux, X64, Debian10]
|
runs-on: [self-hosted, Linux, X64, Ubuntu20.04]
|
||||||
env:
|
env:
|
||||||
THREADS: 24
|
THREADS: 24
|
||||||
|
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||||
|
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Number of commits to fetch. `0` indicates all history for all
|
# Number of commits to fetch. `0` indicates all history for all
|
||||||
# branches and tags. (default: 1)
|
# branches and tags. (default: 1)
|
||||||
@@ -141,7 +121,7 @@ jobs:
|
|||||||
- name: Build debug binaries
|
- name: Build debug binaries
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Initialize dependencies.
|
# Initialize dependencies.
|
||||||
./init
|
./init
|
||||||
@@ -154,7 +134,7 @@ jobs:
|
|||||||
- name: Run leftover CTest tests
|
- name: Run leftover CTest tests
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Run leftover CTest tests (all except unit and benchmark tests).
|
# Run leftover CTest tests (all except unit and benchmark tests).
|
||||||
cd build
|
cd build
|
||||||
@@ -186,28 +166,30 @@ jobs:
|
|||||||
- name: Run cppcheck and clang-format
|
- name: Run cppcheck and clang-format
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Run cppcheck and clang-format.
|
# Run cppcheck and clang-format.
|
||||||
cd tools/github
|
cd tools/github
|
||||||
./cppcheck_and_clang_format diff
|
./cppcheck_and_clang_format diff
|
||||||
|
|
||||||
- name: Save cppcheck and clang-format errors
|
- name: Save cppcheck and clang-format errors
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: "Code coverage"
|
name: "Code coverage"
|
||||||
path: tools/github/cppcheck_and_clang_format.txt
|
path: tools/github/cppcheck_and_clang_format.txt
|
||||||
|
|
||||||
release_build:
|
release_build:
|
||||||
name: "Release build"
|
name: "Release build"
|
||||||
runs-on: [self-hosted, General, Linux, X64, Debian10]
|
runs-on: [self-hosted, Linux, X64, Ubuntu20.04]
|
||||||
env:
|
env:
|
||||||
THREADS: 24
|
THREADS: 24
|
||||||
|
MEMGRAPH_ENTERPRISE_LICENSE: ${{ secrets.MEMGRAPH_ENTERPRISE_LICENSE }}
|
||||||
|
MEMGRAPH_ORGANIZATION_NAME: ${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}
|
||||||
timeout-minutes: 960
|
timeout-minutes: 960
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Set up repository
|
- name: Set up repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
# Number of commits to fetch. `0` indicates all history for all
|
# Number of commits to fetch. `0` indicates all history for all
|
||||||
# branches and tags. (default: 1)
|
# branches and tags. (default: 1)
|
||||||
@@ -216,7 +198,7 @@ jobs:
|
|||||||
- name: Build release binaries
|
- name: Build release binaries
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Initialize dependencies.
|
# Initialize dependencies.
|
||||||
./init
|
./init
|
||||||
@@ -229,15 +211,20 @@ jobs:
|
|||||||
- name: Create enterprise DEB package
|
- name: Create enterprise DEB package
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
cd build
|
||||||
|
|
||||||
|
# create mgconsole
|
||||||
|
# we use the -B to force the build
|
||||||
|
make -j$THREADS -B mgconsole
|
||||||
|
|
||||||
# Create enterprise DEB package.
|
# Create enterprise DEB package.
|
||||||
cd build
|
|
||||||
mkdir output && cd output
|
mkdir output && cd output
|
||||||
cpack -G DEB --config ../CPackConfig.cmake
|
cpack -G DEB --config ../CPackConfig.cmake
|
||||||
|
|
||||||
- name: Save enterprise DEB package
|
- name: Save enterprise DEB package
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: "Enterprise DEB package"
|
name: "Enterprise DEB package"
|
||||||
path: build/output/memgraph*.deb
|
path: build/output/memgraph*.deb
|
||||||
@@ -245,7 +232,7 @@ jobs:
|
|||||||
- name: Run micro benchmark tests
|
- name: Run micro benchmark tests
|
||||||
run: |
|
run: |
|
||||||
# Activate toolchain.
|
# Activate toolchain.
|
||||||
source /opt/toolchain-v2/activate
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
# Run micro benchmark tests.
|
# Run micro benchmark tests.
|
||||||
cd build
|
cd build
|
||||||
@@ -274,13 +261,31 @@ jobs:
|
|||||||
./continuous_integration
|
./continuous_integration
|
||||||
|
|
||||||
- name: Save quality assurance status
|
- name: Save quality assurance status
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: "GQL Behave Status"
|
name: "GQL Behave Status"
|
||||||
path: |
|
path: |
|
||||||
tests/gql_behave/gql_behave_status.csv
|
tests/gql_behave/gql_behave_status.csv
|
||||||
tests/gql_behave/gql_behave_status.html
|
tests/gql_behave/gql_behave_status.html
|
||||||
|
|
||||||
|
- name: Run unit tests
|
||||||
|
run: |
|
||||||
|
# Activate toolchain.
|
||||||
|
source /opt/toolchain-v4/activate
|
||||||
|
|
||||||
|
# Run unit tests.
|
||||||
|
cd build
|
||||||
|
ctest -R memgraph__unit --output-on-failure
|
||||||
|
|
||||||
|
- name: Run e2e tests
|
||||||
|
run: |
|
||||||
|
# TODO(gitbuda): Setup mgclient and pymgclient properly.
|
||||||
|
cd tests
|
||||||
|
./setup.sh
|
||||||
|
source ve3/bin/activate
|
||||||
|
cd e2e
|
||||||
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../../libs/mgclient/lib python runner.py --workloads-root-directory .
|
||||||
|
|
||||||
- name: Run stress test (plain)
|
- name: Run stress test (plain)
|
||||||
run: |
|
run: |
|
||||||
cd tests/stress
|
cd tests/stress
|
||||||
116
.github/workflows/test_all_workers.yaml
vendored
116
.github/workflows/test_all_workers.yaml
vendored
@@ -1,116 +0,0 @@
|
|||||||
name: Test All Workers
|
|
||||||
|
|
||||||
on: [workflow_dispatch]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
HP-DL360G6-1:
|
|
||||||
name: "HP-DL360G6-1"
|
|
||||||
runs-on: [HP-DL360G6-1]
|
|
||||||
timeout-minutes: 10
|
|
||||||
steps:
|
|
||||||
- name: Set up repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Check the system
|
|
||||||
run: |
|
|
||||||
source /opt/toolchain-v2/activate
|
|
||||||
./tools/check-build-system
|
|
||||||
HP-DL360G6-2:
|
|
||||||
name: "HP-DL360G6-2"
|
|
||||||
runs-on: [HP-DL360G6-2]
|
|
||||||
timeout-minutes: 10
|
|
||||||
steps:
|
|
||||||
- name: Set up repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Check the system
|
|
||||||
run: |
|
|
||||||
source /opt/toolchain-v2/activate
|
|
||||||
./tools/check-build-system
|
|
||||||
HP-DL360G6-3:
|
|
||||||
name: "HP-DL360G6-3"
|
|
||||||
runs-on: [HP-DL360G6-3]
|
|
||||||
timeout-minutes: 10
|
|
||||||
steps:
|
|
||||||
- name: Set up repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Check the system
|
|
||||||
run: |
|
|
||||||
source /opt/toolchain-v2/activate
|
|
||||||
./tools/check-build-system
|
|
||||||
|
|
||||||
HP-DL360G6-v2-1:
|
|
||||||
name: "HP-DL360G6-v2-1"
|
|
||||||
runs-on: [HP-DL360G6-v2-1]
|
|
||||||
timeout-minutes: 10
|
|
||||||
steps:
|
|
||||||
- name: Set up repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Check the system
|
|
||||||
run: |
|
|
||||||
source /opt/toolchain-v2/activate
|
|
||||||
./tools/check-build-system
|
|
||||||
HP-DL360G6-v2-2:
|
|
||||||
name: "HP-DL360G6-v2-2"
|
|
||||||
runs-on: [HP-DL360G6-v2-2]
|
|
||||||
timeout-minutes: 10
|
|
||||||
steps:
|
|
||||||
- name: Set up repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Check the system
|
|
||||||
run: |
|
|
||||||
source /opt/toolchain-v2/activate
|
|
||||||
./tools/check-build-system
|
|
||||||
HP-DL360G6-v2-3:
|
|
||||||
name: "HP-DL360G6-v2-3"
|
|
||||||
runs-on: [HP-DL360G6-v2-3]
|
|
||||||
timeout-minutes: 10
|
|
||||||
steps:
|
|
||||||
- name: Set up repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Check the system
|
|
||||||
run: |
|
|
||||||
source /opt/toolchain-v2/activate
|
|
||||||
./tools/check-build-system
|
|
||||||
HP-DL360G6-v2-4:
|
|
||||||
name: "HP-DL360G6-v2-4"
|
|
||||||
runs-on: [HP-DL360G6-v2-4]
|
|
||||||
timeout-minutes: 10
|
|
||||||
steps:
|
|
||||||
- name: Set up repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Check the system
|
|
||||||
run: |
|
|
||||||
source /opt/toolchain-v2/activate
|
|
||||||
./tools/check-build-system
|
|
||||||
HP-DL360G6-v2-5:
|
|
||||||
name: "HP-DL360G6-v2-5"
|
|
||||||
runs-on: [HP-DL360G6-v2-5]
|
|
||||||
timeout-minutes: 10
|
|
||||||
steps:
|
|
||||||
- name: Set up repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Check the system
|
|
||||||
run: |
|
|
||||||
source /opt/toolchain-v2/activate
|
|
||||||
./tools/check-build-system
|
|
||||||
HP-DL360G6-v2-6:
|
|
||||||
name: "HP-DL360G6-v2-6"
|
|
||||||
runs-on: [HP-DL360G6-v2-6]
|
|
||||||
timeout-minutes: 10
|
|
||||||
steps:
|
|
||||||
- name: Set up repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Check the system
|
|
||||||
run: |
|
|
||||||
source /opt/toolchain-v2/activate
|
|
||||||
./tools/check-build-system
|
|
||||||
HP-DL360G6-v2-7:
|
|
||||||
name: "HP-DL360G6-v2-7"
|
|
||||||
runs-on: [HP-DL360G6-v2-7]
|
|
||||||
timeout-minutes: 10
|
|
||||||
steps:
|
|
||||||
- name: Set up repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Check the system
|
|
||||||
run: |
|
|
||||||
source /opt/toolchain-v2/activate
|
|
||||||
./tools/check-build-system
|
|
||||||
12
.gitignore
vendored
12
.gitignore
vendored
@@ -23,6 +23,8 @@ cmake-build-*
|
|||||||
cmake/DownloadProject/
|
cmake/DownloadProject/
|
||||||
dist/
|
dist/
|
||||||
src/query/frontend/opencypher/generated/
|
src/query/frontend/opencypher/generated/
|
||||||
|
src/query/v2/frontend/opencypher/generated/
|
||||||
|
src/parser/opencypher/generated
|
||||||
tags
|
tags
|
||||||
ve/
|
ve/
|
||||||
ve3/
|
ve3/
|
||||||
@@ -50,15 +52,25 @@ src/distributed/pull_produce_rpc_messages.hpp
|
|||||||
src/distributed/storage_gc_rpc_messages.hpp
|
src/distributed/storage_gc_rpc_messages.hpp
|
||||||
src/distributed/token_sharing_rpc_messages.hpp
|
src/distributed/token_sharing_rpc_messages.hpp
|
||||||
src/distributed/updates_rpc_messages.hpp
|
src/distributed/updates_rpc_messages.hpp
|
||||||
|
src/query/v2/frontend/ast/ast.hpp
|
||||||
src/query/frontend/ast/ast.hpp
|
src/query/frontend/ast/ast.hpp
|
||||||
|
src/storage/v3/bindings/ast/ast.hpp
|
||||||
src/query/distributed/frontend/ast/ast_serialization.hpp
|
src/query/distributed/frontend/ast/ast_serialization.hpp
|
||||||
|
src/query/v2/distributed/frontend/ast/ast_serialization.hpp
|
||||||
src/durability/distributed/state_delta.hpp
|
src/durability/distributed/state_delta.hpp
|
||||||
src/durability/single_node/state_delta.hpp
|
src/durability/single_node/state_delta.hpp
|
||||||
src/durability/single_node_ha/state_delta.hpp
|
src/durability/single_node_ha/state_delta.hpp
|
||||||
src/query/frontend/semantic/symbol.hpp
|
src/query/frontend/semantic/symbol.hpp
|
||||||
|
src/query/v2/frontend/semantic/symbol.hpp
|
||||||
|
src/expr/semantic/symbol.hpp
|
||||||
src/query/distributed/frontend/semantic/symbol_serialization.hpp
|
src/query/distributed/frontend/semantic/symbol_serialization.hpp
|
||||||
|
src/query/v2/distributed/frontend/semantic/symbol_serialization.hpp
|
||||||
src/query/distributed/plan/ops.hpp
|
src/query/distributed/plan/ops.hpp
|
||||||
|
src/query/v2/distributed/plan/ops.hpp
|
||||||
src/query/plan/operator.hpp
|
src/query/plan/operator.hpp
|
||||||
|
src/query/v2/plan/operator.hpp
|
||||||
|
src/parser/opencypher/generated
|
||||||
|
src/expr/semantic/symbol.hpp
|
||||||
src/raft/log_entry.hpp
|
src/raft/log_entry.hpp
|
||||||
src/raft/raft_rpc_messages.hpp
|
src/raft/raft_rpc_messages.hpp
|
||||||
src/raft/snapshot_metadata.hpp
|
src/raft/snapshot_metadata.hpp
|
||||||
|
|||||||
20
.pre-commit-config.yaml
Normal file
20
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
repos:
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: v2.3.0
|
||||||
|
hooks:
|
||||||
|
- id: check-yaml
|
||||||
|
- id: end-of-file-fixer
|
||||||
|
- id: trailing-whitespace
|
||||||
|
- repo: https://github.com/psf/black
|
||||||
|
rev: 22.10.0
|
||||||
|
hooks:
|
||||||
|
- id: black
|
||||||
|
- repo: https://github.com/pycqa/isort
|
||||||
|
rev: 5.10.1
|
||||||
|
hooks:
|
||||||
|
- id: isort
|
||||||
|
name: isort (python)
|
||||||
|
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||||
|
rev: v13.0.0
|
||||||
|
hooks:
|
||||||
|
- id: clang-format
|
||||||
416
CHANGELOG.md
416
CHANGELOG.md
@@ -1,413 +1,5 @@
|
|||||||
# Change Log
|
Change Log for all versions of Memgraph can be found on-line at
|
||||||
|
https://docs.memgraph.com/memgraph/changelog
|
||||||
|
|
||||||
## v1.2.0
|
All the updates to the Change Log can be made in the following repository:
|
||||||
|
https://github.com/memgraph/docs
|
||||||
### Breaking Changes
|
|
||||||
|
|
||||||
* SSL is disabled by default (`--bolt-cert-file` and `--bolt-key-file` are
|
|
||||||
empty). This change might only affect the client connection configuration.
|
|
||||||
|
|
||||||
### Major Features and Improvements
|
|
||||||
|
|
||||||
* Added support for Bolt v4.0 and v4.1.
|
|
||||||
* Added `mgp_networkx.py` as an alternative implementation of NetworkX graph
|
|
||||||
objects, which is useful to use Memgraph data from NetworkX algorithms
|
|
||||||
optimally.
|
|
||||||
* Added `nxalg.py` query module as a proxy to NetworkX algorithms.
|
|
||||||
* Added plan optimization to use a label-property index where the property is
|
|
||||||
not null. As a result, the query engine, instead of scanning all elements and
|
|
||||||
applying the filter, performs a label-property index lookup when possible.
|
|
||||||
|
|
||||||
### Bug Fixes and Other Changes
|
|
||||||
|
|
||||||
* Fixed Cypher `ID` function `Null` handling. When the `ID` function receives
|
|
||||||
`Null`, it will also return `Null`.
|
|
||||||
* Fixed bug that caused random crashes in SSL communication on platforms
|
|
||||||
that use older versions of OpenSSL (< 1.1) by adding proper multi-threading
|
|
||||||
handling.
|
|
||||||
* Fix `DISCARD` message handling. The query is now executed before discarding
|
|
||||||
the results.
|
|
||||||
|
|
||||||
## v1.1.0
|
|
||||||
|
|
||||||
### Major Features and Improvements
|
|
||||||
|
|
||||||
* Properties in nodes and edges are now stored encoded and compressed. This
|
|
||||||
change significantly reduces memory usage. Depending on the specific dataset,
|
|
||||||
total memory usage can be reduced up to 50%.
|
|
||||||
* Added support for rescanning query modules. Previously, the query modules
|
|
||||||
directory was scanned only upon startup. Now it is scanned each time the user
|
|
||||||
requests to load a query module. The functions used to load the query modules
|
|
||||||
were renamed to `mg.load()` and `mg.load_all()` (from `mg.reload()` and
|
|
||||||
`mg.reload_all()`).
|
|
||||||
* Improved execution performance of queries that have an IN list filter by
|
|
||||||
using label+property indices.
|
|
||||||
Example: `MATCH (n:Label) WHERE n.property IN [] ...`
|
|
||||||
* Added support for `ANY` and `NONE` openCypher functions. Previously, only
|
|
||||||
`ALL` and `SINGLE` functions were implemented.
|
|
||||||
|
|
||||||
### Bug Fixes and Other Changes
|
|
||||||
|
|
||||||
* Fixed invalid paths returned by variable expansion when the starting node and
|
|
||||||
destination node used the same symbol.
|
|
||||||
Example: `MATCH path = (n:Person {name: "John"})-[:KNOWS*]->(n) RETURN path`
|
|
||||||
* Improved semantics of `ALL` and `SINGLE` functions to be consistent with
|
|
||||||
openCypher when handling lists with `Null`s.
|
|
||||||
* `SHOW CONSTRAINT INFO` now returns property names as a list for unique
|
|
||||||
constraints.
|
|
||||||
* Escaped label/property/edgetype names in `DUMP DATABASE` to support names
|
|
||||||
with spaces in them.
|
|
||||||
* Fixed handling of `DUMP DATABASE` queries in multi-command transactions
|
|
||||||
(`BEGIN`, ..., `COMMIT`).
|
|
||||||
* Fixed handling of various query types in explicit transactions. For example,
|
|
||||||
constraints were allowed to be created in multi-command transactions
|
|
||||||
(`BEGIN`, ..., `COMMIT`) but that isn't a transactional operation and as such
|
|
||||||
can't be allowed in multi-command transactions.
|
|
||||||
* Fixed integer overflow bugs in `COUNT`, `LIMIT` and `SKIP`.
|
|
||||||
* Fixed integer overflow bugs in weighted shortest path expansions.
|
|
||||||
* Fixed various other integer overflow bugs in query execution.
|
|
||||||
* Added Marvel Comic Universe tutorial.
|
|
||||||
* Added FootballTransfers tutorial.
|
|
||||||
|
|
||||||
## v1.0.0
|
|
||||||
|
|
||||||
### Major Features and Improvements
|
|
||||||
|
|
||||||
* [Enterprise Ed.] Exposed authentication username/rolename regex as a flag
|
|
||||||
(`--auth-user-or-role-name-regex`).
|
|
||||||
* [Enterprise Ed.] Improved auth module error handling and added support for
|
|
||||||
relative paths.
|
|
||||||
* Added support for Python query modules. This release of Memgraph supports
|
|
||||||
query modules written using the already existing C API and the new Python
|
|
||||||
API.
|
|
||||||
* Added support for unique constraints. The unique constraint is created with a
|
|
||||||
label and one or more properties.
|
|
||||||
* Implemented support for importing CSV files (`mg_import_csv`). The importer
|
|
||||||
is compatible with the Neo4j batch CSV importer.
|
|
||||||
* Snapshot and write-ahead log format changed (backward compatible with v0.50).
|
|
||||||
* Vertices looked up by their openCypher ID (`MATCH (n) WHERE ID(n) = ...`)
|
|
||||||
will now find the node in O(logn) instead of O(n).
|
|
||||||
* Improved planning of BFS expansion, a faster, specific approach is now
|
|
||||||
favored instead of a ScanAll+Filter operation.
|
|
||||||
* Added syntax for limiting memory of `CALL`.
|
|
||||||
* Exposed server name that should be used for Bolt handshake as flag
|
|
||||||
(`--bolt-server-name-for-init`).
|
|
||||||
* Added several more functions to the query module C API.
|
|
||||||
* Implemented a storage locking mechanism that prevents the user from
|
|
||||||
concurrently starting two Memgraph instances with the same data directory.
|
|
||||||
|
|
||||||
### Bug Fixes and Other Changes
|
|
||||||
|
|
||||||
* [Enterprise Ed.] Fixed a bug that crashed the database when granting
|
|
||||||
privileges to a user.
|
|
||||||
* [Enterprise Ed.] Improved Louvain algorithm for community detection.
|
|
||||||
* Type of variable expansion is now printed in `EXPLAIN` (e.g. ExpandVariable,
|
|
||||||
STShortestPath, BFSExpand, WeightedShortestPath).
|
|
||||||
* Correctly display `CALL` in `EXPLAIN` output.
|
|
||||||
* Correctly delimit arguments when printing the signature of a query module.
|
|
||||||
* Fixed a planning issue when `CALL` preceded filtering.
|
|
||||||
* Fixed spelling mistakes in the storage durability module.
|
|
||||||
* Fixed storage GC indices/constraints subtle race condition.
|
|
||||||
* Reduced memory allocations in storage API and indices.
|
|
||||||
* Memgraph version is now outputted to `stdout` when Memgraph is started.
|
|
||||||
* Improved RPM packaging.
|
|
||||||
* Reduced number of errors reported in production log when loading query
|
|
||||||
modules.
|
|
||||||
* Removed `early access` wording from the Community Offering license.
|
|
||||||
|
|
||||||
## v0.50.0
|
|
||||||
|
|
||||||
### Breaking Changes
|
|
||||||
|
|
||||||
* [Enterprise Ed.] Remove support for Kafka streams.
|
|
||||||
* Snapshot and write-ahead log format changed (not backward compatible).
|
|
||||||
* Removed support for unique constraints.
|
|
||||||
* Label indices aren't created automatically, create them explicitly instead.
|
|
||||||
* Renamed several database flags. Please see the configuration file for a list of current flags.
|
|
||||||
|
|
||||||
### Major Features and Improvements
|
|
||||||
|
|
||||||
* [Enterprise Ed.] Add support for auth module.
|
|
||||||
* [Enterprise Ed.] LDAP support migrated to auth module.
|
|
||||||
* Implemented new graph storage engine.
|
|
||||||
* Add support for disabling properties on edges.
|
|
||||||
* Add support for existence constraints.
|
|
||||||
* Add support for custom openCypher procedures using a C API.
|
|
||||||
* Support loading query modules implementing read-only procedures.
|
|
||||||
* Add `CALL <procedure> YIELD <result>` syntax for invoking loaded procedures.
|
|
||||||
* Add `CREATE INDEX ON :Label` for creating label indices.
|
|
||||||
* Add `DROP INDEX ON :Label` for dropping label indices.
|
|
||||||
* Add `DUMP DATABASE` clause to openCypher.
|
|
||||||
* Add functions for treating character strings as byte strings.
|
|
||||||
|
|
||||||
### Bug Fixes and Other Changes
|
|
||||||
|
|
||||||
* Fix several memory management bugs.
|
|
||||||
* Reduce memory usage in query execution.
|
|
||||||
* Fix bug that crashes the database when `EXPLAIN` is used.
|
|
||||||
|
|
||||||
## v0.15.0
|
|
||||||
|
|
||||||
### Breaking Changes
|
|
||||||
|
|
||||||
* Snapshot and write-ahead log format changed (not backward compatible).
|
|
||||||
* `indexInfo()` function replaced with `SHOW INDEX INFO` syntax.
|
|
||||||
* Removed support for unique index. Use unique constraints instead.
|
|
||||||
* `CREATE UNIQUE INDEX ON :label (property)` replaced with `CREATE CONSTRAINT ON (n:label) ASSERT n.property IS UNIQUE`.
|
|
||||||
* Changed semantics for `COUNTER` openCypher function.
|
|
||||||
|
|
||||||
### Major Features and Improvements
|
|
||||||
|
|
||||||
* [Enterprise Ed.] Add new privilege, `STATS` for accessing storage info.
|
|
||||||
* [Enterprise Ed.] LDAP authentication and authorization support.
|
|
||||||
* [Enterprise Ed.] Add audit logging feature.
|
|
||||||
* Add multiple properties unique constraint which replace unique indices.
|
|
||||||
* Add `SHOW STORAGE INFO` feature.
|
|
||||||
* Add `PROFILE` clause to openCypher.
|
|
||||||
* Add `CREATE CONSTRAINT` clause to openCypher.
|
|
||||||
* Add `DROP CONSTRAINT` clause to openCypher.
|
|
||||||
* Add `SHOW CONSTRAINT INFO` feature.
|
|
||||||
* Add `uniformSample` function to openCypher.
|
|
||||||
* Add regex matching to openCypher.
|
|
||||||
|
|
||||||
### Bug Fixes and Other Changes
|
|
||||||
|
|
||||||
* Fix bug in explicit transaction handling.
|
|
||||||
* Fix bug in edge filtering by edge type and destination.
|
|
||||||
* Fix bug in query comment parsing.
|
|
||||||
* Fix bug in query symbol table.
|
|
||||||
* Fix OpenSSL memory leaks.
|
|
||||||
* Make authentication case insensitive.
|
|
||||||
* Remove `COALESCE` function.
|
|
||||||
* Add movie tutorial.
|
|
||||||
* Add backpacking tutorial.
|
|
||||||
|
|
||||||
## v0.14.0
|
|
||||||
|
|
||||||
### Breaking Changes
|
|
||||||
|
|
||||||
* Write-ahead log format changed (not backward compatible).
|
|
||||||
|
|
||||||
### Major Features and Improvements
|
|
||||||
|
|
||||||
* [Enterprise Ed.] Reduce memory usage in distributed usage.
|
|
||||||
* Add `DROP INDEX` feature.
|
|
||||||
* Improve SSL error messages.
|
|
||||||
|
|
||||||
### Bug Fixes and Other Changes
|
|
||||||
|
|
||||||
* [Enterprise Ed.] Fix issues with reading and writing in a distributed query.
|
|
||||||
* Correctly handle an edge case with unique constraint checks.
|
|
||||||
* Fix a minor issue with `mg_import_csv`.
|
|
||||||
* Fix an issue with `EXPLAIN`.
|
|
||||||
|
|
||||||
## v0.13.0
|
|
||||||
|
|
||||||
### Breaking Changes
|
|
||||||
|
|
||||||
* Write-ahead log format changed (not backward compatible).
|
|
||||||
* Snapshot format changed (not backward compatible).
|
|
||||||
|
|
||||||
### Major Features and Improvements
|
|
||||||
|
|
||||||
* [Enterprise Ed.] Authentication and authorization support.
|
|
||||||
* [Enterprise Ed.] Kafka integration.
|
|
||||||
* [Enterprise Ed.] Support dynamic worker addition in distributed.
|
|
||||||
* Reduce memory usage and improve overall performance.
|
|
||||||
* Add `CREATE UNIQUE INDEX` clause to openCypher.
|
|
||||||
* Add `EXPLAIN` clause to openCypher.
|
|
||||||
* Add `inDegree` and `outDegree` functions to openCypher.
|
|
||||||
* Improve BFS performance when both endpoints are known.
|
|
||||||
* Add new `node-label`, `relationship-type` and `quote` options to
|
|
||||||
`mg_import_csv` tool.
|
|
||||||
* Reduce memory usage of `mg_import_csv`.
|
|
||||||
|
|
||||||
### Bug Fixes and Other Changes
|
|
||||||
|
|
||||||
* [Enterprise Ed.] Fix an edge case in distributed index creation.
|
|
||||||
* [Enterprise Ed.] Fix issues with Cartesian in distributed queries.
|
|
||||||
* Correctly handle large messages in Bolt protocol.
|
|
||||||
* Fix issues when handling explicitly started transactions in queries.
|
|
||||||
* Allow openCypher keywords to be used as variable names.
|
|
||||||
* Revise and make user visible error messages consistent.
|
|
||||||
* Improve aborting time consuming execution.
|
|
||||||
|
|
||||||
## v0.12.0
|
|
||||||
|
|
||||||
### Breaking Changes
|
|
||||||
|
|
||||||
* Snapshot format changed (not backward compatible).
|
|
||||||
|
|
||||||
### Major Features and Improvements
|
|
||||||
|
|
||||||
* Improved Id Cypher function.
|
|
||||||
* Added string functions to openCypher (`lTrim`, `left`, `rTrim`, `replace`,
|
|
||||||
`reverse`, `right`, `split`, `substring`, `toLower`, `toUpper`, `trim`).
|
|
||||||
* Added `timestamp` function to openCypher.
|
|
||||||
* Added support for dynamic property access with `[]` operator.
|
|
||||||
|
|
||||||
## v0.11.0
|
|
||||||
|
|
||||||
### Major Features and Improvements
|
|
||||||
|
|
||||||
* [Enterprise Ed.] Improve Cartesian support in distributed queries.
|
|
||||||
* [Enterprise Ed.] Improve distributed execution of BFS.
|
|
||||||
* [Enterprise Ed.] Dynamic graph partitioner added.
|
|
||||||
* Static nodes/edges id generators exposed through the Id Cypher function.
|
|
||||||
* Properties on disk added.
|
|
||||||
* Telemetry added.
|
|
||||||
* SSL support added.
|
|
||||||
* `toString` function added.
|
|
||||||
|
|
||||||
### Bug Fixes and Other Changes
|
|
||||||
|
|
||||||
* Document issues with Docker on OS X.
|
|
||||||
* Add BFS and Dijkstra's algorithm examples to documentation.
|
|
||||||
|
|
||||||
## v0.10.0
|
|
||||||
|
|
||||||
### Breaking Changes
|
|
||||||
|
|
||||||
* Snapshot format changed (not backward compatible).
|
|
||||||
|
|
||||||
### Major Features and Improvements
|
|
||||||
|
|
||||||
* [Enterprise Ed.] Distributed storage and execution.
|
|
||||||
* `reduce` and `single` functions added to openCypher.
|
|
||||||
* `wShortest` edge expansion added to openCypher.
|
|
||||||
* Support packaging RPM on CentOS 7.
|
|
||||||
|
|
||||||
### Bug Fixes and Other Changes
|
|
||||||
|
|
||||||
* Report an error if updating a deleted element.
|
|
||||||
* Log an error if reading info on available memory fails.
|
|
||||||
* Fix a bug when `MATCH` would stop matching if a result was empty, but later
|
|
||||||
results still contain data to be matched. The simplest case of this was the
|
|
||||||
query: `UNWIND [1,2,3] AS x MATCH (n :Label {prop: x}) RETURN n`. If there
|
|
||||||
was no node `(:Label {prop: 1})`, then the `MATCH` wouldn't even try to find
|
|
||||||
for `x` being 2 or 3.
|
|
||||||
* Report an error if trying to compare a property value with something that
|
|
||||||
cannot be stored in a property.
|
|
||||||
* Fix crashes in some obscure cases.
|
|
||||||
* Commit log automatically garbage collected.
|
|
||||||
* Add minor performance improvements.
|
|
||||||
|
|
||||||
## v0.9.0
|
|
||||||
|
|
||||||
### Breaking Changes
|
|
||||||
|
|
||||||
* Snapshot format changed (not backward compatible).
|
|
||||||
* Snapshot configuration flags changed, general durability flags added.
|
|
||||||
|
|
||||||
### Major Features and Improvements
|
|
||||||
|
|
||||||
* Write-ahead log added.
|
|
||||||
* `nodes` and `relationships` functions added.
|
|
||||||
* `UNION` and `UNION ALL` is implemented.
|
|
||||||
* Concurrent index creation is now enabled.
|
|
||||||
|
|
||||||
### Bug Fixes and Other Changes
|
|
||||||
|
|
||||||
|
|
||||||
## v0.8.0
|
|
||||||
|
|
||||||
### Major Features and Improvements
|
|
||||||
|
|
||||||
* CASE construct (without aggregations).
|
|
||||||
* Named path support added.
|
|
||||||
* Maps can now be stored as node/edge properties.
|
|
||||||
* Map indexing supported.
|
|
||||||
* `rand` function added.
|
|
||||||
* `assert` function added.
|
|
||||||
* `counter` and `counterSet` functions added.
|
|
||||||
* `indexInfo` function added.
|
|
||||||
* `collect` aggregation now supports Map collection.
|
|
||||||
* Changed the BFS syntax.
|
|
||||||
|
|
||||||
### Bug Fixes and Other Changes
|
|
||||||
|
|
||||||
* Use \u to specify 4 digit codepoint and \U for 8 digit
|
|
||||||
* Keywords appearing in header (named expressions) keep original case.
|
|
||||||
* Our Bolt protocol implementation is now completely compatible with the protocol version 1 specification. (https://boltprotocol.org/v1/)
|
|
||||||
* Added a log warning when running out of memory and the `memory_warning_threshold` flag
|
|
||||||
* Edges are no longer additionally filtered after expansion.
|
|
||||||
|
|
||||||
## v0.7.0
|
|
||||||
|
|
||||||
### Major Features and Improvements
|
|
||||||
|
|
||||||
* Variable length path `MATCH`.
|
|
||||||
* Explicitly started transactions (multi-query transactions).
|
|
||||||
* Map literal.
|
|
||||||
* Query parameters (except for parameters in place of property maps).
|
|
||||||
* `all` function in openCypher.
|
|
||||||
* `degree` function in openCypher.
|
|
||||||
* User specified transaction execution timeout.
|
|
||||||
|
|
||||||
### Bug Fixes and Other Changes
|
|
||||||
|
|
||||||
* Concurrent `BUILD INDEX` deadlock now returns an error to the client.
|
|
||||||
* A `MATCH` preceeded by `OPTIONAL MATCH` expansion inconsistencies.
|
|
||||||
* High concurrency Antlr parsing bug.
|
|
||||||
* Indexing improvements.
|
|
||||||
* Query stripping and caching speedups.
|
|
||||||
|
|
||||||
## v0.6.0
|
|
||||||
|
|
||||||
### Major Features and Improvements
|
|
||||||
|
|
||||||
* AST caching.
|
|
||||||
* Label + property index support.
|
|
||||||
* Different logging setup & format.
|
|
||||||
|
|
||||||
## v0.5.0
|
|
||||||
|
|
||||||
### Major Features and Improvements
|
|
||||||
|
|
||||||
* Use label indexes to speed up querying.
|
|
||||||
* Generate multiple query plans and use the cost estimator to select the best.
|
|
||||||
* Snapshots & Recovery.
|
|
||||||
* Abandon old yaml configuration and migrate to gflags.
|
|
||||||
* Query stripping & AST caching support.
|
|
||||||
|
|
||||||
### Bug Fixes and Other Changes
|
|
||||||
|
|
||||||
* Fixed race condition in MVCC. Hints exp+aborted race condition prevented.
|
|
||||||
* Fixed conceptual bug in MVCC GC. Evaluate old records w.r.t. the oldest.
|
|
||||||
transaction's id AND snapshot.
|
|
||||||
* User friendly error messages thrown from the query engine.
|
|
||||||
|
|
||||||
## Build 837
|
|
||||||
|
|
||||||
### Bug Fixes and Other Changes
|
|
||||||
|
|
||||||
* List indexing supported with preceeding IN (for example in query `RETURN 1 IN [[1,2]][0]`).
|
|
||||||
|
|
||||||
## Build 825
|
|
||||||
|
|
||||||
### Major Features and Improvements
|
|
||||||
|
|
||||||
* RETURN *, count(*), OPTIONAL MATCH, UNWIND, DISTINCT (except DISTINCT in aggregate functions), list indexing and slicing, escaped labels, IN LIST operator, range function.
|
|
||||||
|
|
||||||
### Bug Fixes and Other Changes
|
|
||||||
|
|
||||||
* TCP_NODELAY -> import should be faster.
|
|
||||||
* Clear hint bits.
|
|
||||||
|
|
||||||
## Build 783
|
|
||||||
|
|
||||||
### Major Features and Improvements
|
|
||||||
|
|
||||||
* SKIP, LIMIT, ORDER BY.
|
|
||||||
* Math functions.
|
|
||||||
* Initial support for MERGE clause.
|
|
||||||
|
|
||||||
### Bug Fixes and Other Changes
|
|
||||||
|
|
||||||
* Unhandled Lock Timeout Exception.
|
|
||||||
|
|
||||||
## Build 755
|
|
||||||
|
|
||||||
### Major Features and Improvements
|
|
||||||
|
|
||||||
* MATCH, CREATE, WHERE, SET, REMOVE, DELETE.
|
|
||||||
|
|||||||
206
CMakeLists.txt
206
CMakeLists.txt
@@ -4,7 +4,6 @@ cmake_minimum_required(VERSION 3.8)
|
|||||||
|
|
||||||
# !! IMPORTANT !! run ./project_root/init.sh before cmake command
|
# !! IMPORTANT !! run ./project_root/init.sh before cmake command
|
||||||
# to download dependencies
|
# to download dependencies
|
||||||
|
|
||||||
if(NOT UNIX)
|
if(NOT UNIX)
|
||||||
message(FATAL_ERROR "Unsupported operating system.")
|
message(FATAL_ERROR "Unsupported operating system.")
|
||||||
endif()
|
endif()
|
||||||
@@ -19,6 +18,7 @@ set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM TRUE)
|
|||||||
find_program(CCACHE_FOUND ccache)
|
find_program(CCACHE_FOUND ccache)
|
||||||
option(USE_CCACHE "ccache:" ON)
|
option(USE_CCACHE "ccache:" ON)
|
||||||
message(STATUS "CCache: ${USE_CCACHE}")
|
message(STATUS "CCache: ${USE_CCACHE}")
|
||||||
|
|
||||||
if(CCACHE_FOUND AND USE_CCACHE)
|
if(CCACHE_FOUND AND USE_CCACHE)
|
||||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
|
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
|
||||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
|
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
|
||||||
@@ -28,7 +28,8 @@ endif(CCACHE_FOUND AND USE_CCACHE)
|
|||||||
# NOTE: must be choosen before use of project() or enable_language()
|
# NOTE: must be choosen before use of project() or enable_language()
|
||||||
find_program(CLANG_FOUND clang)
|
find_program(CLANG_FOUND clang)
|
||||||
find_program(CLANGXX_FOUND clang++)
|
find_program(CLANGXX_FOUND clang++)
|
||||||
if (CLANG_FOUND AND CLANGXX_FOUND)
|
|
||||||
|
if(CLANG_FOUND AND CLANGXX_FOUND)
|
||||||
set(CMAKE_C_COMPILER ${CLANG_FOUND})
|
set(CMAKE_C_COMPILER ${CLANG_FOUND})
|
||||||
set(CMAKE_CXX_COMPILER ${CLANGXX_FOUND})
|
set(CMAKE_CXX_COMPILER ${CLANGXX_FOUND})
|
||||||
else()
|
else()
|
||||||
@@ -36,9 +37,12 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
project(memgraph)
|
project(memgraph)
|
||||||
|
|
||||||
|
# Install licenses.
|
||||||
|
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/licenses/
|
||||||
|
DESTINATION share/doc/memgraph)
|
||||||
|
|
||||||
# For more information about how to release a new version of Memgraph, see
|
# For more information about how to release a new version of Memgraph, see
|
||||||
# `release/README.md`.
|
# `release/README.md`.
|
||||||
|
|
||||||
@@ -57,39 +61,67 @@ set(MEMGRAPH_OVERRIDE_VERSION "")
|
|||||||
set(MEMGRAPH_OVERRIDE_VERSION_SUFFIX "")
|
set(MEMGRAPH_OVERRIDE_VERSION_SUFFIX "")
|
||||||
|
|
||||||
# Variables used to generate the versions.
|
# Variables used to generate the versions.
|
||||||
if (MG_ENTERPRISE)
|
if(MG_ENTERPRISE)
|
||||||
set(get_version_enterprise "--enterprise")
|
set(get_version_offering "")
|
||||||
else()
|
else()
|
||||||
set(get_version_enterprise "")
|
set(get_version_offering "--open-source")
|
||||||
endif()
|
endif()
|
||||||
set(get_version_script "${CMAKE_SOURCE_DIR}/release/get_version.py")
|
|
||||||
|
set(get_version_script "${CMAKE_CURRENT_SOURCE_DIR}/release/get_version.py")
|
||||||
|
|
||||||
# Get version that should be used in the binary.
|
# Get version that should be used in the binary.
|
||||||
execute_process(
|
execute_process(
|
||||||
OUTPUT_VARIABLE MEMGRAPH_VERSION
|
OUTPUT_VARIABLE MEMGRAPH_VERSION
|
||||||
COMMAND "${get_version_script}" ${get_version_enterprise}
|
RESULT_VARIABLE MEMGRAPH_VERSION_RESULT
|
||||||
"${MEMGRAPH_OVERRIDE_VERSION}"
|
COMMAND "${get_version_script}" ${get_version_offering}
|
||||||
"${MEMGRAPH_OVERRIDE_VERSION_SUFFIX}"
|
"${MEMGRAPH_OVERRIDE_VERSION}"
|
||||||
|
"${MEMGRAPH_OVERRIDE_VERSION_SUFFIX}"
|
||||||
|
"--memgraph-root-dir"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(MEMGRAPH_VERSION_RESULT AND NOT MEMGRAPH_VERSION_RESULT EQUAL 0)
|
||||||
|
message(FATAL_ERROR "Unable to get Memgraph version.")
|
||||||
|
else()
|
||||||
|
MESSAGE(STATUS "Memgraph version: ${MEMGRAPH_VERSION}")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Get version that should be used in the DEB package.
|
# Get version that should be used in the DEB package.
|
||||||
execute_process(
|
execute_process(
|
||||||
OUTPUT_VARIABLE MEMGRAPH_VERSION_DEB
|
OUTPUT_VARIABLE MEMGRAPH_VERSION_DEB
|
||||||
COMMAND "${get_version_script}" ${get_version_enterprise}
|
RESULT_VARIABLE MEMGRAPH_VERSION_DEB_RESULT
|
||||||
--variant deb
|
COMMAND "${get_version_script}" ${get_version_offering}
|
||||||
"${MEMGRAPH_OVERRIDE_VERSION}"
|
--variant deb
|
||||||
"${MEMGRAPH_OVERRIDE_VERSION_SUFFIX}"
|
"${MEMGRAPH_OVERRIDE_VERSION}"
|
||||||
|
"${MEMGRAPH_OVERRIDE_VERSION_SUFFIX}"
|
||||||
|
"--memgraph-root-dir"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(MEMGRAPH_VERSION_DEB_RESULT AND NOT MEMGRAPH_VERSION_DEB_RESULT EQUAL 0)
|
||||||
|
message(FATAL_ERROR "Unable to get Memgraph DEB version.")
|
||||||
|
else()
|
||||||
|
MESSAGE(STATUS "Memgraph DEB version: ${MEMGRAPH_VERSION_DEB}")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Get version that should be used in the RPM package.
|
# Get version that should be used in the RPM package.
|
||||||
execute_process(
|
execute_process(
|
||||||
OUTPUT_VARIABLE MEMGRAPH_VERSION_RPM
|
OUTPUT_VARIABLE MEMGRAPH_VERSION_RPM
|
||||||
COMMAND "${get_version_script}" ${get_version_enterprise}
|
RESULT_VARIABLE MEMGRAPH_VERSION_RPM_RESULT
|
||||||
--variant rpm
|
COMMAND "${get_version_script}" ${get_version_offering}
|
||||||
"${MEMGRAPH_OVERRIDE_VERSION}"
|
--variant rpm
|
||||||
"${MEMGRAPH_OVERRIDE_VERSION_SUFFIX}"
|
"${MEMGRAPH_OVERRIDE_VERSION}"
|
||||||
|
"${MEMGRAPH_OVERRIDE_VERSION_SUFFIX}"
|
||||||
|
"--memgraph-root-dir"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(MEMGRAPH_VERSION_RPM_RESULT AND NOT MEMGRAPH_VERSION_RPM_RESULT EQUAL 0)
|
||||||
|
message(FATAL_ERROR "Unable to get Memgraph RPM version.")
|
||||||
|
else()
|
||||||
|
MESSAGE(STATUS "Memgraph RPM version: ${MEMGRAPH_VERSION_RPM}")
|
||||||
|
endif()
|
||||||
|
|
||||||
# We want the above variables to be updated each time something is committed to
|
# We want the above variables to be updated each time something is committed to
|
||||||
# the repository. That is why we include a dependency on the current git HEAD
|
# the repository. That is why we include a dependency on the current git HEAD
|
||||||
# to trigger a new CMake run when the git repository state changes. This is a
|
# to trigger a new CMake run when the git repository state changes. This is a
|
||||||
@@ -107,22 +139,24 @@ execute_process(
|
|||||||
# unnecessary recalculations of the release version. The release version only
|
# unnecessary recalculations of the release version. The release version only
|
||||||
# changes on every `git commit` or `git checkout`. That is why we watch the
|
# changes on every `git commit` or `git checkout`. That is why we watch the
|
||||||
# following files for changes:
|
# following files for changes:
|
||||||
# - `.git/HEAD` -> changes each time a `git checkout` is issued
|
# - `.git/HEAD` -> changes each time a `git checkout` is issued
|
||||||
# - `.git/refs/heads/...` -> the value in `.git/HEAD` is a branch name (when
|
# - `.git/refs/heads/...` -> the value in `.git/HEAD` is a branch name (when
|
||||||
# you are on a branch) and you have to monitor the file of the specific
|
# you are on a branch) and you have to monitor the file of the specific
|
||||||
# branch to detect when a `git commit` was issued
|
# branch to detect when a `git commit` was issued
|
||||||
# More details about the contents of the `.git` directory and the specific
|
# More details about the contents of the `.git` directory and the specific
|
||||||
# files used can be seen here:
|
# files used can be seen here:
|
||||||
# https://git-scm.com/book/en/v2/Git-Internals-Git-References
|
# https://git-scm.com/book/en/v2/Git-Internals-Git-References
|
||||||
set(git_directory "${CMAKE_SOURCE_DIR}/.git")
|
set(git_directory "${CMAKE_SOURCE_DIR}/.git")
|
||||||
if (EXISTS "${git_directory}")
|
|
||||||
|
if(EXISTS "${git_directory}")
|
||||||
set_property(DIRECTORY APPEND PROPERTY
|
set_property(DIRECTORY APPEND PROPERTY
|
||||||
CMAKE_CONFIGURE_DEPENDS "${git_directory}/HEAD")
|
CMAKE_CONFIGURE_DEPENDS "${git_directory}/HEAD")
|
||||||
file(STRINGS "${git_directory}/HEAD" git_head_data)
|
file(STRINGS "${git_directory}/HEAD" git_head_data)
|
||||||
if (git_head_data MATCHES "^ref: ")
|
|
||||||
|
if(git_head_data MATCHES "^ref: ")
|
||||||
string(SUBSTRING "${git_head_data}" 5 -1 git_head_ref)
|
string(SUBSTRING "${git_head_data}" 5 -1 git_head_ref)
|
||||||
set_property(DIRECTORY APPEND PROPERTY
|
set_property(DIRECTORY APPEND PROPERTY
|
||||||
CMAKE_CONFIGURE_DEPENDS "${git_directory}/${git_head_ref}")
|
CMAKE_CONFIGURE_DEPENDS "${git_directory}/${git_head_ref}")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -131,16 +165,19 @@ endif()
|
|||||||
# setup CMake module path, defines path for include() and find_package()
|
# setup CMake module path, defines path for include() and find_package()
|
||||||
# https://cmake.org/cmake/help/latest/variable/CMAKE_MODULE_PATH.html
|
# https://cmake.org/cmake/help/latest/variable/CMAKE_MODULE_PATH.html
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake)
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake)
|
||||||
|
|
||||||
# custom function definitions
|
# custom function definitions
|
||||||
include(functions)
|
include(functions)
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
# We want out of source builds, so that cmake generated files don't get mixed
|
# We want out of source builds, so that cmake generated files don't get mixed
|
||||||
# with source files. This allows for easier clean up.
|
# with source files. This allows for easier clean up.
|
||||||
disallow_in_source_build()
|
disallow_in_source_build()
|
||||||
add_custom_target(clean_all
|
add_custom_target(clean_all
|
||||||
COMMAND ${CMAKE_COMMAND} -P ${PROJECT_SOURCE_DIR}/cmake/clean_all.cmake
|
COMMAND ${CMAKE_COMMAND} -P ${PROJECT_SOURCE_DIR}/cmake/clean_all.cmake
|
||||||
COMMENT "Removing all files in ${CMAKE_BINARY_DIR}")
|
COMMENT "Removing all files in ${CMAKE_BINARY_DIR}")
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
# build flags -----------------------------------------------------------------
|
# build flags -----------------------------------------------------------------
|
||||||
@@ -151,16 +188,19 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
# c99-designator is disabled because of required mixture of designated and
|
# c99-designator is disabled because of required mixture of designated and
|
||||||
# non-designated initializers in Python Query Module code (`py_module.cpp`).
|
# non-designated initializers in Python Query Module code (`py_module.cpp`).
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall \
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall \
|
||||||
-Werror=switch -Werror=switch-bool -Werror=return-type \
|
-Werror=switch -Werror=switch-bool -Werror=return-type \
|
||||||
-Werror=return-stack-address \
|
-Werror=return-stack-address \
|
||||||
-Wno-c99-designator")
|
-Wno-c99-designator \
|
||||||
|
-DBOOST_STACKTRACE_USE_ADDR2LINE \
|
||||||
|
-DBOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT")
|
||||||
|
|
||||||
# Don't omit frame pointer in RelWithDebInfo, for additional callchain debug.
|
# Don't omit frame pointer in RelWithDebInfo, for additional callchain debug.
|
||||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||||
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fno-omit-frame-pointer")
|
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fno-omit-frame-pointer")
|
||||||
|
|
||||||
# Statically link libgcc and libstdc++, the GCC allows this according to:
|
# Statically link libgcc and libstdc++, the GCC allows this according to:
|
||||||
# https://gcc.gnu.org/onlinedocs/gcc-10.2.0/libstdc++/manual/manual/license.html
|
# https://gcc.gnu.org/onlinedocs/gcc-10.2.0/libstdc++/manual/manual/license.html
|
||||||
@@ -176,40 +216,49 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
|
|||||||
# release flags
|
# release flags
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
|
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
|
||||||
|
|
||||||
#debug flags
|
SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -pthread")
|
||||||
|
|
||||||
|
# debug flags
|
||||||
set(PREFERRED_DEBUGGER "gdb" CACHE STRING
|
set(PREFERRED_DEBUGGER "gdb" CACHE STRING
|
||||||
"Tunes the debug output for your preferred debugger (gdb or lldb).")
|
"Tunes the debug output for your preferred debugger (gdb or lldb).")
|
||||||
if ("${PREFERRED_DEBUGGER}" STREQUAL "gdb" AND
|
|
||||||
"${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang|GNU")
|
if("${PREFERRED_DEBUGGER}" STREQUAL "gdb" AND
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb")
|
"${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang|GNU")
|
||||||
elseif ("${PREFERRED_DEBUGGER}" STREQUAL "lldb" AND
|
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb")
|
||||||
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
elseif("${PREFERRED_DEBUGGER}" STREQUAL "lldb" AND
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-glldb")
|
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||||
|
set(CMAKE_CXX_FLAGS_DEBUG "-glldb")
|
||||||
else()
|
else()
|
||||||
message(WARNING "Unable to tune for PREFERRED_DEBUGGER: "
|
message(WARNING "Unable to tune for PREFERRED_DEBUGGER: "
|
||||||
"'${PREFERRED_DEBUGGER}' with compiler: '${CMAKE_CXX_COMPILER_ID}'")
|
"'${PREFERRED_DEBUGGER}' with compiler: '${CMAKE_CXX_COMPILER_ID}'")
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-g")
|
set(CMAKE_CXX_FLAGS_DEBUG "-g")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
# default build type is debug
|
# default build type is debug
|
||||||
if (NOT CMAKE_BUILD_TYPE)
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
set(CMAKE_BUILD_TYPE "Debug")
|
set(CMAKE_BUILD_TYPE "Debug")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
message(STATUS "CMake build type: ${CMAKE_BUILD_TYPE}")
|
message(STATUS "CMake build type: ${CMAKE_BUILD_TYPE}")
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
set(MG_ARCH "x86_64" CACHE STRING "Host architecture to build Memgraph on. Supported values are x86_64 (default), ARM64.")
|
||||||
|
|
||||||
# setup external dependencies -------------------------------------------------
|
# setup external dependencies -------------------------------------------------
|
||||||
|
|
||||||
# threading
|
# threading
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
# optional readline
|
# optional readline
|
||||||
option(USE_READLINE "Use GNU Readline library if available (default ON). \
|
option(USE_READLINE "Use GNU Readline library if available (default ON). \
|
||||||
Set this to OFF to prevent linking with Readline even if it is available." ON)
|
Set this to OFF to prevent linking with Readline even if it is available." ON)
|
||||||
if (USE_READLINE)
|
|
||||||
|
if(USE_READLINE)
|
||||||
find_package(Readline)
|
find_package(Readline)
|
||||||
if (READLINE_FOUND)
|
|
||||||
|
if(READLINE_FOUND)
|
||||||
add_definitions(-DHAS_READLINE)
|
add_definitions(-DHAS_READLINE)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
@@ -225,20 +274,27 @@ option(ASAN "Build with Address Sanitizer. To get a reasonable performance optio
|
|||||||
option(TSAN "Build with Thread Sanitizer. To get a reasonable performance option should be used only in Release or RelWithDebInfo build " OFF)
|
option(TSAN "Build with Thread Sanitizer. To get a reasonable performance option should be used only in Release or RelWithDebInfo build " OFF)
|
||||||
option(UBSAN "Build with Undefined Behaviour Sanitizer" OFF)
|
option(UBSAN "Build with Undefined Behaviour Sanitizer" OFF)
|
||||||
|
|
||||||
if (TEST_COVERAGE)
|
if(TEST_COVERAGE)
|
||||||
string(TOLOWER ${CMAKE_BUILD_TYPE} lower_build_type)
|
string(TOLOWER ${CMAKE_BUILD_TYPE} lower_build_type)
|
||||||
if (NOT lower_build_type STREQUAL "debug")
|
|
||||||
|
if(NOT lower_build_type STREQUAL "debug")
|
||||||
message(FATAL_ERROR "Generating test coverage unsupported in non Debug builds. Current build type is '${CMAKE_BUILD_TYPE}'")
|
message(FATAL_ERROR "Generating test coverage unsupported in non Debug builds. Current build type is '${CMAKE_BUILD_TYPE}'")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping")
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-instr-generate -fcoverage-mapping")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-instr-generate -fcoverage-mapping")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MG_ENTERPRISE)
|
if(MG_ENTERPRISE)
|
||||||
add_definitions(-DMG_ENTERPRISE)
|
add_definitions(-DMG_ENTERPRISE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ASAN)
|
set(ENABLE_JEMALLOC ON)
|
||||||
|
|
||||||
|
if(ASAN)
|
||||||
|
message(WARNING "Disabling jemalloc as it doesn't work well with ASAN")
|
||||||
|
set(ENABLE_JEMALLOC OFF)
|
||||||
|
|
||||||
# Enable Addres sanitizer and get nicer stack traces in error messages.
|
# Enable Addres sanitizer and get nicer stack traces in error messages.
|
||||||
# NOTE: AddressSanitizer uses llvm-symbolizer binary from the Clang
|
# NOTE: AddressSanitizer uses llvm-symbolizer binary from the Clang
|
||||||
# distribution to symbolize the stack traces (note that ideally the
|
# distribution to symbolize the stack traces (note that ideally the
|
||||||
@@ -247,19 +303,20 @@ if (ASAN)
|
|||||||
# provide it in separate ASAN_SYMBOLIZER_PATH environment variable.
|
# provide it in separate ASAN_SYMBOLIZER_PATH environment variable.
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
|
||||||
|
|
||||||
# To detect Stack-use-after-return bugs set run-time flag:
|
# To detect Stack-use-after-return bugs set run-time flag:
|
||||||
# ASAN_OPTIONS=detect_stack_use_after_return=1
|
# ASAN_OPTIONS=detect_stack_use_after_return=1
|
||||||
# To check initialization order bugs set run-time flag:
|
# To check initialization order bugs set run-time flag:
|
||||||
# ASAN_OPTIONS=check_initialization_order=true
|
# ASAN_OPTIONS=check_initialization_order=true
|
||||||
# This mode reports an error if initializer for a global variable accesses
|
# This mode reports an error if initializer for a global variable accesses
|
||||||
# dynamically initialized global from another translation unit, which is
|
# dynamically initialized global from another translation unit, which is
|
||||||
# not yet initialized
|
# not yet initialized
|
||||||
# ASAN_OPTIONS=strict_init_order=true
|
# ASAN_OPTIONS=strict_init_order=true
|
||||||
# This mode reports an error if initializer for a global variable accesses
|
# This mode reports an error if initializer for a global variable accesses
|
||||||
# any dynamically initialized global from another translation unit.
|
# any dynamically initialized global from another translation unit.
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (TSAN)
|
if(TSAN)
|
||||||
# ThreadSanitizer generally requires all code to be compiled with -fsanitize=thread.
|
# ThreadSanitizer generally requires all code to be compiled with -fsanitize=thread.
|
||||||
# If some code (e.g. dynamic libraries) is not compiled with the flag, it can
|
# If some code (e.g. dynamic libraries) is not compiled with the flag, it can
|
||||||
# lead to false positive race reports, false negative race reports and/or
|
# lead to false positive race reports, false negative race reports and/or
|
||||||
@@ -272,23 +329,29 @@ if (TSAN)
|
|||||||
# (unwinding stack on each memory access is too expensive).
|
# (unwinding stack on each memory access is too expensive).
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread")
|
||||||
|
|
||||||
# By default ThreadSanitizer uses addr2line utility to symbolize reports.
|
# By default ThreadSanitizer uses addr2line utility to symbolize reports.
|
||||||
# llvm-symbolizer is faster, consumes less memory and produces much better
|
# llvm-symbolizer is faster, consumes less memory and produces much better
|
||||||
# reports. To use it set runtime flag:
|
# reports. To use it set runtime flag:
|
||||||
# TSAN_OPTIONS="extern-symbolizer-path=~/llvm-symbolizer"
|
# TSAN_OPTIONS="extern-symbolizer-path=~/llvm-symbolizer"
|
||||||
# For more runtime flags see: https://github.com/google/sanitizers/wiki/ThreadSanitizerFlags
|
# For more runtime flags see: https://github.com/google/sanitizers/wiki/ThreadSanitizerFlags
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (UBSAN)
|
if(UBSAN)
|
||||||
# Compile with UBSAN but disable vptr check. This is disabled because it
|
# Compile with UBSAN but disable vptr check. This is disabled because it
|
||||||
# requires linking with clang++ to make sure C++ specific parts of the
|
# requires linking with clang++ to make sure C++ specific parts of the
|
||||||
# runtime library and c++ standard libraries are present.
|
# runtime library and c++ standard libraries are present.
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-omit-frame-pointer -fno-sanitize=vptr")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-omit-frame-pointer -fno-sanitize=vptr")
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fno-sanitize=vptr")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined -fno-sanitize=vptr")
|
||||||
# Run program with environment variable UBSAN_OPTIONS=print_stacktrace=1
|
|
||||||
# Make sure llvm-symbolizer binary is in path
|
# Run program with environment variable UBSAN_OPTIONS=print_stacktrace=1.
|
||||||
|
# Make sure llvm-symbolizer binary is in path.
|
||||||
|
# To make the program abort on undefined behavior, use UBSAN_OPTIONS=halt_on_error=1.
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(MG_PYTHON_VERSION "" CACHE STRING "Specify the exact Python version used by the query modules")
|
||||||
|
set(MG_PYTHON_PATH "" CACHE STRING "Specify the exact Python path used by the query modules")
|
||||||
|
|
||||||
# Add subprojects
|
# Add subprojects
|
||||||
include_directories(src)
|
include_directories(src)
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
@@ -296,8 +359,13 @@ add_subdirectory(src)
|
|||||||
# Release configuration
|
# Release configuration
|
||||||
add_subdirectory(release)
|
add_subdirectory(release)
|
||||||
|
|
||||||
enable_testing()
|
option(MG_ENABLE_TESTING "Set this to OFF to disable building test binaries" ON)
|
||||||
add_subdirectory(tests)
|
message(STATUS "MG_ENABLE_TESTING: ${MG_ENABLE_TESTING}")
|
||||||
|
|
||||||
|
if(MG_ENABLE_TESTING)
|
||||||
|
enable_testing()
|
||||||
|
add_subdirectory(tests)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(TOOLS)
|
if(TOOLS)
|
||||||
add_subdirectory(tools)
|
add_subdirectory(tools)
|
||||||
@@ -306,3 +374,7 @@ endif()
|
|||||||
if(QUERY_MODULES)
|
if(QUERY_MODULES)
|
||||||
add_subdirectory(query_modules)
|
add_subdirectory(query_modules)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
install(FILES ${CMAKE_BINARY_DIR}/bin/mgconsole
|
||||||
|
PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
|
||||||
|
TYPE BIN)
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
/docs/ @gitbuda
|
|
||||||
/src/communication/ @antonio2368
|
|
||||||
/src/query/ @the-joksim
|
|
||||||
/src/storage/ @antonio2368
|
|
||||||
127
CODE_OF_CONDUCT.md
Normal file
127
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
We as members, contributors, and leaders pledge to make participation in our
|
||||||
|
community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||||
|
identity and expression, level of experience, education, socio-economic status,
|
||||||
|
nationality, personal appearance, race, caste, color, religion, or sexual
|
||||||
|
identity and orientation.
|
||||||
|
|
||||||
|
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||||
|
diverse, inclusive, and healthy community.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to a positive environment for our
|
||||||
|
community include:
|
||||||
|
|
||||||
|
- Demonstrating empathy and kindness toward other people
|
||||||
|
- Being respectful of differing opinions, viewpoints, and experiences
|
||||||
|
- Giving and gracefully accepting constructive feedback
|
||||||
|
- Accepting responsibility and apologizing to those affected by our mistakes,
|
||||||
|
and learning from the experience
|
||||||
|
- Focusing on what is best not just for us as individuals, but for the overall
|
||||||
|
community
|
||||||
|
|
||||||
|
Examples of unacceptable behavior include:
|
||||||
|
|
||||||
|
- The use of sexualized language or imagery, and sexual attention or advances of
|
||||||
|
any kind
|
||||||
|
- Trolling, insulting or derogatory comments, and personal or political attacks
|
||||||
|
- Public or private harassment
|
||||||
|
- Publishing other's private information, such as a physical or email address,
|
||||||
|
without their explicit permission
|
||||||
|
- Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Enforcement Responsibilities
|
||||||
|
|
||||||
|
Community leaders are responsible for clarifying and enforcing our standards of
|
||||||
|
acceptable behavior and will take appropriate and fair corrective action in
|
||||||
|
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||||
|
or harmful.
|
||||||
|
|
||||||
|
Community leaders have the right and responsibility to remove, edit, or reject
|
||||||
|
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||||
|
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||||
|
decisions when appropriate.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies within all community spaces, and also applies when
|
||||||
|
an individual is officially representing the community in public spaces.
|
||||||
|
Examples of representing our community include using an official e-mail address,
|
||||||
|
posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported to the community leaders responsible for enforcement at
|
||||||
|
[contact@memgraph.com](contact@memgraph.com). All complaints will be reviewed
|
||||||
|
and investigated promptly and fairly.
|
||||||
|
|
||||||
|
All community leaders are obligated to respect the privacy and security of the
|
||||||
|
reporter of any incident.
|
||||||
|
|
||||||
|
## Enforcement Guidelines
|
||||||
|
|
||||||
|
Community leaders will follow these Community Impact Guidelines in determining
|
||||||
|
the consequences for any action they deem in violation of this Code of Conduct:
|
||||||
|
|
||||||
|
### 1. Correction
|
||||||
|
|
||||||
|
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||||
|
unprofessional or unwelcome in the community.
|
||||||
|
|
||||||
|
**Consequence**: A private, written warning from community leaders, providing
|
||||||
|
clarity around the nature of the violation and an explanation of why the
|
||||||
|
behavior was inappropriate. A public apology may be requested.
|
||||||
|
|
||||||
|
### 2. Warning
|
||||||
|
|
||||||
|
**Community Impact**: A violation through a single incident or series of
|
||||||
|
actions.
|
||||||
|
|
||||||
|
**Consequence**: A warning with consequences for continued behavior. No
|
||||||
|
interaction with the people involved, including unsolicited interaction with
|
||||||
|
those enforcing the Code of Conduct, for a specified period of time. This
|
||||||
|
includes avoiding interactions in community spaces as well as external channels
|
||||||
|
like social media. Violating these terms may lead to a temporary or permanent
|
||||||
|
ban.
|
||||||
|
|
||||||
|
### 3. Temporary Ban
|
||||||
|
|
||||||
|
**Community Impact**: A serious violation of community standards, including
|
||||||
|
sustained inappropriate behavior.
|
||||||
|
|
||||||
|
**Consequence**: A temporary ban from any sort of interaction or public
|
||||||
|
communication with the community for a specified period of time. No public or
|
||||||
|
private interaction with the people involved, including unsolicited interaction
|
||||||
|
with those enforcing the Code of Conduct, is allowed during this period.
|
||||||
|
Violating these terms may lead to a permanent ban.
|
||||||
|
|
||||||
|
### 4. Permanent Ban
|
||||||
|
|
||||||
|
**Community Impact**: Demonstrating a pattern of violation of community
|
||||||
|
standards, including sustained inappropriate behavior, harassment of an
|
||||||
|
individual, or aggression toward or disparagement of classes of individuals.
|
||||||
|
|
||||||
|
**Consequence**: A permanent ban from any sort of public interaction within the
|
||||||
|
community.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the Contributor Covenant, version 2.1,
|
||||||
|
available at
|
||||||
|
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html](https://www.contributor-covenant.org/version/2/1/code_of_conduct.html).
|
||||||
|
|
||||||
|
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||||
|
enforcement ladder][mozilla coc].
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see the FAQ at
|
||||||
|
[https://www.contributor-covenant.org/faq](https://www.contributor-covenant.org/faq).
|
||||||
|
Translations are available at
|
||||||
|
[https://www.contributor-covenant.org/translations](https://www.contributor-covenant.org/translations).
|
||||||
121
CONTRIBUTING.md
Normal file
121
CONTRIBUTING.md
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
# How to contribute?
|
||||||
|
|
||||||
|
This is a general purpose guide for contributing to Memgraph. We're still
|
||||||
|
working out the kinks to make contributing to this project as easy and
|
||||||
|
transparent as possible, but we're not quite there yet. Hopefully, this document
|
||||||
|
makes the process for contributing clear and answers some questions that you may
|
||||||
|
have.
|
||||||
|
|
||||||
|
- [How to contribute?](#how-to-contribute)
|
||||||
|
- [Open development](#open-development)
|
||||||
|
- [Branch organization](#branch-organization)
|
||||||
|
- [Bugs & changes](#bugs--changes)
|
||||||
|
- [Where to find known issues?](#where-to-find-known-issues)
|
||||||
|
- [Proposing a change](#proposing-a-change)
|
||||||
|
- [Your first pull request](#your-first-pull-request)
|
||||||
|
- [Sending a pull request](#sending-a-pull-request)
|
||||||
|
- [Style guide](#style-guide)
|
||||||
|
- [How to get in touch?](#how-to-get-in-touch)
|
||||||
|
- [Code of Conduct](#code-of-conduct)
|
||||||
|
- [License](#license)
|
||||||
|
- [Attribution](#attribution)
|
||||||
|
|
||||||
|
## Open development
|
||||||
|
|
||||||
|
All work on Memgraph is done via [GitHub](https://github.com/memgraph/memgraph).
|
||||||
|
Both core team members and external contributors send pull requests which go
|
||||||
|
through the same review process.
|
||||||
|
|
||||||
|
## Branch organization
|
||||||
|
|
||||||
|
Most pull requests should target the [`master
|
||||||
|
branch`](https://github.com/memgraph/memgraph/tree/master). We only use separate
|
||||||
|
branches for developing new features and fixing bugs before they are merged with
|
||||||
|
`master`. We do our best to keep `master` in good shape, with all tests passing.
|
||||||
|
|
||||||
|
Code that lands in `master` must be compatible with the latest stable release.
|
||||||
|
It may contain additional features but no breaking changes if it's not
|
||||||
|
absolutely necessary. We should be able to release a new minor version from the
|
||||||
|
tip of `master` at any time.
|
||||||
|
|
||||||
|
## Bugs & changes
|
||||||
|
|
||||||
|
### Where to find known issues?
|
||||||
|
|
||||||
|
We are using [GitHub Issues](https://github.com/memgraph/memgraph/issues) for
|
||||||
|
our public bugs. We keep a close eye on this and try to make it clear when we
|
||||||
|
have an internal fix in progress. Before filing a new task, try to make sure
|
||||||
|
your problem doesn't already exist.
|
||||||
|
|
||||||
|
### Proposing a change
|
||||||
|
|
||||||
|
If you intend to change the public API, or make any non-trivial changes to the
|
||||||
|
implementation, we recommend [filing an
|
||||||
|
issue](https://github.com/memgraph/memgraph/issues/new). This lets us reach an
|
||||||
|
agreement on your proposal before you put significant effort into it.
|
||||||
|
|
||||||
|
If you're only fixing a bug, it's fine to submit a pull request right away but
|
||||||
|
we still recommend to file an issue detailing what you're fixing. This is
|
||||||
|
helpful in case we don't accept that specific fix but want to keep track of the
|
||||||
|
issue.
|
||||||
|
|
||||||
|
### Your first pull request
|
||||||
|
|
||||||
|
Working on your first Pull Request? You can learn how from this free video
|
||||||
|
series:
|
||||||
|
|
||||||
|
**[How to Contribute to an Open Source Project on
|
||||||
|
GitHub](https://app.egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github)**
|
||||||
|
|
||||||
|
If you decide to fix an issue, please be sure to check the comment thread in
|
||||||
|
case somebody is already working on a fix. If nobody is working on it at the
|
||||||
|
moment, please leave a comment stating that you intend to work on it so other
|
||||||
|
people don't accidentally duplicate your effort.
|
||||||
|
|
||||||
|
If somebody claims an issue but doesn't follow up for more than two weeks, it's
|
||||||
|
fine to take it over but you should still leave a comment.
|
||||||
|
|
||||||
|
### Sending a pull request
|
||||||
|
|
||||||
|
The core team is monitoring for pull requests. We will review your pull request
|
||||||
|
and either merge it, request changes to it, or close it with an explanation.
|
||||||
|
**Before submitting a pull request,** please make sure the following is done:
|
||||||
|
|
||||||
|
1. Fork [the repository](https://github.com/memgraph/memgraph) and create your
|
||||||
|
branch from `master`.
|
||||||
|
2. If you've fixed a bug or added code that should be tested, add tests!
|
||||||
|
3. Use the formatter `clang-format` for C/C++ code and `flake8` for Python code.
|
||||||
|
`clang-format` will automatically detect the `.clang-format` file in the root
|
||||||
|
directory while `flake8` can be used with the default configuration.
|
||||||
|
|
||||||
|
### Style guide
|
||||||
|
|
||||||
|
Memgraph uses the [Google Style
|
||||||
|
Guide](https://google.github.io/styleguide/cppguide.html) for C++ in most of its
|
||||||
|
code. You should follow them whenever writing new code.
|
||||||
|
|
||||||
|
## How to get in touch?
|
||||||
|
|
||||||
|
Aside from communicating directly via Pull Requests and Issues, the Memgraph
|
||||||
|
Community [Discord Server](https://discord.gg/memgraph) is the best place for
|
||||||
|
conversing with project maintainers and other community members.
|
||||||
|
|
||||||
|
## [Code of Conduct](https://github.com/memgraph/memgraph/blob/master/CODE_OF_CONDUCT.md)
|
||||||
|
|
||||||
|
Memgraph has adopted the [Contributor
|
||||||
|
Covenant](https://www.contributor-covenant.org/) as its Code of Conduct, and we
|
||||||
|
expect project participants to adhere to it. Please read [the full
|
||||||
|
text](https://github.com/memgraph/memgraph/blob/master/CODE_OF_CONDUCT.md) so
|
||||||
|
that you can understand what actions will and will not be tolerated.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
By contributing to Memgraph, you agree that your contributions will be licensed
|
||||||
|
under the [Memgraph licensing
|
||||||
|
scheme](https://github.com/memgraph/memgraph/blob/master/LICENSE).
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Contributing guide is adapted from the **React.js Contributing guide**
|
||||||
|
available at
|
||||||
|
[https://reactjs.org/docs/how-to-contribute.html](https://reactjs.org/docs/how-to-contribute.html).
|
||||||
5
LICENSE
Normal file
5
LICENSE
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Source code in this repository is variously licensed under the Business Source
|
||||||
|
License 1.1 (BSL), the Memgraph Enterprise License (MEL). A copy of each licence
|
||||||
|
can be found in the licences directory. Source code in a given file is licensed
|
||||||
|
under the BSL and the copyright belongs to The Memgraph Authors unless
|
||||||
|
otherwise noted at th beginning of the file.
|
||||||
173
README.md
173
README.md
@@ -1,47 +1,148 @@
|
|||||||
# Memgraph
|
<p align="center">
|
||||||
|
<img width="400px" src="https://uploads-ssl.webflow.com/5e7ceb09657a69bdab054b3a/5e7ceb09657a6937ab054bba_Black_Original%20_Logo.png">
|
||||||
|
</p>
|
||||||
|
|
||||||
Memgraph is an ACID compliant high performance transactional distributed
|
---
|
||||||
in-memory graph database featuring runtime native query compiling, lock free
|
|
||||||
data structures, multi-version concurrency control and asynchronous IO.
|
|
||||||
|
|
||||||
## Development Documentation
|
<p align="center">
|
||||||
|
Build modern, graph-based applications on top of your streaming data in minutes.
|
||||||
|
</p>
|
||||||
|
|
||||||
* [Quick Start](docs/dev/quick-start.md)
|
<p align="center">
|
||||||
* [Workflow](docs/dev/workflow.md)
|
<a href="https://github.com/memgraph/memgraph/blob/master/licenses/APL.txt">
|
||||||
* [Storage](docs/dev/storage/v2/contents.md)
|
<img src="https://img.shields.io/badge/license-APL-green" alt="license" title="license"/>
|
||||||
* [Query Engine](docs/dev/query/contents.md)
|
</a>
|
||||||
* [Communication](docs/dev/communication/contents.md)
|
<a href="https://github.com/memgraph/memgraph/blob/master/licenses/BSL.txt">
|
||||||
* [Lisp C++ Preprocessor (LCP)](docs/dev/lcp.md)
|
<img src="https://img.shields.io/badge/license-BSL-yellowgreen" alt="license" title="license"/>
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/memgraph/memgraph/blob/master/licenses/MEL.txt" alt="Documentation">
|
||||||
|
<img src="https://img.shields.io/badge/license-MEL-yellow" alt="license" title="license"/>
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
## Feature Specifications
|
<p align="center">
|
||||||
|
<a href="https://github.com/memgraph/memgraph">
|
||||||
|
<img src="https://img.shields.io/github/workflow/status/memgraph/memgraph/Release%20Ubuntu%2020.04/master" alt="build" title="build"/>
|
||||||
|
</a>
|
||||||
|
<a href="https://memgraph.com/docs/" alt="Documentation">
|
||||||
|
<img src="https://img.shields.io/badge/documentation-Memgraph-orange" />
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
Each prominent Memgraph feature requires a feature specification. The purpose
|
<p align="center">
|
||||||
of the feature specification is to have a base for discussing all aspects of
|
<a href="https://memgr.ph/join-discord">
|
||||||
the feature. Elements of feature specifications should be:
|
<img src="https://img.shields.io/badge/Discord-7289DA?style=for-the-badge&logo=discord&logoColor=white" alt="Discord"/>
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
* High-level context.
|
## :clipboard: Description
|
||||||
* Interface.
|
|
||||||
* User stories. Usage from the end-user perspective. In the case of a library,
|
|
||||||
that should be cases on how to use the programming interface. In the case of
|
|
||||||
a shell script, that should be cases on how to use flags.
|
|
||||||
* Discussion about concurrency, memory management, error management.
|
|
||||||
* Any other essential functional or non-functional requirements.
|
|
||||||
* Test and benchmark strategy.
|
|
||||||
* Possible future changes/improvements/extensions.
|
|
||||||
* Security concerns.
|
|
||||||
* Additional and/or optional implementation details.
|
|
||||||
|
|
||||||
It's crucial to keep feature spec up-to-date with the implementation. Take a
|
Memgraph is a streaming graph application platform that helps you wrangle your
|
||||||
look at the list of [feature specifications](docs/feature_spec/contents.md) to
|
streaming data, build sophisticated models that you can query in real-time, and
|
||||||
learn more about powerful Memgraph features.
|
develop graph applications.
|
||||||
|
|
||||||
## User Documentation
|
Memgraph directly connects to your streaming infrastructure. You can ingest data
|
||||||
|
from sources like Kafka, SQL, or plain CSV files. Memgraph provides a standard
|
||||||
|
interface to query your data with Cypher, a widely-used and declarative query
|
||||||
|
language that is easy to write, understand and optimize for performance. This is
|
||||||
|
achieved by using the property graph data model, which stores data in terms of
|
||||||
|
objects, their attributes, and the relationships that connect them. This is a
|
||||||
|
natural and effective way to model many real-world problems without relying on
|
||||||
|
complex SQL schemas.
|
||||||
|
|
||||||
Memgraph user documentation is maintained within
|
Memgraph is implemented in C/C++ and leverages an in-memory first architecture
|
||||||
[docs](https://github.com/memgraph/docs) repository. The documentation is also
|
to ensure that you’re getting the best possible performance consistently and
|
||||||
available on [GitBook](https://docs.memgraph.com).
|
without surprises. It’s also ACID-compliant and highly available.
|
||||||
|
|
||||||
## Licences
|
## :video_game: Memgraph Playground
|
||||||
|
|
||||||
* [Community](release/LICENSE_COMMUNITY.md)
|
You don't need to install anything to try out Memgraph. Check out
|
||||||
* [Enterprise](release/LICENSE_ENTERPRISE.md)
|
our **[Memgraph Playground](https://playground.memgraph.com/)** sandboxes in
|
||||||
|
your browser.
|
||||||
|
|
||||||
|
<p align="left">
|
||||||
|
<a href="https://playground.memgraph.com/">
|
||||||
|
<img width="450px" alt="Memgraph Playground" src="https://download.memgraph.com/asset/github/memgraph/memgraph-playground.png">
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
## :floppy_disk: Download & Install
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
[](https://memgraph.com/docs/memgraph/install-memgraph-on-windows-docker)
|
||||||
|
[](https://memgraph.com/docs/memgraph/install-memgraph-on-windows-wsl)
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
|
||||||
|
[](https://memgraph.com/docs/memgraph/install-memgraph-on-macos-docker)
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
[](https://memgraph.com/docs/memgraph/install-memgraph-on-linux-docker)
|
||||||
|
[](https://memgraph.com/docs/memgraph/install-memgraph-on-debian)
|
||||||
|
[](https://memgraph.com/docs/memgraph/install-memgraph-on-ubuntu)
|
||||||
|
[](https://memgraph.com/docs/memgraph/install-memgraph-from-rpm)
|
||||||
|
|
||||||
|
You can find the binaries and Docker images on the [Download
|
||||||
|
Hub](https://memgraph.com/download) and the installation instructions in the
|
||||||
|
[official documentation](https://memgraph.com/docs/memgraph/installation).
|
||||||
|
|
||||||
|
## :zap: Features
|
||||||
|
|
||||||
|
- Run Python, Rust, and C/C++ code natively, check out the
|
||||||
|
[MAGE](https://github.com/memgraph/mage) graph algorithm library
|
||||||
|
- Native support for machine learning
|
||||||
|
- Streaming support
|
||||||
|
- Replication
|
||||||
|
- Authentication and authorization
|
||||||
|
- ACID compliance
|
||||||
|
|
||||||
|
## :bookmark_tabs: Documentation
|
||||||
|
|
||||||
|
The Memgraph documentation is available at
|
||||||
|
[memgraph.com/docs](https://memgraph.com/docs).
|
||||||
|
|
||||||
|
## :question: Configuration
|
||||||
|
|
||||||
|
Command line options that Memgraph accepts are available in the [reference
|
||||||
|
guide](https://memgraph.com/docs/memgraph/reference-guide/configuration).
|
||||||
|
|
||||||
|
## :trophy: Contributing
|
||||||
|
|
||||||
|
The main purpose of this repository is to continue evolving Memgraph, making it
|
||||||
|
faster and easier to use. Development of Memgraph happens in the open on GitHub,
|
||||||
|
and we are grateful to the community for contributing bug fixes and
|
||||||
|
improvements. Read below to learn how you can take part in improving Memgraph.
|
||||||
|
|
||||||
|
### Code of Conduct
|
||||||
|
|
||||||
|
Memgraph has adopted a Code of Conduct that we expect project participants to
|
||||||
|
adhere to. Please read [the full text](CODE_OF_CONDUCT.md) so that you can
|
||||||
|
understand what actions will and will not be tolerated.
|
||||||
|
|
||||||
|
### Contributing Guide
|
||||||
|
|
||||||
|
Read our [contributing guide](CONTRIBUTING.md) to learn about our development
|
||||||
|
process and how to propose bug fixes and improvements.
|
||||||
|
|
||||||
|
### Internals
|
||||||
|
|
||||||
|
Read our
|
||||||
|
[internal](https://memgraph.notion.site/Memgraph-Internals-12b69132d67a417898972927d6870bd2)
|
||||||
|
docs to learn more about Memgraph's architecture, how to build the project from
|
||||||
|
source and how to start contributing. All information related to the database,
|
||||||
|
can be found in the aforementioned docs.
|
||||||
|
|
||||||
|
### :scroll: License
|
||||||
|
|
||||||
|
Memgraph Community is available under the [BSL
|
||||||
|
license](./licenses/BSL.txt).</br> Memgraph Enterprise is available under the
|
||||||
|
[MEL license](./licenses/MEL.txt).
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="#">
|
||||||
|
<img src="https://img.shields.io/badge/⬆️back_to_top_⬆️-white" alt="Back to top" title="Back to top"/>
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|||||||
55
cmake/FindJemalloc.cmake
Normal file
55
cmake/FindJemalloc.cmake
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# Try to find jemalloc library
|
||||||
|
#
|
||||||
|
# Use this module as:
|
||||||
|
# find_package(Jemalloc)
|
||||||
|
#
|
||||||
|
# or:
|
||||||
|
# find_package(Jemalloc REQUIRED)
|
||||||
|
#
|
||||||
|
# This will define the following variables:
|
||||||
|
#
|
||||||
|
# Jemalloc_FOUND True if the system has the jemalloc library.
|
||||||
|
# Jemalloc_INCLUDE_DIRS Include directories needed to use jemalloc.
|
||||||
|
# Jemalloc_LIBRARIES Libraries needed to link to jemalloc.
|
||||||
|
#
|
||||||
|
# The following cache variables may also be set:
|
||||||
|
#
|
||||||
|
# Jemalloc_INCLUDE_DIR The directory containing jemalloc/jemalloc.h.
|
||||||
|
# Jemalloc_LIBRARY The path to the jemalloc static library.
|
||||||
|
|
||||||
|
find_path(Jemalloc_INCLUDE_DIR NAMES jemalloc/jemalloc.h PATH_SUFFIXES include)
|
||||||
|
|
||||||
|
find_library(Jemalloc_LIBRARY NAMES libjemalloc.a PATH_SUFFIXES lib)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(Jemalloc
|
||||||
|
FOUND_VAR Jemalloc_FOUND
|
||||||
|
REQUIRED_VARS
|
||||||
|
Jemalloc_LIBRARY
|
||||||
|
Jemalloc_INCLUDE_DIR
|
||||||
|
)
|
||||||
|
|
||||||
|
if(Jemalloc_FOUND)
|
||||||
|
set(Jemalloc_LIBRARIES ${Jemalloc_LIBRARY})
|
||||||
|
set(Jemalloc_INCLUDE_DIRS ${Jemalloc_INCLUDE_DIR})
|
||||||
|
else()
|
||||||
|
if(Jemalloc_FIND_REQUIRED)
|
||||||
|
message(FATAL_ERROR "Cannot find jemalloc!")
|
||||||
|
else()
|
||||||
|
message(WARNING "jemalloc is not found!")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(Jemalloc_FOUND AND NOT TARGET Jemalloc::Jemalloc)
|
||||||
|
add_library(Jemalloc::Jemalloc UNKNOWN IMPORTED)
|
||||||
|
set_target_properties(Jemalloc::Jemalloc
|
||||||
|
PROPERTIES
|
||||||
|
IMPORTED_LOCATION "${Jemalloc_LIBRARY}"
|
||||||
|
INTERFACE_INCLUDE_DIRECTORIES "${Jemalloc_INCLUDE_DIR}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
mark_as_advanced(
|
||||||
|
Jemalloc_INCLUDE_DIR
|
||||||
|
Jemalloc_LIBRARY
|
||||||
|
)
|
||||||
@@ -39,10 +39,22 @@ modifications:
|
|||||||
value: "/var/log/memgraph/memgraph.log"
|
value: "/var/log/memgraph/memgraph.log"
|
||||||
override: true
|
override: true
|
||||||
|
|
||||||
|
- name: "log_level"
|
||||||
|
value: "WARNING"
|
||||||
|
override: true
|
||||||
|
|
||||||
- name: "bolt_num_workers"
|
- name: "bolt_num_workers"
|
||||||
value: ""
|
value: ""
|
||||||
override: false
|
override: false
|
||||||
|
|
||||||
|
- name: "bolt_cert_file"
|
||||||
|
value: "/etc/memgraph/ssl/cert.pem"
|
||||||
|
override: false
|
||||||
|
|
||||||
|
- name: "bolt_key_file"
|
||||||
|
value: "/etc/memgraph/ssl/key.pem"
|
||||||
|
override: false
|
||||||
|
|
||||||
- name: "storage_properties_on_edges"
|
- name: "storage_properties_on_edges"
|
||||||
value: "true"
|
value: "true"
|
||||||
override: true
|
override: true
|
||||||
@@ -71,23 +83,27 @@ modifications:
|
|||||||
value: "true"
|
value: "true"
|
||||||
override: true
|
override: true
|
||||||
|
|
||||||
- name: "query_modules_directory"
|
# - name: "query_modules_directory"
|
||||||
value: "/usr/lib/memgraph/query_modules"
|
# value: "/usr/lib/memgraph/query_modules"
|
||||||
|
# override: true
|
||||||
|
|
||||||
|
- name: "memory_limit"
|
||||||
|
value: "0"
|
||||||
override: true
|
override: true
|
||||||
|
|
||||||
- name: "auth_module_executable"
|
- name: "isolation_level"
|
||||||
value: "/usr/lib/memgraph/auth_module/example.py"
|
value: "SNAPSHOT_ISOLATION"
|
||||||
|
override: true
|
||||||
|
|
||||||
|
- name: "allow_load_csv"
|
||||||
|
value: "true"
|
||||||
override: false
|
override: false
|
||||||
|
|
||||||
undocumented:
|
undocumented:
|
||||||
- "flag_file"
|
- "flag_file"
|
||||||
- "log_file_mode"
|
- "also_log_to_stderr"
|
||||||
- "log_link_basename"
|
|
||||||
- "log_prefix"
|
|
||||||
- "max_log_size"
|
|
||||||
- "min_log_level"
|
|
||||||
- "help"
|
- "help"
|
||||||
- "help_xml"
|
- "help_xml"
|
||||||
- "stderr_threshold"
|
|
||||||
- "stop_logging_if_full_disk"
|
|
||||||
- "version"
|
- "version"
|
||||||
|
- "organization_name"
|
||||||
|
- "license_key"
|
||||||
|
|||||||
@@ -1,269 +0,0 @@
|
|||||||
# Code Review Guidelines
|
|
||||||
|
|
||||||
This chapter describes some of the things you should be on the lookout when
|
|
||||||
reviewing someone else's code.
|
|
||||||
|
|
||||||
## Exceptions
|
|
||||||
|
|
||||||
Although the Google C++ Style Guide forbids exceptions, we do allow them in
|
|
||||||
our codebase. As a reviewer you should watch out for the following.
|
|
||||||
|
|
||||||
The documentation of throwing functions needs to be in-sync with the
|
|
||||||
implementation. This must be enforced recursively. I.e. if a function A now
|
|
||||||
throws a new exception, and the function B uses A, then B needs to handle that
|
|
||||||
exception or have its documentation updated and so on. Naturally, the same
|
|
||||||
applies when an exception is removed.
|
|
||||||
|
|
||||||
Transitive callers of the function which throws a new exception must be OK
|
|
||||||
with that. This ties into the previous point. You need to check that all users
|
|
||||||
of the new exception either handle it correctly or propagate it.
|
|
||||||
|
|
||||||
Exceptions should not escape out of class destructors, because that will
|
|
||||||
terminate the program. The code should be changed so that such cases are not
|
|
||||||
possible.
|
|
||||||
|
|
||||||
Exceptions being thrown in class constructors. Although this is well defined
|
|
||||||
in C++, it usually implies that a constructor is doing too much work and the
|
|
||||||
class construction & initialization should be redesigned. Usual approaches are
|
|
||||||
using the (Static) Factory Method pattern or having some sort of an
|
|
||||||
initialization method that needs to be called after the construction is done.
|
|
||||||
Prefer the Factory Method.
|
|
||||||
|
|
||||||
Don't forget that STL functions may also throw!
|
|
||||||
|
|
||||||
## Pointers & References
|
|
||||||
|
|
||||||
In cases when some code passes a pointer or reference, or if a code stores a
|
|
||||||
pointer or reference you should take a careful look at the following.
|
|
||||||
|
|
||||||
* Lifetime of the pointed to value (this includes both ownership and
|
|
||||||
multithreaded access).
|
|
||||||
* In case of a class, check validity of destructor and move/copy
|
|
||||||
constructors.
|
|
||||||
* Is the pointed to value mutated, if not it should be `const` (`const Type
|
|
||||||
*` or `const Type &`).
|
|
||||||
|
|
||||||
## Allocators & Memory Resources
|
|
||||||
|
|
||||||
With the introduction of polymorphic allocators (C++17 `<memory_resource>` and
|
|
||||||
our `utils/memory.hpp`) we get a more convenient type signatures for
|
|
||||||
containers so as to keep the outward facing API nice. This convenience comes
|
|
||||||
at a cost of less static checks on the type level due to type erasure.
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
std::pmr::vector<int> first_vec(std::pmr::null_memory_resource());
|
|
||||||
std::pmr::vector<int> second_vec(std::pmr::new_delete_resource());
|
|
||||||
|
|
||||||
second_vec = first_vec // What happens here?
|
|
||||||
|
|
||||||
// Or with our implementation
|
|
||||||
utils::MonotonicBufferResource monotonic_memory(1024);
|
|
||||||
std::vector<int, utils::Allocator<int>> first_vec(&monotonic_memory);
|
|
||||||
std::vector<int, utils::Allocator<int>> second_vec(utils::NewDeleteResource());
|
|
||||||
|
|
||||||
second_vec = first_vec // What happens here?
|
|
||||||
|
|
||||||
In the above, both `first_vec` and `second_vec` have the same type, but have
|
|
||||||
*different* allocators! This can lead to ambiguity when moving or copying
|
|
||||||
elements between them.
|
|
||||||
|
|
||||||
You need to watch out for the following.
|
|
||||||
|
|
||||||
* Swapping can lead to undefined behaviour if the allocators are not equal.
|
|
||||||
* Is the move construction done with the right allocator.
|
|
||||||
* Is the move assignment done correctly, also it may throw an exception.
|
|
||||||
* Is the copy construction done with the right allocator.
|
|
||||||
* Is the copy assignment done correctly.
|
|
||||||
* Using `auto` makes allocator propagation rules rather ambiguous.
|
|
||||||
|
|
||||||
## Classes & Object Oriented Programming
|
|
||||||
|
|
||||||
A common mistake is to use classes, inheritance and "OOP" when it's not
|
|
||||||
needed. This sections shows examples of encountered cases.
|
|
||||||
|
|
||||||
### Classes without (Meaningful) Members
|
|
||||||
|
|
||||||
class MyCoolClass {
|
|
||||||
public:
|
|
||||||
int BeCool(int a, int b) { return a + b; }
|
|
||||||
|
|
||||||
void SaySomethingCool() { std::cout << "Hello!"; }
|
|
||||||
};
|
|
||||||
|
|
||||||
The above class has no members (i.e. state) which affect the behaviour of
|
|
||||||
methods. This class should need not exist, it can be easily replaced with a
|
|
||||||
more modular (and shorter) design -- top level functions.
|
|
||||||
|
|
||||||
int BeCool(int a, int b) { return a + b; }
|
|
||||||
|
|
||||||
void SaySomethingCool() { std::cout << "Hello!"; }
|
|
||||||
|
|
||||||
### Classes with a Single Public Method
|
|
||||||
|
|
||||||
clas MyAwesomeClass {
|
|
||||||
public:
|
|
||||||
MyAwesomeClass(int state) : state_(state) {}
|
|
||||||
|
|
||||||
int GetAwesome() { return GetAwesomeImpl() + 1; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
int state_;
|
|
||||||
|
|
||||||
int GetAwesomeImpl() { return state_; }
|
|
||||||
};
|
|
||||||
|
|
||||||
The above class has a `state_` and even a private method, but there's only one
|
|
||||||
public method -- `GetAwesome`.
|
|
||||||
|
|
||||||
You should check "Does the stored state have any meaningful influence on the
|
|
||||||
public method?", similarly to the previous point.
|
|
||||||
|
|
||||||
In the above case it doesn't, and the class should be replaced with a public
|
|
||||||
function in `.hpp` while the private method should become a private function
|
|
||||||
in `.cpp` (static or in anonymous namespace).
|
|
||||||
|
|
||||||
// hpp
|
|
||||||
int GetAwesome(int state);
|
|
||||||
|
|
||||||
// cpp
|
|
||||||
namespace {
|
|
||||||
int GetAwesomeImpl(int state) { return state; }
|
|
||||||
}
|
|
||||||
int GetAwesome(int state) { return GetAwesomeImpl(state) + 1; }
|
|
||||||
|
|
||||||
A counterexample is when the state is meaningful.
|
|
||||||
|
|
||||||
class Counter {
|
|
||||||
public:
|
|
||||||
Counter(int state) : state_(state) {}
|
|
||||||
|
|
||||||
int Get() { return state_++; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
int state_;
|
|
||||||
};
|
|
||||||
|
|
||||||
But even that could be replaced with a closure.
|
|
||||||
|
|
||||||
auto MakeCounter(int state) {
|
|
||||||
return [state]() mutable { return state++; };
|
|
||||||
}
|
|
||||||
|
|
||||||
### Private Methods
|
|
||||||
|
|
||||||
Instead of private methods, top level functions should be preferred. The
|
|
||||||
reasoning is completely explained in "Effective C++" Item 23 by Scott Meyers.
|
|
||||||
In our codebase, even improvements to compilation times can be noticed if
|
|
||||||
private methods in interface (`.hpp`) files are replaced with top level
|
|
||||||
functions in implementation (`.cpp`) files.
|
|
||||||
|
|
||||||
### Inheritance
|
|
||||||
|
|
||||||
The rule is simple -- if there are no virtual methods (but maybe destructor),
|
|
||||||
then the class should be marked as `final` and never inherited.
|
|
||||||
|
|
||||||
If there are virtual methods (i.e. class is meant to be inherited), make sure
|
|
||||||
that either a public virtual destructor or a protected non-virtual destructor
|
|
||||||
exist. See "Effective C++" Item 7 by Scott Meyers. Also take a look at
|
|
||||||
"Effective C++" Items 32---39 by Scott Meyers.
|
|
||||||
|
|
||||||
An example of how inheritance with no virtual methods is replaced with
|
|
||||||
composition.
|
|
||||||
|
|
||||||
class MyBase {
|
|
||||||
public:
|
|
||||||
virtual ~MyBase() {}
|
|
||||||
|
|
||||||
void DoSomethingBase() { ... }
|
|
||||||
};
|
|
||||||
|
|
||||||
class MyDerived final : public MyBase {
|
|
||||||
public:
|
|
||||||
void DoSomethingNew() { ... DoSomethingBase(); ... }
|
|
||||||
};
|
|
||||||
|
|
||||||
With composition, the above becomes.
|
|
||||||
|
|
||||||
class MyBase final {
|
|
||||||
public:
|
|
||||||
void DoSomethingBase() { ... }
|
|
||||||
};
|
|
||||||
|
|
||||||
class MyDerived final {
|
|
||||||
MyBase base_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void DoSomethingNew() { ... base_.DoSomethingBase(); ... }
|
|
||||||
};
|
|
||||||
|
|
||||||
The composition approach is preferred as it encapsulates the fact that
|
|
||||||
`MyBase` is used for the implementation and users only interact with the
|
|
||||||
public interface of `MyDerived`. Additionally, you can easily replace `MyBase
|
|
||||||
base_;` with a C++ PIMPL idiom (`std::unique_ptr<MyBase> base_;`) to make the
|
|
||||||
code more modular with regards to compilation.
|
|
||||||
|
|
||||||
More advanced C++ users will recognize that the encapsulation feature of the
|
|
||||||
non-PIMPL composition can be replaced with private inheritance.
|
|
||||||
|
|
||||||
class MyDerived final : private MyBase {
|
|
||||||
public:
|
|
||||||
void DoSomethingNew() { ... MyBase::DoSomethingBase(); ... }
|
|
||||||
};
|
|
||||||
|
|
||||||
One of the common "counterexample" is the ability to store objects of
|
|
||||||
different type in a container or pass them to a function. Unfortunately, this
|
|
||||||
is not that good of a design. For example.
|
|
||||||
|
|
||||||
class MyBase {
|
|
||||||
... // No virtual methods (but the destructor)
|
|
||||||
};
|
|
||||||
|
|
||||||
class MyFirstClass final : public MyBase { ... };
|
|
||||||
|
|
||||||
class MySecondClass final : public MyBase { ... };
|
|
||||||
|
|
||||||
std::vector<std::unique_ptr<MyBase>> first_and_second_classes;
|
|
||||||
first_and_second_classes.push_back(std::make_unique<MyFirstClass>());
|
|
||||||
first_and_second_classes.push_back(std::make_unique<MySecondClass>());
|
|
||||||
|
|
||||||
void FunctionOnFirstOrSecond(const MyBase &first_or_second, ...) { ... }
|
|
||||||
|
|
||||||
With C++17, the containers for different types should be implemented with
|
|
||||||
`std::variant`, and as before the functions can be templated.
|
|
||||||
|
|
||||||
class MyFirstClass final { ... };
|
|
||||||
|
|
||||||
class MySecondClass final { ... };
|
|
||||||
|
|
||||||
std::vector<std::variant<MyFirstClass, MySecondClass>> first_and_second_classes;
|
|
||||||
// Notice no heap allocation, since we don't store a pointer
|
|
||||||
first_and_second_classes.emplace_back(MyFirstClass());
|
|
||||||
first_and_second_classes.emplace_back(MySecondClass());
|
|
||||||
|
|
||||||
// You can also use `std::variant` here instead of template
|
|
||||||
template <class TFirstOrSecond>
|
|
||||||
void FunctionOnFirstOrSecond(const TFirstOrSecond &first_or_second, ...) { ... }
|
|
||||||
|
|
||||||
Naturally, if the base class has meaningful virtual methods (i.e. other than
|
|
||||||
destructor) it maybe is OK to use inheritance but also consider alternatives.
|
|
||||||
See "Effective C++" Items 32---39 by Scott Meyers.
|
|
||||||
|
|
||||||
### Multiple Inheritance
|
|
||||||
|
|
||||||
Multiple inheritance should not be used unless all base classes are pure
|
|
||||||
interface classes. This decision is inherited from [Google C++ Style
|
|
||||||
Guide](https://google.github.io/styleguide/cppguide.html#Inheritance). For
|
|
||||||
example on how to design with and around multiple inheritance refer to
|
|
||||||
"Effective C++" Item 40 by Scott Meyers.
|
|
||||||
|
|
||||||
Naturally, if there *really* is no better design, then multiple inheritance is
|
|
||||||
allowed. An example of this can be found in our codebase when inheriting
|
|
||||||
Visitor classes (though even that could be replaced with `std::variant` for
|
|
||||||
example).
|
|
||||||
|
|
||||||
## Code Format & Style
|
|
||||||
|
|
||||||
If something doesn't conform to our code formatting and style, just refer the
|
|
||||||
author to either [C++ Style](cpp-code-conventions.md) or [Other Code
|
|
||||||
Conventions](other-code-conventions.md).
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
# Communication
|
|
||||||
|
|
||||||
## Bolt
|
|
||||||
|
|
||||||
Memgraph implements [Bolt communication protocol](https://7687.org/).
|
|
||||||
@@ -1,350 +0,0 @@
|
|||||||
# C++ Code Conventions
|
|
||||||
|
|
||||||
This chapter describes code conventions which should be followed when writing
|
|
||||||
C++ code.
|
|
||||||
|
|
||||||
## Code Style
|
|
||||||
|
|
||||||
Memgraph uses the
|
|
||||||
[Google Style Guide for C++](https://google.github.io/styleguide/cppguide.html)
|
|
||||||
in most of its code. You should follow them whenever writing new code.
|
|
||||||
Besides following the style guide, take a look at
|
|
||||||
[Code Review Guidelines](code-review.md) for common design issues and pitfalls
|
|
||||||
with C++ as well as [Required Reading](required-reading.md).
|
|
||||||
|
|
||||||
### Often Overlooked Style Conventions
|
|
||||||
|
|
||||||
#### Pointers & References
|
|
||||||
|
|
||||||
References provide a shorter syntax for accessing members and better declare
|
|
||||||
the intent that a pointer *should* not be `nullptr`. They do not prevent
|
|
||||||
accessing a `nullptr` and obfuscate the client/calling code because the
|
|
||||||
reference argument is passed just like a value. Errors with such code have
|
|
||||||
been very difficult to debug. Therefore, pointers are always used. They will
|
|
||||||
not prevent bugs but will make some of them more obvious when reading code.
|
|
||||||
|
|
||||||
The only time a reference can be used is if it is `const`. Note that this
|
|
||||||
kind of reference is not allowed if it is stored somewhere, i.e. in a class.
|
|
||||||
You should use a pointer to `const` then. The primary reason being is that
|
|
||||||
references obscure the semantics of moving an object, thus making bugs with
|
|
||||||
references pointing to invalid memory harder to track down.
|
|
||||||
|
|
||||||
Example of this can be seen while capturing member variables by reference
|
|
||||||
inside a lambda.
|
|
||||||
Let's define a class that has two members, where one of those members is a
|
|
||||||
lambda that captures the other member by reference.
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
struct S {
|
|
||||||
std::function<void()> foo;
|
|
||||||
int bar;
|
|
||||||
|
|
||||||
S() : foo([&]() { std::cout << bar; })
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
```
|
|
||||||
What would happend if we move an instance of this object? Our lambda
|
|
||||||
reference capture will point to the same location as before, i.e. it
|
|
||||||
will point to the **old** memory location of `bar`. This means we have
|
|
||||||
a dangling reference in our code!
|
|
||||||
There are multiple ways to avoid this. The simple solutions would be
|
|
||||||
capturing by value or disabling move constructors/assignments.
|
|
||||||
Still, if we capture by reference an object that is not a member
|
|
||||||
of the struct containing the lambda, we can still have a dangling
|
|
||||||
reference if we move that object somewhere in our code and there is
|
|
||||||
nothing we can do to prevent that.
|
|
||||||
So, be careful with lambda catptures, and remember that references are
|
|
||||||
still a pointer under the hood!
|
|
||||||
|
|
||||||
[Style guide reference](https://google.github.io/styleguide/cppguide.html#Reference_Arguments)
|
|
||||||
|
|
||||||
#### Constructors & RAII
|
|
||||||
|
|
||||||
RAII (Resource Acquisition is Initialization) is a nice mechanism for managing
|
|
||||||
resources. It is especially useful when exceptions are used, such as in our
|
|
||||||
code. Unfortunately, they do have 2 major downsides.
|
|
||||||
|
|
||||||
* Only exceptions can be used for to signal failure.
|
|
||||||
* Calls to virtual methods are not resolved as expected.
|
|
||||||
|
|
||||||
For those reasons the style guide recommends minimal work that cannot fail.
|
|
||||||
Using virtual methods or doing a lot more should be delegated to some form of
|
|
||||||
`Init` method, possibly coupled with static factory methods. Similar rules
|
|
||||||
apply to destructors, which are not allowed to even throw exceptions.
|
|
||||||
|
|
||||||
[Style guide reference](https://google.github.io/styleguide/cppguide.html#Doing_Work_in_Constructors)
|
|
||||||
|
|
||||||
#### Constructors and member variables
|
|
||||||
|
|
||||||
One of the most powerful tools in C++ is the move semantics. We won't go into
|
|
||||||
detail how it works, but you should know how to utilize it as much as
|
|
||||||
possible. In our example we will define a small `struct` called `S` which
|
|
||||||
contains only a single member, `text` of type `std::string`.
|
|
||||||
```cpp
|
|
||||||
struct S {
|
|
||||||
std::string text;
|
|
||||||
};
|
|
||||||
```
|
|
||||||
We want to define a constructor that takes a `std::string`, and saves its
|
|
||||||
value in `text`. This is a common situation, where the constructor takes
|
|
||||||
a value, and saves it in the object to be constructed.
|
|
||||||
|
|
||||||
Our first implementation would look like this:
|
|
||||||
```cpp
|
|
||||||
S(const std::string &s) : text(s) {}
|
|
||||||
```
|
|
||||||
|
|
||||||
This is a valid solution but with one downside - we always copy. If we
|
|
||||||
construct an object like this:
|
|
||||||
```cpp
|
|
||||||
S s("some text");
|
|
||||||
```
|
|
||||||
we would create a temporary `std::string` object and then copy it to our member
|
|
||||||
variable.
|
|
||||||
|
|
||||||
Of course, we know what to do now - we will capture temporary variables using
|
|
||||||
`&&` and move it into our `text` variable.
|
|
||||||
```cpp
|
|
||||||
S(std::string &&s) : text(std::move(s)) {}
|
|
||||||
```
|
|
||||||
|
|
||||||
Now let's add an extra member variable of type `std::vector<int>` called
|
|
||||||
`words`. Our constructors accept 2 values now - `std::vector<int>` and
|
|
||||||
`std::string`. Those arguments could be passed by value, by reference, or
|
|
||||||
as rvalues. To cover all the cases we need to define a dedicated constructor
|
|
||||||
for each case.
|
|
||||||
Fortunately, there are two simpler options, the first one is writing a
|
|
||||||
templated constructor:
|
|
||||||
```cpp
|
|
||||||
template<typename T1, typename T2>
|
|
||||||
S(T1 &&s, T2 &&v) : text(std::forward<T1>(s), words(std::forward<T2>(v) {}
|
|
||||||
```
|
|
||||||
But don't forget to define `requires` clause so you don't accept any type. This
|
|
||||||
solution is optimal but really hard to read AND write. The second solution is
|
|
||||||
something you should ALWAYS prefer in these simple cases where we only store
|
|
||||||
one of the arguments:
|
|
||||||
```cpp
|
|
||||||
S(std::string s, std::vector<int> v) : text(std::move(s)), words(std::move(v)) {}
|
|
||||||
```
|
|
||||||
This way we have an almost optimal solution. The only extra operation we have is
|
|
||||||
the extra move when we send an `lvalue`. We would copy the value to the `s`, and
|
|
||||||
then move it to the `text` variable. Before, we would copy directly to `text`.
|
|
||||||
Also, you should ALWAYS write const-correct code, meaning `s` and `v` cannot be
|
|
||||||
`const` as it's not correct here. Why is that? You CANNOT move a const object!
|
|
||||||
It would just degrade to copying the object. I would say that this is a small
|
|
||||||
price to pay for a much cleaner and more maintainable code.
|
|
||||||
|
|
||||||
### Additional Style Conventions
|
|
||||||
|
|
||||||
Old code may have broken Google C++ Style accidentally, but the new code
|
|
||||||
should adhere to it as close as possible. We do have some exceptions
|
|
||||||
to Google style as well as additions for unspecified conventions.
|
|
||||||
|
|
||||||
#### Using C++ Exceptions
|
|
||||||
|
|
||||||
Unlike Google, we do not forbid using exceptions.
|
|
||||||
|
|
||||||
But, you should be very careful when using them and introducing new ones. They
|
|
||||||
are indeed handy, but cause problems with understanding the control flow since
|
|
||||||
exceptions are another form of `goto`. It also becomes very hard to determine
|
|
||||||
that the program is in correct state after the stack is unwound and the thrown
|
|
||||||
exception handled. Other than those issues, throwing exceptions in destructors
|
|
||||||
will terminate the program. The same will happen if a thread doesn't handle an
|
|
||||||
exception even though it is not the main thread.
|
|
||||||
|
|
||||||
[Style guide reference](https://google.github.io/styleguide/cppguide.html#Exceptions)
|
|
||||||
|
|
||||||
In general, when introducing a new exception, either via `throw` statement or
|
|
||||||
calling a function which throws, you must examine all transitive callers and
|
|
||||||
update their implementation and/or documentation.
|
|
||||||
|
|
||||||
#### Assertions
|
|
||||||
|
|
||||||
We use `CHECK` and `DCHECK` macros from glog library. You are encouraged to
|
|
||||||
use them as often as possible to both document and validate various pre and
|
|
||||||
post conditions of a function.
|
|
||||||
|
|
||||||
`CHECK` remains even in release build and should be preferred over it's cousin
|
|
||||||
`DCHECK` which only exists in debug builds. The primary reason is that you
|
|
||||||
want to trigger assertions in release builds in case the tests didn't
|
|
||||||
completely validate all code paths. It is better to fail fast and crash the
|
|
||||||
program, than to leave it in undefined state and potentially corrupt end
|
|
||||||
user's work. In cases when profiling shows that `CHECK` is causing visible
|
|
||||||
slowdown you should switch to `DCHECK`.
|
|
||||||
|
|
||||||
#### Template Parameter Naming
|
|
||||||
|
|
||||||
Template parameter names should start with capital letter 'T' followed by a
|
|
||||||
short descriptive name. For example:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
template <typename TKey, typename TValue>
|
|
||||||
class KeyValueStore
|
|
||||||
```
|
|
||||||
|
|
||||||
## Code Formatting
|
|
||||||
|
|
||||||
You should install `clang-format` and run it on code you change or add. The
|
|
||||||
root of Memgraph's project contains the `.clang-format` file, which specifies
|
|
||||||
how formatting should behave. Running `clang-format -style=file` in the
|
|
||||||
project's root will read the file and behave as expected. For ease of use, you
|
|
||||||
should integrate formatting with your favourite editor.
|
|
||||||
|
|
||||||
The code formatting isn't enforced, because sometimes manual formatting may
|
|
||||||
produce better results. Though, running `clang-format` is strongly encouraged.
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
Besides following the comment guidelines from [Google Style
|
|
||||||
Guide](https://google.github.io/styleguide/cppguide.html#Comments), your
|
|
||||||
documentation of the public API should be
|
|
||||||
[Doxygen](https://github.com/doxygen/doxygen) compatible. For private parts of
|
|
||||||
the code or for comments accompanying the implementation, you are free to
|
|
||||||
break doxygen compatibility. In both cases, you should write your
|
|
||||||
documentation as full sentences, correctly written in English.
|
|
||||||
|
|
||||||
## Doxygen
|
|
||||||
|
|
||||||
To start a Doxygen compatible documentation string, you should open your
|
|
||||||
comment with either a JavaDoc style block comment (`/**`) or a line comment
|
|
||||||
containing 3 slashes (`///`). Take a look at the 2 examples below.
|
|
||||||
|
|
||||||
### Block Comment
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
/**
|
|
||||||
* One sentence, brief description.
|
|
||||||
*
|
|
||||||
* Long form description.
|
|
||||||
*/
|
|
||||||
```
|
|
||||||
|
|
||||||
### Line Comment
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
/// One sentence, brief description.
|
|
||||||
///
|
|
||||||
/// Long form description.
|
|
||||||
```
|
|
||||||
|
|
||||||
If you only have a brief description, you may collapse the documentation into
|
|
||||||
a single line.
|
|
||||||
|
|
||||||
### Block Comment
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
/** Brief description. */
|
|
||||||
```
|
|
||||||
|
|
||||||
### Line Comment
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
/// Brief description.
|
|
||||||
```
|
|
||||||
|
|
||||||
Whichever style you choose, keep it consistent across the whole file.
|
|
||||||
|
|
||||||
Doxygen supports various commands in comments, such as `@file` and `@param`.
|
|
||||||
These help Doxygen to render specified things differently or to track them for
|
|
||||||
cross referencing. If you want to learn more, take a look at these two links:
|
|
||||||
|
|
||||||
* http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html
|
|
||||||
* http://www.stack.nl/~dimitri/doxygen/manual/commands.html
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
Below are a few examples of documentation from the codebase.
|
|
||||||
|
|
||||||
### Function
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
/**
|
|
||||||
* Removes whitespace characters from the start and from the end of a string.
|
|
||||||
*
|
|
||||||
* @param s String that is going to be trimmed.
|
|
||||||
*
|
|
||||||
* @return Trimmed string.
|
|
||||||
*/
|
|
||||||
inline std::string Trim(const std::string &s);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Class
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
/** Base class for logical operators.
|
|
||||||
*
|
|
||||||
* Each operator describes an operation, which is to be performed on the
|
|
||||||
* database. Operators are iterated over using a @c Cursor. Various operators
|
|
||||||
* can serve as inputs to others and thus a sequence of operations is formed.
|
|
||||||
*/
|
|
||||||
class LogicalOperator
|
|
||||||
: public ::utils::Visitable<HierarchicalLogicalOperatorVisitor> {
|
|
||||||
public:
|
|
||||||
/** Constructs a @c Cursor which is used to run this operator.
|
|
||||||
*
|
|
||||||
* @param GraphDbAccessor Used to perform operations on the database.
|
|
||||||
*/
|
|
||||||
virtual std::unique_ptr<Cursor> MakeCursor(GraphDbAccessor &db) const = 0;
|
|
||||||
|
|
||||||
/** Return @c Symbol vector where the results will be stored.
|
|
||||||
*
|
|
||||||
* Currently, outputs symbols are only generated in @c Produce operator.
|
|
||||||
* @c Skip, @c Limit and @c OrderBy propagate the symbols from @c Produce (if
|
|
||||||
* it exists as input operator). In the future, we may want this method to
|
|
||||||
* return the symbols that will be set in this operator.
|
|
||||||
*
|
|
||||||
* @param SymbolTable used to find symbols for expressions.
|
|
||||||
* @return std::vector<Symbol> used for results.
|
|
||||||
*/
|
|
||||||
virtual std::vector<Symbol> OutputSymbols(const SymbolTable &) const {
|
|
||||||
return std::vector<Symbol>();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~LogicalOperator() {}
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
### File Header
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
/// @file visitor.hpp
|
|
||||||
///
|
|
||||||
/// This file contains the generic implementation of visitor pattern.
|
|
||||||
///
|
|
||||||
/// There are 2 approaches to the pattern:
|
|
||||||
///
|
|
||||||
/// * classic visitor pattern using @c Accept and @c Visit methods, and
|
|
||||||
/// * hierarchical visitor which also uses @c PreVisit and @c PostVisit
|
|
||||||
/// methods.
|
|
||||||
///
|
|
||||||
/// Classic Visitor
|
|
||||||
/// ===============
|
|
||||||
///
|
|
||||||
/// Explanation on the classic visitor pattern can be found from many
|
|
||||||
/// sources, but here is the link to hopefully most easily accessible
|
|
||||||
/// information: https://en.wikipedia.org/wiki/Visitor_pattern
|
|
||||||
///
|
|
||||||
/// The idea behind the generic implementation of classic visitor pattern is to
|
|
||||||
/// allow returning any type via @c Accept and @c Visit methods. Traversing the
|
|
||||||
/// class hierarchy is relegated to the visitor classes. Therefore, visitor
|
|
||||||
/// should call @c Accept on children when visiting their parents. To implement
|
|
||||||
/// such a visitor refer to @c Visitor and @c Visitable classes.
|
|
||||||
///
|
|
||||||
/// Hierarchical Visitor
|
|
||||||
/// ====================
|
|
||||||
///
|
|
||||||
/// Unlike the classic visitor, the intent of this design is to allow the
|
|
||||||
/// visited structure itself to control the traversal. This way the internal
|
|
||||||
/// children structure of classes can remain private. On the other hand,
|
|
||||||
/// visitors may want to differentiate visiting composite types from leaf types.
|
|
||||||
/// Composite types are those which contain visitable children, unlike the leaf
|
|
||||||
/// nodes. Differentiation is accomplished by providing @c PreVisit and @c
|
|
||||||
/// PostVisit methods, which should be called inside @c Accept of composite
|
|
||||||
/// types. Regular @c Visit is only called inside @c Accept of leaf types.
|
|
||||||
/// To implement such a visitor refer to @c CompositeVisitor, @c LeafVisitor and
|
|
||||||
/// @c Visitable classes.
|
|
||||||
///
|
|
||||||
/// Implementation of hierarchical visiting is modelled after:
|
|
||||||
/// http://wiki.c2.com/?HierarchicalVisitorPattern
|
|
||||||
```
|
|
||||||
|
|
||||||
1349
docs/dev/lcp.md
1349
docs/dev/lcp.md
File diff suppressed because it is too large
Load Diff
@@ -1,15 +0,0 @@
|
|||||||
# Other Code Conventions
|
|
||||||
|
|
||||||
While we are mainly programming in C++, we do use other programming languages
|
|
||||||
when appropriate. This chapter describes conventions for such code.
|
|
||||||
|
|
||||||
## Python
|
|
||||||
|
|
||||||
Code written in Python should adhere to
|
|
||||||
[PEP 8](https://www.python.org/dev/peps/pep-0008/). You should run `flake8` on
|
|
||||||
your code to automatically check compliance.
|
|
||||||
|
|
||||||
## Common Lisp
|
|
||||||
|
|
||||||
Code written in Common Lisp should adhere to
|
|
||||||
[Google Common Lisp Style](https://google.github.io/styleguide/lispguide.xml).
|
|
||||||
1
docs/dev/query/.gitignore
vendored
1
docs/dev/query/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
html/
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
# Query Parsing, Planning and Execution
|
|
||||||
|
|
||||||
This part of the documentation deals with query execution.
|
|
||||||
|
|
||||||
Memgraph currently supports only query interpretation. Each new query is
|
|
||||||
parsed, analysed and translated into a sequence of operations which are then
|
|
||||||
executed on the main database storage. Query execution is organized into the
|
|
||||||
following phases:
|
|
||||||
|
|
||||||
1. [Lexical Analysis (Tokenization)](parsing.md)
|
|
||||||
2. [Syntactic Analysis (Parsing)](parsing.md)
|
|
||||||
3. [Semantic Analysis and Symbol Generation](semantic.md)
|
|
||||||
4. [Logical Planning](planning.md)
|
|
||||||
5. [Logical Plan Execution](execution.md)
|
|
||||||
|
|
||||||
The main entry point is `Interpreter::operator()`, which takes a query text
|
|
||||||
string and produces a `Results` object. To instantiate the object,
|
|
||||||
`Interpreter` needs to perform the above steps from 1 to 4. If any of the
|
|
||||||
steps fail, a `QueryException` is thrown. The complete `LogicalPlan` is
|
|
||||||
wrapped into a `CachedPlan` and stored for reuse. This way we can skip the
|
|
||||||
whole process of analysing a query if it appears to be the same as before.
|
|
||||||
|
|
||||||
When we have valid plan, the client code can invoke `Results::PullAll` with a
|
|
||||||
stream object. The `Results` instance will then execute the plan and fill the
|
|
||||||
stream with the obtained results.
|
|
||||||
|
|
||||||
Since we want to optionally run Memgraph as a distributed database, we have
|
|
||||||
hooks for creating a different plan of logical operators.
|
|
||||||
`DistributedInterpreter` inherits from `Interpreter` and overrides
|
|
||||||
`MakeLogicalPlan` method. This method needs to return a concrete instance of
|
|
||||||
`LogicalPlan`, and in case of distributed database that will be
|
|
||||||
`DistributedLogicalPlan`.
|
|
||||||
|
|
||||||

|
|
||||||
@@ -1,373 +0,0 @@
|
|||||||
# Logical Plan Execution
|
|
||||||
|
|
||||||
We implement classical iterator style operators. Logical operators define
|
|
||||||
operations on database. They encapsulate the following info: what the input is
|
|
||||||
(another `LogicalOperator`), what to do with the data, and how to do it.
|
|
||||||
|
|
||||||
Currently logical operators can have zero or more input operations, and thus a
|
|
||||||
`LogicalOperator` tree is formed. Most `LogicalOperator` types have only one
|
|
||||||
input, so we are mostly working with chains instead of full fledged trees.
|
|
||||||
You can find information on each operator in `src/query/plan/operator.lcp`.
|
|
||||||
|
|
||||||
## Cursor
|
|
||||||
|
|
||||||
Logical operators do not perform database work themselves. Instead they create
|
|
||||||
`Cursor` objects that do the actual work, based on the info in the operator.
|
|
||||||
Cursors expose a `Pull` method that gets called by the cursor's consumer. The
|
|
||||||
consumer keeps pulling as long as the `Pull` returns `true` (indicating it
|
|
||||||
successfully performed some work and might be eligible for another `Pull`).
|
|
||||||
Most cursors will call the `Pull` function of their input provided cursor, so
|
|
||||||
typically a cursor chain is created that is analogue to the logical operator
|
|
||||||
chain it's created from.
|
|
||||||
|
|
||||||
## Frame
|
|
||||||
|
|
||||||
The `Frame` object contains all the data of the current `Pull` chain. It
|
|
||||||
serves for communicating data between cursors.
|
|
||||||
|
|
||||||
For example, in a `MATCH (n) RETURN n` query the `ScanAllCursor` places a
|
|
||||||
vertex on the `Frame` for each `Pull`. It places it on the place reserved for
|
|
||||||
the `n` symbol. Then the `ProduceCursor` can take that same value from the
|
|
||||||
`Frame` because it knows the appropriate symbol. `Frame` positions are indexed
|
|
||||||
by `Symbol` objects.
|
|
||||||
|
|
||||||
## ExpressionEvaluator
|
|
||||||
|
|
||||||
Expressions results are not placed on the `Frame` since they do not need to be
|
|
||||||
communicated between different `Cursors`. Instead, expressions are evaluated
|
|
||||||
using an instance of `ExpressionEvaluator`. Since generally speaking an
|
|
||||||
expression can be defined by a tree of subexpressions, the
|
|
||||||
`ExpressionEvaluator` is implemented as a tree visitor. There is a performance
|
|
||||||
sub-optimality here because a stack is used to communicate intermediary
|
|
||||||
expression results between elements of the tree. This is one of the reasons
|
|
||||||
why it's planned to use `Frame` for intermediary expression results as well.
|
|
||||||
The other reason is that it might facilitate compilation later on.
|
|
||||||
|
|
||||||
## Cypher Execution Semantics
|
|
||||||
|
|
||||||
Cypher query execution has *mostly* well-defined semantics. Some are
|
|
||||||
explicitly defined by openCypher and its TCK, while others are implicitly
|
|
||||||
defined by Neo4j's implementation of Cypher that we want to be generally
|
|
||||||
compatible with.
|
|
||||||
|
|
||||||
These semantics can in short be described as follows: a Cypher query consists
|
|
||||||
of multiple clauses some of which modify it. Generally, every clause in the
|
|
||||||
query, when reading it left to right, operates on a consistent state of the
|
|
||||||
property graph, untouched by subsequent clauses. This means that a `MATCH`
|
|
||||||
clause in the beginning operates on a graph-state in which modifications by
|
|
||||||
the subsequent `SET` are not visible.
|
|
||||||
|
|
||||||
The stated semantics feel very natural to the end-user, and Neo seems to
|
|
||||||
implement them well. For Memgraph the situation is complex because
|
|
||||||
`LogicalOperator` execution (through a `Cursor`) happens one `Pull` at a time
|
|
||||||
(generally meaning all the query clauses get executed for every top-level
|
|
||||||
`Pull`). This is not inherently consistent with Cypher semantics because a
|
|
||||||
`SET` clause can modify data, and the `MATCH` clause that precedes it might
|
|
||||||
see the modification in a subsequent `Pull`. Also, the `RETURN` clause might
|
|
||||||
want to stream results to the user before all `SET` clauses have been
|
|
||||||
executed, so the user might see some intermediate graph state. There are many
|
|
||||||
edge-cases that Memgraph does its best to avoid to stay true to Cypher
|
|
||||||
semantics, while at the same time using a high-performance streaming approach.
|
|
||||||
The edge-cases are enumerated in this document along with the implementation
|
|
||||||
details they imply.
|
|
||||||
|
|
||||||
## Implementation Peculiarities
|
|
||||||
|
|
||||||
### Once
|
|
||||||
|
|
||||||
An operator that does nothing but whose `Cursor::Pull` returns `true` on the
|
|
||||||
first `Pull` and `false` on subsequent ones. This operator is used when
|
|
||||||
another operator has an optional input, because in Cypher a clause will
|
|
||||||
typically execute once for every input from the preceding clauses, or just
|
|
||||||
once if there was no preceding input. For example, consider the `CREATE`
|
|
||||||
clause. In the query `CREATE (n)` only one node is created, while in the query
|
|
||||||
`MATCH (n) CREATE (m)` a node is created for each existing node. Thus in our
|
|
||||||
`CreateNode` logical operator the input is either a `ScanAll` operator, or a
|
|
||||||
`Once` operator.
|
|
||||||
|
|
||||||
### storage::View
|
|
||||||
|
|
||||||
In the previous section, [Cypher Execution
|
|
||||||
Semantics](#cypher-execution-semantics), we mentioned how the preceding
|
|
||||||
clauses should not see changes made in subsequent ones. For that reason, some
|
|
||||||
operators take a `storage::View` enum value. This value determines which state of
|
|
||||||
the graph an operator sees.
|
|
||||||
|
|
||||||
Consider the query `MATCH (n)--(m) WHERE n.x = 0 SET m.x = 1`. Naive streaming
|
|
||||||
could match a vertex `n` on the given criteria, expand to `m`, update it's
|
|
||||||
property, and in the next iteration consider the vertex previously matched to
|
|
||||||
`m` and skip it because it's newly set property value does not qualify. This
|
|
||||||
is not how Cypher works. To handle this issue properly, Memgraph designed the
|
|
||||||
`VertexAccessor` class that tracks two versions of data: one that was visible
|
|
||||||
before the current transaction+command, and the optional other that was
|
|
||||||
created in the current transaction+command. The `MATCH` clause will be planned
|
|
||||||
as `ScanAll` and `Expand` operations using `storage::View::OLD` value. This
|
|
||||||
will ensure modifications performed in the same query do not affect it. The
|
|
||||||
same applies to edges and the `EdgeAccessor` class.
|
|
||||||
|
|
||||||
### Existing Record Detection
|
|
||||||
|
|
||||||
It's possible that a pattern element has already been declared in the same
|
|
||||||
pattern, or a preceding pattern. For example `MATCH (n)--(m), (n)--(l)` or a
|
|
||||||
cycle-detection match `MATCH (n)-->(n) RETURN n`. Implementation-wise,
|
|
||||||
existing record detection just checks that the expanded record is equal to the
|
|
||||||
one already on the frame.
|
|
||||||
|
|
||||||
### Why Not Use Separate Expansion Ops for Edges and Vertices?
|
|
||||||
|
|
||||||
Expanding an edge and a vertex in separate ops is not feasible when matching a
|
|
||||||
cycle in bi-directional expansions. Consider the query `MATCH (n)--(n) RETURN
|
|
||||||
n`. Let's try to expand first the edge in one op, and vertex in the next. The
|
|
||||||
vertex expansion consumes the edge expansion input. It takes the expanded edge
|
|
||||||
from the frame. It needs to detect a cycle by comparing the vertex existing on
|
|
||||||
the frame with one of the edge vertices (`from` or `to`). But which one? It
|
|
||||||
doesn't know, and can't ensure correct cycle detection.
|
|
||||||
|
|
||||||
### Data Visibility During and After SET
|
|
||||||
|
|
||||||
In Cypher, setting values always works on the latest version of data (from
|
|
||||||
preceding or current clause). That means that within a `SET` clause all the
|
|
||||||
changes from previous clauses must be visible, as well as changes done by the
|
|
||||||
current `SET` clause. Also, if there is a clause after `SET` it must see *all*
|
|
||||||
the changes performed by the preceding `SET`. Both these things are best
|
|
||||||
illustrated with the following queries executed on an empty database:
|
|
||||||
|
|
||||||
CREATE (n:A {x:0})-[:EdgeType]->(m:B {x:0})
|
|
||||||
MATCH (n)--(m) SET m.x = n.x + 1 RETURN labels(n), n.x, labels(m), m.x
|
|
||||||
|
|
||||||
This returns:
|
|
||||||
|
|
||||||
+---------+---+---------+---+
|
|
||||||
|labels(n)|n.x|labels(m)|m.x|
|
|
||||||
+:=======:+:=:+:=======:+:=:+
|
|
||||||
|[A] |2 |[B] |1 |
|
|
||||||
+---------+---+---------+---+
|
|
||||||
|[B] |1 |[A] |2 |
|
|
||||||
+---------+---+---------+---+
|
|
||||||
|
|
||||||
The obtained result implies the following operations:
|
|
||||||
|
|
||||||
1. In the first iteration set the value of the `B.x` to 1
|
|
||||||
2. In the second iteration the we observe `B.x` with the value of 1 and set
|
|
||||||
`A.x` to 2
|
|
||||||
3. In `RETURN` we see all the changes made in both iterations
|
|
||||||
|
|
||||||
To implement the desired behavior Memgraph utilizes two techniques. First is
|
|
||||||
the already mentioned tracking of two versions of data in vertex accessors.
|
|
||||||
Using this approach ensures that the second iteration in the example query
|
|
||||||
sees the data modification performed by the preceding iteration. The second
|
|
||||||
technique is the `Accumulate` operation that accumulates all the iterations
|
|
||||||
from the preceding logical op before passing them to the next logical op. In
|
|
||||||
the example query, `Accumulate` ensures that the results returned to the user
|
|
||||||
reflect changes performed in all iterations of the query (naive streaming
|
|
||||||
could stream results at the end of first iteration producing inconsistent
|
|
||||||
results). Note that `Accumulate` is demanding regarding memory and slows down
|
|
||||||
query execution. For that reason it should be used only when necessary, for
|
|
||||||
example it does not have to be used in a query that has `MATCH` and `SET` but
|
|
||||||
no `RETURN`.
|
|
||||||
|
|
||||||
### Neo4j Inconsistency on Multiple SET Clauses
|
|
||||||
|
|
||||||
Considering the preceding example it could be expected that when a query has
|
|
||||||
multiple `SET` clauses all the changes from those preceding one are visible.
|
|
||||||
This is not the case in Neo4j's implementation. Consider the following queries
|
|
||||||
executed on an empty database:
|
|
||||||
|
|
||||||
CREATE (n:A {x:0})-[:EdgeType]->(m:B {x:0})
|
|
||||||
MATCH (n)--(m) SET n.x = n.x + 1 SET m.x = m.x * 2
|
|
||||||
RETURN labels(n), n.x, labels(m), m.x
|
|
||||||
|
|
||||||
This returns:
|
|
||||||
|
|
||||||
+---------+---+---------+---+
|
|
||||||
|labels(n)|n.x|labels(m)|m.x|
|
|
||||||
+:=======:+:=:+:=======:+:=:+
|
|
||||||
|[A] |2 |[B] |1 |
|
|
||||||
+---------+---+---------+---+
|
|
||||||
|[B] |1 |[A] |2 |
|
|
||||||
+---------+---+---------+---+
|
|
||||||
|
|
||||||
If all the iterations of the first `SET` clause were executed before executing
|
|
||||||
the second, all the resulting values would be 2. This not being the case, we
|
|
||||||
conclude that Neo4j does not use a barrier-like mechanism between `SET`
|
|
||||||
clauses. It is Memgraph's current vision that this is inconsistent and we
|
|
||||||
plan to reduce Neo4j compliance in favour of operation consistency.
|
|
||||||
|
|
||||||
### Double Deletion
|
|
||||||
|
|
||||||
It's possible to match the same graph element multiple times in a single query
|
|
||||||
and delete it. Neo supports this, and so do we. The relevant implementation
|
|
||||||
detail is in the `GraphDbAccessor` class, where the record deletion functions
|
|
||||||
reside, and not in the logical plan execution. It comes down to checking if a
|
|
||||||
record has already been deleted in the current transaction+command and not
|
|
||||||
attempting to do it again (results in a crash).
|
|
||||||
|
|
||||||
### Set + Delete Edge-case
|
|
||||||
|
|
||||||
It's legal for a query to combine `SET` and `DELETE` clauses. Consider the
|
|
||||||
following queries executed on an empty database:
|
|
||||||
|
|
||||||
|
|
||||||
CREATE ()-[:T]->()
|
|
||||||
MATCH (n)--(m) SET n.x = 42 DETACH DELETE m
|
|
||||||
|
|
||||||
Due to the `MATCH` being undirected the second pull will attempt to set data
|
|
||||||
on a deleted vertex. This is not a legal operation in Memgraph storage
|
|
||||||
implementation. For that reason the logical operator for `SET` must check if
|
|
||||||
the record it's trying to set something on has been deleted by the current
|
|
||||||
transaction+command. If so, the modification is not executed.
|
|
||||||
|
|
||||||
### Deletion Accumulation
|
|
||||||
|
|
||||||
Sometimes it's necessary to accumulate deletions of all the matches before
|
|
||||||
attempting to execute them. Consider this the following. Start with an empty
|
|
||||||
database and execute queries:
|
|
||||||
|
|
||||||
CREATE ()-[:T]->()-[:T]->()
|
|
||||||
MATCH (a)-[r1]-(b)-[r2]-(c) DELETE r1, b, c
|
|
||||||
|
|
||||||
Note that the `DELETE` clause attempts to delete node `c`, but it does not
|
|
||||||
detach it by deleting edge `r2`. However, due to undirected edge in the
|
|
||||||
`MATCH`, both edges get pulled and deleted.
|
|
||||||
|
|
||||||
Currently Memgraph does not support this behavior, Neo does. There are a few
|
|
||||||
ways that we could do this.
|
|
||||||
|
|
||||||
* Accumulate on deletion (that sucks because we have to keep track of
|
|
||||||
everything that gets returned after the deletion).
|
|
||||||
* Maybe we could stream through the deletion op, but defer actual deletion
|
|
||||||
until plan-execution end.
|
|
||||||
* Ignore this because it's very edgy (this is the currently selected option).
|
|
||||||
|
|
||||||
### Aggregation Without Input
|
|
||||||
|
|
||||||
It is necessary to define what aggregation ops return when they receive no
|
|
||||||
input. Following is a table that shows what Neo4j's Cypher implementation and
|
|
||||||
SQL produce.
|
|
||||||
|
|
||||||
|
|
||||||
+-------------+------------------------+---------------------+---------------------+------------------+
|
|
||||||
| \<OP\> | 1. Cypher, no group-by | 2. Cypher, group-by | 3. SQL, no group-by | 4. SQL, group-by |
|
|
||||||
+=============+:======================:+:===================:+:===================:+:================:+
|
|
||||||
| Count(\*) | 0 | \<NO\_ROWS> | 0 | \<NO\_ROWS> |
|
|
||||||
+-------------+------------------------+---------------------+---------------------+------------------+
|
|
||||||
| Count(prop) | 0 | \<NO\_ROWS> | 0 | \<NO\_ROWS> |
|
|
||||||
+-------------+------------------------+---------------------+---------------------+------------------+
|
|
||||||
| Sum | 0 | \<NO\_ROWS> | NULL | \<NO\_ROWS> |
|
|
||||||
+-------------+------------------------+---------------------+---------------------+------------------+
|
|
||||||
| Avg | NULL | \<NO\_ROWS> | NULL | \<NO\_ROWS> |
|
|
||||||
+-------------+------------------------+---------------------+---------------------+------------------+
|
|
||||||
| Min | NULL | \<NO\_ROWS> | NULL | \<NO\_ROWS> |
|
|
||||||
+-------------+------------------------+---------------------+---------------------+------------------+
|
|
||||||
| Max | NULL | \<NO\_ROWS> | NULL | \<NO\_ROWS> |
|
|
||||||
+-------------+------------------------+---------------------+---------------------+------------------+
|
|
||||||
| Collect | [] | \<NO\_ROWS> | N/A | N/A |
|
|
||||||
+-------------+------------------------+---------------------+---------------------+------------------+
|
|
||||||
|
|
||||||
Where:
|
|
||||||
|
|
||||||
1. `MATCH (n) RETURN <OP>(n.prop)`
|
|
||||||
2. `MATCH (n) RETURN <OP>(n.prop), (n.prop2)`
|
|
||||||
3. `SELECT <OP>(prop) FROM Table`
|
|
||||||
4. `SELECT <OP>(prop), prop2 FROM Table GROUP BY prop2`
|
|
||||||
|
|
||||||
Neo's Cypher implementation diverges from SQL only when performing `SUM`.
|
|
||||||
Memgraph implements SQL-like behavior. It is considered that `SUM` of
|
|
||||||
arbitrary elements should not be implicitly 0, especially in a property graph
|
|
||||||
without a strict schema (the property in question can contain values of
|
|
||||||
arbitrary types, or no values at all).
|
|
||||||
|
|
||||||
### OrderBy
|
|
||||||
|
|
||||||
The `OrderBy` logical operator sorts the results in the desired order. It
|
|
||||||
occurs in Cypher as part of a `WITH` or `RETURN` clause. Both the concept and
|
|
||||||
the implementation are straightforward. It's necessary for the logical op to
|
|
||||||
`Pull` everything from its input so it can be sorted. It's not necessary to
|
|
||||||
keep the whole `Frame` state of each input, it is sufficient to keep a list of
|
|
||||||
`TypedValues` on which the results will be sorted, and another list of values
|
|
||||||
that need to be remembered and recreated on the `Frame` when yielding.
|
|
||||||
|
|
||||||
The sorting itself is made to reflect that of Neo's implementation which comes
|
|
||||||
down to these points.
|
|
||||||
|
|
||||||
* `Null` comes last (as if it's greater than anything).
|
|
||||||
* Primitive types compare naturally, with no implicit casting except from
|
|
||||||
`int` to `double`.
|
|
||||||
* Complex types are not comparable.
|
|
||||||
* Every unsupported comparison results in an exception that gets propagated
|
|
||||||
to the end user.
|
|
||||||
|
|
||||||
### Limit in Write Queries
|
|
||||||
|
|
||||||
`Limit` can be used as part of a write query, in which case it will *not*
|
|
||||||
reduce the amount of performed updates. For example, consider a database that
|
|
||||||
has 10 vertices. The query `MATCH (n) SET n.x = 1 RETURN n LIMIT 3` will
|
|
||||||
result in all vertices having their property value changed, while returning
|
|
||||||
only the first to the client. This makes sense from the implementation
|
|
||||||
standpoint, because `Accumulate` is planned after `SetProperty` but before
|
|
||||||
`Produce` and `Limit` operations. Note that this behavior can be
|
|
||||||
non-deterministic in some queries, since it relies on the order of iteration
|
|
||||||
over nodes which is undefined when not explicitly specified.
|
|
||||||
|
|
||||||
### Merge
|
|
||||||
|
|
||||||
`MERGE` in Cypher attempts to match a pattern. If it already exists, it does
|
|
||||||
nothing and subsequent clauses like `RETURN` can use the matched pattern
|
|
||||||
elements. If the pattern can't match to any data, it creates it. For detailed
|
|
||||||
information see Neo4j's [merge
|
|
||||||
documentation.](https://neo4j.com/docs/developer-manual/current/cypher/clauses/merge/)
|
|
||||||
|
|
||||||
An important thing about `MERGE` is visibility of modified data. `MERGE` takes
|
|
||||||
an input (typically a `MATCH`) and has two additional *phases*: the merging
|
|
||||||
part, and the subsequent set parts (`ON MATCH SET` and `ON CREATE SET`).
|
|
||||||
Analysis of Neo4j's behavior indicates that each of these three phases (input,
|
|
||||||
merge, set) does not see changes to the graph state done by subsequent phase.
|
|
||||||
The input phase does not see data created by the merge phase, nor the set
|
|
||||||
phase. This is consistent with what seems like the general Cypher philosophy
|
|
||||||
that query clause effects aren't visible in the preceding clauses.
|
|
||||||
|
|
||||||
We define the `Merge` logical operator as a *routing* operator that uses three
|
|
||||||
logical operator branches.
|
|
||||||
|
|
||||||
1. The input from a preceding clause.
|
|
||||||
|
|
||||||
For example in `MATCH (n), (m) MERGE (n)-[:T]-(m)`. This input is
|
|
||||||
optional because `MERGE` is allowed to be the first clause in a query.
|
|
||||||
|
|
||||||
2. The `merge_match` branch.
|
|
||||||
|
|
||||||
This logical operator branch is `Pull`-ed from until exhausted for each
|
|
||||||
successful `Pull` from the input branch.
|
|
||||||
|
|
||||||
3. The `merge_create` branch.
|
|
||||||
|
|
||||||
This branch is `Pull`ed when the `merge_match` branch does not match
|
|
||||||
anything (no successful `Pull`s) for an input `Pull`. It is `Pull`ed only
|
|
||||||
once in such a situation, since only one creation needs to occur for a
|
|
||||||
failed match.
|
|
||||||
|
|
||||||
The `ON MATCH SET` and `ON CREATE SET` parts of the `MERGE` clause are
|
|
||||||
included in the `merge_match` and `merge_create` branches respectively. They
|
|
||||||
are placed on the end of their branches so that they execute only when those
|
|
||||||
branches succeed.
|
|
||||||
|
|
||||||
Memgraph strives to be consistent with Neo in its `MERGE` implementation,
|
|
||||||
while at the same time keeping performance as good as possible. Consistency
|
|
||||||
with Neo w.r.t. graph state visibility is not trivial. Documentation for
|
|
||||||
`Expand` and `Set` describe how Memgraph keeps track of both the updated
|
|
||||||
version of an edge/vertex and the old one, as it was before the current
|
|
||||||
transaction+command. This technique is also used in `Merge`. The input
|
|
||||||
phase/branch of `Merge` always looks at the old data. The merge phase needs to
|
|
||||||
see the new data so it doesn't create more data then necessary.
|
|
||||||
|
|
||||||
For example, consider the query.
|
|
||||||
|
|
||||||
MATCH (p:Person) MERGE (c:City {name: p.lives_in})
|
|
||||||
|
|
||||||
This query needs to create a city node only once for each unique `p.lives_in`.
|
|
||||||
Finally the set phase of a `MERGE` clause should not affect the merge phase.
|
|
||||||
To achieve this the `merge_match` branch of the `Merge` operator should see
|
|
||||||
the latest created nodes, but filter them on their old state (if those nodes
|
|
||||||
were not created by the `create_branch`). Implementation-wise that means that
|
|
||||||
`ScanAll` and `Expand` operators in the `merge_branch` need to look at the new
|
|
||||||
graph state, while `Filter` operators the old, if available.
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
digraph interpreter {
|
|
||||||
node [fontname="dejavusansmono"]
|
|
||||||
edge [fontname="dejavusansmono"]
|
|
||||||
node [shape=record]
|
|
||||||
edge [dir=back,arrowtail=empty,arrowsize=1.5]
|
|
||||||
Interpreter [label="{\N|+ operator(query : string, ...) : Results\l|
|
|
||||||
# MakeLogicalPlan(...) : LogicalPlan\l|
|
|
||||||
- plan_cache_ : Map(QueryHash, CachedPlan)\l}"]
|
|
||||||
Interpreter -> DistributedInterpreter
|
|
||||||
Results [label="{\N|+ PullAll(stream) : void\l|- plan_ : CachedPlan\l}"]
|
|
||||||
Interpreter -> Results
|
|
||||||
[dir=forward,style=dashed,arrowhead=open,label="<<create>>"]
|
|
||||||
CachedPlan -> Results
|
|
||||||
[dir=forward,arrowhead=odiamond,taillabel="1",headlabel="*"]
|
|
||||||
Interpreter -> CachedPlan [arrowtail=diamond,taillabel="1",headlabel="*"]
|
|
||||||
CachedPlan -> LogicalPlan [arrowtail=diamond]
|
|
||||||
LogicalPlan [label="{\N|+ GetRoot() : LogicalOperator
|
|
||||||
\l+ GetCost() : double\l}"]
|
|
||||||
LogicalPlan -> SingleNodeLogicalPlan [style=dashed]
|
|
||||||
LogicalPlan -> DistributedLogicalPlan [style=dashed]
|
|
||||||
DistributedInterpreter -> DistributedLogicalPlan
|
|
||||||
[dir=forward,style=dashed,arrowhead=open,label="<<create>>"]
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 55 KiB |
@@ -1,62 +0,0 @@
|
|||||||
# Lexical and Syntactic Analysis
|
|
||||||
|
|
||||||
## Antlr
|
|
||||||
|
|
||||||
We use Antlr for lexical and syntax analysis of Cypher queries. Antrl uses
|
|
||||||
grammar file `Cypher.g4` downloaded from http://www.opencypher.org to generate
|
|
||||||
the parser and the visitor for the Cypher parse tree. Even though the provided
|
|
||||||
grammar is not very pleasant to work with we decided not to do any drastic
|
|
||||||
changes to it so that our transition to newly published versions of
|
|
||||||
`Cypher.g4` would be easier. Nevertheless, we had to fix some bugs and add
|
|
||||||
features, so our version is not completely the same.
|
|
||||||
|
|
||||||
In addition to using `Cypher.g4`, we have `MemgraphCypher.g4`. This grammar
|
|
||||||
file defines Memgraph specific extensions to the original grammar. Most
|
|
||||||
notable example is the inclusion of syntax for handling authorization. At the
|
|
||||||
moment, some extensions are also found in `Cypher.g4`. For example, the syntax
|
|
||||||
for using a lambda function in relationship patterns. These extensions should
|
|
||||||
be moved out of `Cypher.g4`, so that it remains as close to the original
|
|
||||||
grammar as possible. Additionally, having `MemgraphCypher.g4` may not be
|
|
||||||
enough if we wish to split the functionality for community and enterprise
|
|
||||||
editions of Memgraph.
|
|
||||||
|
|
||||||
## Abstract Syntax Tree (AST)
|
|
||||||
|
|
||||||
Since Antlr generated visitor and the official openCypher grammar are not very
|
|
||||||
practical to use, we translate the Antlr's AST to our own AST. Currently there
|
|
||||||
are ~40 types of nodes in our AST. Their definitions can be found in
|
|
||||||
`src/query/frontend/ast/ast.lcp`.
|
|
||||||
|
|
||||||
Major groups of types can be found under the following base types.
|
|
||||||
|
|
||||||
* `Expression` --- types corresponding to Cypher expressions.
|
|
||||||
* `Clause` --- types corresponding to Cypher clauses.
|
|
||||||
* `PatternAtom` --- node or edge related information.
|
|
||||||
* `Query` --- different kinds of queries, allows extending the language with
|
|
||||||
Memgraph specific query syntax.
|
|
||||||
|
|
||||||
Memory management of created AST nodes is done with `AstStorage`. Each type
|
|
||||||
must be created by invoking `AstStorage::Create` method. This way all of the
|
|
||||||
pointers to nodes and their children are raw pointers. The only owner of
|
|
||||||
allocated memory is the `AstStorage`. When the storage goes out of scope, the
|
|
||||||
pointers become invalid. It may be more natural to handle tree ownership via
|
|
||||||
`unique_ptr`, i.e. each node owns its children. But there are some benefits to
|
|
||||||
having a custom storage and allocation scheme.
|
|
||||||
|
|
||||||
The primary reason we opted for not using `unique_ptr` is the requirement of
|
|
||||||
Antlr's base visitor class that the resulting values must by copyable. The
|
|
||||||
result is wrapped in `antlr::Any` so that the derived visitor classes may
|
|
||||||
return any type they wish when visiting Antlr's AST. Unfortunately,
|
|
||||||
`antlr::Any` does not work with non-copyable types.
|
|
||||||
|
|
||||||
Another benefit of having `AstStorage` is that we can easily add a different
|
|
||||||
allocation scheme for AST nodes. The interface of node creation would not
|
|
||||||
change.
|
|
||||||
|
|
||||||
### AST Translation
|
|
||||||
|
|
||||||
The translation process is done via `CypherMainVisitor` class, which is
|
|
||||||
derived from Antlr generated visitor. Besides instancing our AST types, a
|
|
||||||
minimal number of syntactic checks are done on a query. These checks handle
|
|
||||||
the cases which were valid in original openCypher grammar, but may be invalid
|
|
||||||
when combined with other syntax elements.
|
|
||||||
@@ -1,526 +0,0 @@
|
|||||||
# Logical Planning
|
|
||||||
|
|
||||||
After the semantic analysis and symbol generation, the AST is converted to a
|
|
||||||
tree of logical operators. This conversion is called *planning* and the tree
|
|
||||||
of logical operators is called a *plan*. The whole planning process is done in
|
|
||||||
the following steps.
|
|
||||||
|
|
||||||
1. [AST Preprocessing](#ast-preprocessing)
|
|
||||||
|
|
||||||
The first step is to preprocess the AST by collecting
|
|
||||||
information on filters, divide the query into parts, normalize patterns
|
|
||||||
in `MATCH` clauses, etc.
|
|
||||||
|
|
||||||
2. [Logical Operator Planning](#logical-operator-planning)
|
|
||||||
|
|
||||||
After the preprocess step, the planning can be done via 2 planners:
|
|
||||||
`VariableStartPlanner` and `RuleBasedPlanner`. The first planner will
|
|
||||||
generate multiple plans where each plan has different starting points for
|
|
||||||
searching the patterns in `MATCH` clauses. The second planner produces a
|
|
||||||
single plan by mapping the query parts as they are to logical operators.
|
|
||||||
|
|
||||||
3. [Logical Plan Postprocessing](#logical-plan-postprocessing)
|
|
||||||
|
|
||||||
In this stage, we perform various transformations on the generated logical
|
|
||||||
plan. Here we want to optimize the operations in order to improve
|
|
||||||
performance during the execution. Naturally, transformations need to
|
|
||||||
preserve the semantic behaviour of the original plan.
|
|
||||||
|
|
||||||
4. [Cost Estimation](#cost-estimation)
|
|
||||||
|
|
||||||
After the generation, the execution cost of each plan is estimated. This
|
|
||||||
estimation is used to select the best plan which will be executed.
|
|
||||||
|
|
||||||
The implementation can be found in the `query/plan` directory, with the public
|
|
||||||
entry point being `query/plan/planner.hpp`.
|
|
||||||
|
|
||||||
## AST Preprocessing
|
|
||||||
|
|
||||||
Each openCypher query consists of at least 1 **single query**. Multiple single
|
|
||||||
queries are chained together using a **query combinator**. Currently, there is
|
|
||||||
only one combinator, `UNION`. The preprocessing step starts in the
|
|
||||||
`CollectQueryParts` function. This function will take a look at each single
|
|
||||||
query and divide it into parts. Each part is separated with `RETURN` and
|
|
||||||
`WITH` clauses. For example:
|
|
||||||
|
|
||||||
MATCH (n) CREATE (m) WITH m MATCH (l)-[]-(m) RETURN l
|
|
||||||
| | |
|
|
||||||
|------- part 1 -----------+-------- part 2 --------|
|
|
||||||
| |
|
|
||||||
|-------------------- single query -----------------|
|
|
||||||
|
|
||||||
Each part is created by collecting all `MATCH` clauses and *normalizing* their
|
|
||||||
patterns. Pattern normalization is the process of converting an arbitrarily
|
|
||||||
long pattern chain of nodes and edges into a list of triplets `(start node,
|
|
||||||
edge, end node)`. The triplets should preserve the semantics of the match. For
|
|
||||||
example:
|
|
||||||
|
|
||||||
MATCH (a)-[p]-(b)-[q]-(c)-[r]-(d)
|
|
||||||
|
|
||||||
is equivalent to:
|
|
||||||
|
|
||||||
MATCH (a)-[p]-(b), (b)-[q]-(c), (c)-[r]-(d)
|
|
||||||
|
|
||||||
With this representation, it becomes easier to reorder the triplets and choose
|
|
||||||
different strategies for pattern matching.
|
|
||||||
|
|
||||||
In addition to normalizing patterns, all of the filter expressions in patterns
|
|
||||||
and inside of the `WHERE` clause (of the accompanying `MATCH`) are extracted
|
|
||||||
and stored separately. During the extraction, symbols used in the filter
|
|
||||||
expression are collected. This allows for planning filters in a valid order,
|
|
||||||
as the matching for triplets is being done. Another important benefit of
|
|
||||||
having extra information on filters, is to recognize when a database index
|
|
||||||
could be used.
|
|
||||||
|
|
||||||
After each `MATCH` is processed, they are all grouped, so that even the whole
|
|
||||||
`MATCH` clauses may be reordered. The important thing is to remember which
|
|
||||||
symbols were used to name edges in each `MATCH`. With those symbols we can
|
|
||||||
plan for *cyphermorphism*, i.e. ensure different edges in the search pattern
|
|
||||||
of a single `MATCH` map to different edges in the graph. This preserves the
|
|
||||||
semantic of the query, even though we may have reordered the matching. The
|
|
||||||
same steps are done for `OPTIONAL MATCH`.
|
|
||||||
|
|
||||||
Another clause which needs processing is `MERGE`. Here we normalize the
|
|
||||||
pattern, since the `MERGE` is a bit like `MATCH` and `CREATE` in one.
|
|
||||||
|
|
||||||
All the other clauses are left as is.
|
|
||||||
|
|
||||||
In the end, each query part consists of:
|
|
||||||
|
|
||||||
* processed and grouped `MATCH` clauses;
|
|
||||||
* processed and grouped `OPTIONAL MATCH` clauses;
|
|
||||||
* processed `MERGE` matching pattern and
|
|
||||||
* unchanged remaining clauses.
|
|
||||||
|
|
||||||
The last stored clause is guaranteed to be either `WITH` or `RETURN`.
|
|
||||||
|
|
||||||
## Logical Operator Planning
|
|
||||||
|
|
||||||
### Variable Start Planner
|
|
||||||
|
|
||||||
The `VariableStartPlanner` generates multiple plans for a single query. Each
|
|
||||||
plan is generated by selecting a different starting point for pattern
|
|
||||||
matching.
|
|
||||||
|
|
||||||
The algorithm works as follows.
|
|
||||||
|
|
||||||
1. For each query part:
|
|
||||||
1. For each node in triplets of collected `MATCH` clauses:
|
|
||||||
i. Add the node to a set of `expanded` nodes
|
|
||||||
ii. Select a triplet `(start node, edge, end node)` whose `start node` is
|
|
||||||
in the `expanded` set
|
|
||||||
iii. If no triplet was selected, choose a new starting node that isn't in
|
|
||||||
`expanded` and continue expanding
|
|
||||||
iv. Repeat steps ii. -- iii. until all triplets have been selected
|
|
||||||
and store that as a variation of the `MATCH` clauses
|
|
||||||
2. Do step 1.1. for `OPTIONAL MATCH` and `MERGE` clauses
|
|
||||||
3. Take all combinations of the generated `MATCH`, `OPTIONAL MATCH` and
|
|
||||||
`MERGE` and store them as variations of the query part.
|
|
||||||
2. For each combination of query part variations:
|
|
||||||
1. Generate a plan using the rule based planner
|
|
||||||
|
|
||||||
### Rule Based Planner
|
|
||||||
|
|
||||||
The `RuleBasedPlanner` generates a single plan for a single query. A plan is
|
|
||||||
generated by following hardcoded rules for producing logical operators. The
|
|
||||||
following sections are an overview on how each openCypher clause is converted
|
|
||||||
to a `LogicalOperator`.
|
|
||||||
|
|
||||||
#### MATCH
|
|
||||||
|
|
||||||
`MATCH` clause is used to specify which patterns need to be searched for in
|
|
||||||
the database. These patterns are normalized in the preprocess step to be
|
|
||||||
represented as triplets `(start node, edge, end node)`. When there is no edge,
|
|
||||||
then the triplet is reduced only to the `start node`. Generating the operators
|
|
||||||
is done by looping over these triplets.
|
|
||||||
|
|
||||||
##### Searching for Nodes
|
|
||||||
|
|
||||||
The simplest search is finding standalone nodes. For example, `MATCH (n)`
|
|
||||||
will find all the nodes in the graph. This is accomplished by generating a
|
|
||||||
`ScanAll` operator and forwarding the node symbol which should store the
|
|
||||||
results. In this case, all the nodes will be referenced by `n`.
|
|
||||||
|
|
||||||
Multiple nodes can be specified in a single match, e.g. `MATCH (n), (m)`.
|
|
||||||
Planning is done by repeating the same steps for each sub pattern (separated
|
|
||||||
by a comma). In this case, we would get 2 `ScanAll` operators chained one
|
|
||||||
after the other. An optimization can be obtained if the node in the pattern is
|
|
||||||
already searched for. In `MATCH (n), (n)` we can drop the second `ScanAll`
|
|
||||||
operator since we have already generated it for the first node.
|
|
||||||
|
|
||||||
##### Searching for Relationships
|
|
||||||
|
|
||||||
A more advanced search includes finding nodes with relationships. For example,
|
|
||||||
`MATCH (n)-[r]-(m)` should find every pair of connected nodes in the database.
|
|
||||||
This means, that if a single node has multiple connections, it will be
|
|
||||||
repeated for each combination of pairs. The generation of operators starts
|
|
||||||
from the first node in the pattern. If we are referencing a new starting node,
|
|
||||||
we need to generate a `ScanAll` which finds all the nodes and stores them
|
|
||||||
into `n`. Then, we generate an `Expand` operator which reads the `n` and
|
|
||||||
traverses all the edges of that node. The edge is stored into `r`, while the
|
|
||||||
destination node is stored in `m`.
|
|
||||||
|
|
||||||
Matching multiple relationships proceeds similarly, by repeating the same
|
|
||||||
steps. The only difference is that we need to ensure different edges in the
|
|
||||||
search pattern, map to different edges in the graph. This means that after each
|
|
||||||
`Expand` operator, we need to generate an `EdgeUniquenessFilter`. We provide
|
|
||||||
this operator with a list of symbols for the previously matched edges and the
|
|
||||||
symbol for the current edge.
|
|
||||||
|
|
||||||
For example.
|
|
||||||
|
|
||||||
MATCH (n)-[r1]-(m)-[r2]-(l)
|
|
||||||
|
|
||||||
The above is preprocessed into
|
|
||||||
|
|
||||||
MATCH (n)-[r1]-(m), (m)-[r2]-(l)
|
|
||||||
|
|
||||||
Then we look at each triplet in order and perform the described steps. This
|
|
||||||
way, we would generate:
|
|
||||||
|
|
||||||
ScanAll (n) > Expand (n, r1, m) > Expand (m, r2, l) >
|
|
||||||
EdgeUniquenessFilter ([r1], r2)
|
|
||||||
|
|
||||||
Note that we don't need to make `EdgeUniquenessFilter` after the first
|
|
||||||
`Expand`, since there are no edges to compare to. This filtering needs to work
|
|
||||||
across multiple pattern, but inside a *single* `MATCH` clause.
|
|
||||||
|
|
||||||
Let's take a look at the following.
|
|
||||||
|
|
||||||
MATCH (n)-[r1]-(m), (m)-[r2]-(l)
|
|
||||||
|
|
||||||
We would also generate the exact same operators.
|
|
||||||
|
|
||||||
ScanAll (n) > Expand (n, r1, m) > Expand (m, r2, l) >
|
|
||||||
EdgeUniquenessFilter ([r1], r2)
|
|
||||||
|
|
||||||
On the other hand,
|
|
||||||
|
|
||||||
MATCH (n)-[r1]-(m) MATCH (m)-[r2]-(l)-[r3]-(i)
|
|
||||||
|
|
||||||
would reset the uniqueness filtering at the start of the second match. This
|
|
||||||
would mean that we output the following:
|
|
||||||
|
|
||||||
ScanAll (n) > Expand (n, r1, m) > Expand (m, r2, l) > Expand (l, r3, i) >
|
|
||||||
EdgeUniquenessFilter ([r2], r3)
|
|
||||||
|
|
||||||
There is a difference in how we handle edge uniqueness compared to Neo4j.
|
|
||||||
Neo4j does not allow searching for a single edge multiple times, but we've
|
|
||||||
decided to support that.
|
|
||||||
|
|
||||||
For example, the user can say the following.
|
|
||||||
|
|
||||||
MATCH (n)-[r]-(m)-[r]-l
|
|
||||||
|
|
||||||
We would ensure that both `r` variables match to the same edge. In our
|
|
||||||
terminology, we call this the *edge cycle*. For the above example, we would
|
|
||||||
generate this plan.
|
|
||||||
|
|
||||||
ScanAll (n) > Expand (n, r, m) > Expand (m, r, l)
|
|
||||||
|
|
||||||
We do not put an `EdgeUniquenessFilter` operator between 2 `Expand`
|
|
||||||
operators and we tell the 2nd `Expand` that it is an edge cycle. This, 2nd
|
|
||||||
`Expand` will ensure we have matched both the same edges.
|
|
||||||
|
|
||||||
##### Filtering
|
|
||||||
|
|
||||||
To narrow the search down, the patterns in `MATCH` can have filtered labels
|
|
||||||
and properties. A more general filtering is done using the accompanying
|
|
||||||
`WHERE` clause. During the preprocess step, all filters are collected and
|
|
||||||
extracted into expressions. Additional information on which symbols are used
|
|
||||||
is also stored. This way, each time we generate a `ScanAll` or `Expand`, we
|
|
||||||
look at all the filters to see if any of them can be used. I.e. if the symbols
|
|
||||||
they use have been bound by a newly produced operator. If a filter expression
|
|
||||||
can be used, we immediately add a `Filter` operator with that expression.
|
|
||||||
|
|
||||||
For example.
|
|
||||||
|
|
||||||
MATCH (n)-[r]-(m :label) WHERE n.prop = 42
|
|
||||||
|
|
||||||
We would produce:
|
|
||||||
|
|
||||||
ScanAll (n) > Filter (n.prop) > Expand (n, r, m) > Filter (m :label)
|
|
||||||
|
|
||||||
This means that the same plan is generated for the query:
|
|
||||||
|
|
||||||
MATCH (n {prop: 42})-[r]-(m :label)
|
|
||||||
|
|
||||||
#### OPTIONAL
|
|
||||||
|
|
||||||
If a `MATCH` clause is preceded by `OPTIONAL`, then we need to generate a plan
|
|
||||||
such that we produce results even if we fail to match anything. This is
|
|
||||||
accomplished by generating an `Optional` operator, which takes 2 operator
|
|
||||||
trees:
|
|
||||||
|
|
||||||
* input operation and
|
|
||||||
* optional operation.
|
|
||||||
|
|
||||||
The input is the operation we generated for the part of the query before
|
|
||||||
`OPTIONAL MATCH`. For the optional operation, we simply generate the `OPTIONAL
|
|
||||||
MATCH` part just like we would for regular `MATCH`. In addition to operations,
|
|
||||||
we need to send the symbols which are set during optional matching to the
|
|
||||||
`Optional` operator. The operator will reset values of those symbols to
|
|
||||||
`null`, when the optional part fails to match.
|
|
||||||
|
|
||||||
#### RETURN & WITH
|
|
||||||
|
|
||||||
`RETURN` and `WITH` clauses are very similar to each other. The only
|
|
||||||
difference is that `WITH` separates parts of the query and can be paired with
|
|
||||||
`WHERE` clause.
|
|
||||||
|
|
||||||
The common part is generating operators for the body of the clause. Separation
|
|
||||||
of query parts is mostly done in semantic analysis, which checks that only the
|
|
||||||
symbols exposed through `WITH` are visible in the query parts after the
|
|
||||||
clause. The minor part is done in planning.
|
|
||||||
|
|
||||||
##### Named Results
|
|
||||||
|
|
||||||
Both clauses contain multiple named expressions (`expr AS name`) which are
|
|
||||||
used to generate `Produce` operator.
|
|
||||||
|
|
||||||
##### Aggregations
|
|
||||||
|
|
||||||
If an expression contains an aggregation operator (`sum`, `avg`, ...) we need
|
|
||||||
to plan the `Aggregate` operator as input to `Produce`. This case is more
|
|
||||||
complex, because aggregation in openCypher can perform implicit grouping of
|
|
||||||
results used for aggregation.
|
|
||||||
|
|
||||||
For example, `WITH/RETURN sum(n.x) AS s, n.y AS group` will implicitly group
|
|
||||||
by `n.y` expression.
|
|
||||||
|
|
||||||
Another, obscure grouping can be achieved with `RETURN sum(n.a) + n.b AS s`.
|
|
||||||
Here, the `n.b` will be used for grouping, even though both the `sum` and
|
|
||||||
`n.b` are in the same named expression.
|
|
||||||
|
|
||||||
Therefore, we need to collect all expressions which do not contain
|
|
||||||
aggregations and use them for grouping. You may have noticed that in the last
|
|
||||||
example `sum` is actually a sub-expression of `+`. `Aggregate` operator does
|
|
||||||
not see that (nor it should), so the responsibility of evaluating that falls
|
|
||||||
on `Produce`. One way is for `Aggregate` to store results of grouping
|
|
||||||
expressions on the frame in addition to aggregation results. Unfortunately,
|
|
||||||
this would require rewiring named expressions in `Produce` to reference
|
|
||||||
already evaluated expressions. In the current implementation, we opted for
|
|
||||||
`Aggregate` to store only aggregation results on the frame, while `Produce`
|
|
||||||
will re-evaluate all the other (grouping) expressions. To handle that, symbols
|
|
||||||
which are used in expressions are passed to `Aggregate`, so that they can be
|
|
||||||
remembered. `Produce` will read those symbols from the frame and use it to
|
|
||||||
re-evaluate the needed expressions.
|
|
||||||
|
|
||||||
##### Accumulation
|
|
||||||
|
|
||||||
After we have `Produce` and potentially `Aggregate`, we need to handle a
|
|
||||||
special case when the part of the query before `RETURN` or `WITH` performs
|
|
||||||
updates. For that, we want to run that part of the query fully, so that we get
|
|
||||||
the latest results. This is accomplished by adding `Accumulate` operator as
|
|
||||||
input to `Aggregate` or `Produce` (if there is no aggregation). Accumulation
|
|
||||||
will store all the values for all the used symbols inside `RETURN` and `WITH`,
|
|
||||||
so that they can be used in the operator which follows. This way, only parts
|
|
||||||
of the frame are copied, instead of the whole frame. Here is a minor
|
|
||||||
difference between planning `WITH`, compared to `RETURN`. Since `WITH` can
|
|
||||||
separate writing from reading, we need to advance the transaction command.
|
|
||||||
This enables the later, read parts of the query to obtain the newest changes.
|
|
||||||
This is supported by passing `advance_command` flag to `Accumulate` operator.
|
|
||||||
|
|
||||||
In the simplest case, common to both clauses, we have `Accumulate > Aggregate
|
|
||||||
> Produce` operators, where `Accumulate` and `Aggregate` may be left out.
|
|
||||||
|
|
||||||
##### Ordering
|
|
||||||
|
|
||||||
Planning `ORDER BY` is simple enough. Since it may see new symbols (filled in
|
|
||||||
`Produce`), we add the `OrderBy` operator at the end. The operator will change
|
|
||||||
the order of produced results, so we pass it the ordering expressions and the
|
|
||||||
output symbols of named expressions.
|
|
||||||
|
|
||||||
##### Filtering
|
|
||||||
|
|
||||||
A final difference in `WITH`, is when it contains a `WHERE` clause. For that,
|
|
||||||
we simply generate the `Filter` operator, appended after `Produce` or
|
|
||||||
`OrderBy` (depending which operator is last).
|
|
||||||
|
|
||||||
##### Skipping and Limiting
|
|
||||||
|
|
||||||
If we have `SKIP` or `LIMIT`, we generate `Skip` or `Limit` operators,
|
|
||||||
respectively. These operators are put at the end of the clause.
|
|
||||||
|
|
||||||
This placement may have some unexpected behaviour when combined with
|
|
||||||
operations that update the graph. For example.
|
|
||||||
|
|
||||||
MATCH (n) SET n.x = n.x + 1 RETURN n LIMIT 1
|
|
||||||
|
|
||||||
The above query may be interpreted as if the `SET` will be done only once.
|
|
||||||
Since this is a write query, we need to accumulate results, so the part before
|
|
||||||
`RETURN` will execute completely. The accumulated results will be yielded up
|
|
||||||
to the given limit, and the user would get only the first `n` that was
|
|
||||||
updated. This may confuse the user because in reality, every node in the
|
|
||||||
database had been updated.
|
|
||||||
|
|
||||||
Note that `Skip` always comes before `Limit`. In the current implementation,
|
|
||||||
they are generated directly one after the other.
|
|
||||||
|
|
||||||
#### CREATE
|
|
||||||
|
|
||||||
`CREATE` clause is used to create nodes and edges (relationships).
|
|
||||||
|
|
||||||
For multiple `CREATE` clauses or multiple creation patterns in a single
|
|
||||||
clause, we perform the same, following steps.
|
|
||||||
|
|
||||||
##### Creating a Single Node
|
|
||||||
|
|
||||||
A node is created by simply specifying a node pattern.
|
|
||||||
|
|
||||||
For example `CREATE (n :label {property: "value"}), ()` would create 2 nodes.
|
|
||||||
The 1st one would be created with a label and a property. This node could be
|
|
||||||
referenced later in the query, by using the variable `n`. The 2nd node cannot
|
|
||||||
be referenced and it would be created without any labels nor properties. For
|
|
||||||
node creation, we generate a `CreateNode` operator and pass it all the details
|
|
||||||
of node creation: variable symbol, labels and properties. In the mentioned
|
|
||||||
example, we would have `CreateNode > CreateNode`.
|
|
||||||
|
|
||||||
##### Creating a Relationship
|
|
||||||
|
|
||||||
To create a relationship, the `CREATE` clause must contain a pattern with a
|
|
||||||
directed edge. Compared to creating a single node, this case is a bit more
|
|
||||||
complicated, because either side of the edge may not exist. By exist, we mean
|
|
||||||
that the endpoint is a variable which already references a node.
|
|
||||||
|
|
||||||
For example, `MATCH (n) CREATE (n)-[r]->(m)` would create an edge `r` and a
|
|
||||||
node `m` for each matched node `n`. If we focus on the `CREATE` part, we
|
|
||||||
generate `CreateExpand (n, r, m)` where `n` already exists (refers to matched
|
|
||||||
node) and `m` would be newly created along with edge `r`. If we had only
|
|
||||||
`CREATE (n)-[r]->(m)`, then we would need to create both nodes of the edge
|
|
||||||
`r`. This is done by generating `CreateNode (n) > CreateExpand(n, r, m)`. The
|
|
||||||
final case is when both endpoints refer to an existing node. For example, when
|
|
||||||
adding a node with a cyclical connection `CREATE (n)-[r]->(n)`. In this case,
|
|
||||||
we would generate `CreateNode (n) > CreateExpand (n, r, n)`. We would tell
|
|
||||||
`CreateExpand` to only create the edge `r` between the already created `n`.
|
|
||||||
|
|
||||||
#### MERGE
|
|
||||||
|
|
||||||
Although the merge operation is complex, planning turns out to be relatively
|
|
||||||
simple. The pattern inside the `MERGE` clause is used for both matching and
|
|
||||||
creating. Therefore, we create 2 operator trees, one for each action.
|
|
||||||
|
|
||||||
For example.
|
|
||||||
|
|
||||||
MERGE (n)-[r:r]-(m)
|
|
||||||
|
|
||||||
We would generate a single `Merge` operator which has the following.
|
|
||||||
|
|
||||||
* No input operation (since it is not preceded by any other clause).
|
|
||||||
|
|
||||||
* On match operation
|
|
||||||
|
|
||||||
`ScanAll (n) > Expand (n, r, m) > Filter (r)`
|
|
||||||
|
|
||||||
* On create operation
|
|
||||||
|
|
||||||
`CreateNode (n) > CreateExpand (n, r, m)`
|
|
||||||
|
|
||||||
In cases when `MERGE` contains `ON MATCH` and `ON CREATE` parts, we simply
|
|
||||||
append their operations to the respective operator trees.
|
|
||||||
|
|
||||||
Observe the following example.
|
|
||||||
|
|
||||||
MERGE (n)-[r:r]-(m) ON MATCH SET n.x = 42 ON CREATE SET m :label
|
|
||||||
|
|
||||||
The `Merge` would be generated with the following.
|
|
||||||
|
|
||||||
* No input operation (again, since there is no clause preceding it).
|
|
||||||
|
|
||||||
* On match operation
|
|
||||||
|
|
||||||
`ScanAll (n) > Expand (n, r, m) > Filter (r) > SetProperty (n.x, 42)`
|
|
||||||
|
|
||||||
* On create operation
|
|
||||||
|
|
||||||
`CreateNode (n) > CreateExpand (n, r, m) > SetLabels (n, :label)`
|
|
||||||
|
|
||||||
When we have preceding clauses, we simply put their operator as input to
|
|
||||||
`Merge`.
|
|
||||||
|
|
||||||
MATCH (n) MERGE (n)-[r:r]-(m)
|
|
||||||
|
|
||||||
The above would be generated as
|
|
||||||
|
|
||||||
ScanAll (n) > Merge (on_match_operation, on_create_operation)
|
|
||||||
|
|
||||||
Here we need to be careful to recognize which symbols are already declared.
|
|
||||||
But, since the `on_match_operation` uses the same algorithm for generating a
|
|
||||||
`Match`, that problem is handled there. The same should hold for
|
|
||||||
`on_create_operation`, which uses the process of generating a `Create`. So,
|
|
||||||
finally for this example, the `Merge` would have:
|
|
||||||
|
|
||||||
* Input operation
|
|
||||||
|
|
||||||
`ScanAll (n)`
|
|
||||||
|
|
||||||
* On match operation
|
|
||||||
|
|
||||||
`Expand (n, r, m) > Filter (r)`
|
|
||||||
|
|
||||||
Note that `ScanAll` is not needed since we get the nodes from input.
|
|
||||||
|
|
||||||
* On create operation
|
|
||||||
|
|
||||||
`CreateExpand (n, r, m)`
|
|
||||||
|
|
||||||
Note that `CreateNode` is dropped, since we want to expand the existing one.
|
|
||||||
|
|
||||||
## Logical Plan Postprocessing
|
|
||||||
|
|
||||||
Postprocessing of a logical plan is done by rewriting the original plan into
|
|
||||||
a more efficient one while preserving the original semantic of operations.
|
|
||||||
The rewriters are found in `query/plan/rewrite` directory, and currently we
|
|
||||||
only have one -- `IndexLookupRewriter`.
|
|
||||||
|
|
||||||
### IndexLookupRewriter
|
|
||||||
|
|
||||||
The job of this rewriter is to merge `Filter` and `ScanAll` operations into
|
|
||||||
equivalent `ScanAllBy<Index>` operations. In almost all cases using indexed
|
|
||||||
lookup will be faster than regular lookup, so `IndexLookupRewriter` simply
|
|
||||||
does the transformations whenever possible. The simplest case being the
|
|
||||||
following, assuming we have an index over `id`.
|
|
||||||
|
|
||||||
* Original Plan
|
|
||||||
|
|
||||||
`ScanAll (n) > Filter (id(n) == 42) > Produce (n)`
|
|
||||||
|
|
||||||
* Rewritten Plan
|
|
||||||
|
|
||||||
`ScanAllById (n, id=42) > Produce (n)`
|
|
||||||
|
|
||||||
Naturally, there are some cases we need to be careful about.
|
|
||||||
|
|
||||||
1. Operators with Multiple Branches
|
|
||||||
|
|
||||||
Here we may not carry `Filter` operations outside of the operator into
|
|
||||||
its branches, so the branches are rewritten as stand alone plans with a
|
|
||||||
branch new `IndexLookupRewriter`. Some of the operators with multiple
|
|
||||||
branches are `Merge`, `Optional`, `Cartesian` and `Union`.
|
|
||||||
|
|
||||||
2. Expand Operators
|
|
||||||
|
|
||||||
Expand operations aren't that tricky to handle, but they have a special
|
|
||||||
case where we want to use an indexed lookup of the destination so that the
|
|
||||||
expansion is performed between known nodes. This decision may depend on
|
|
||||||
various parameters which may need further tweaking as we encounter more
|
|
||||||
use-cases of Cypher queries.
|
|
||||||
|
|
||||||
## Cost Estimation
|
|
||||||
|
|
||||||
Cost estimation is the final step of processing a logical plan. The
|
|
||||||
implementation can be found in `query/plan/cost_estimator.hpp`. We give each
|
|
||||||
operator a cost based on the estimated cardinality of results of that operator
|
|
||||||
and on the preset coefficient of the runtime performance of that operator.
|
|
||||||
|
|
||||||
This scheme is rather simple and works quite well, but there are couple of
|
|
||||||
improvements we may want to do at some point.
|
|
||||||
|
|
||||||
* Track more information about the stored graph and use that to improve the
|
|
||||||
estimates.
|
|
||||||
* Do a quick, partial run of the plan and tweak the estimation based on how
|
|
||||||
much each operator produced results. This may require us having some kind
|
|
||||||
of representative subset of the stored graph.
|
|
||||||
* Write micro benchmarks for each operator and based on the results create
|
|
||||||
sensible preset coefficients. This would replace the current coefficients
|
|
||||||
which are just assumptions on how each operator implementation performs.
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
# Semantic Analysis and Symbol Generation
|
|
||||||
|
|
||||||
In this phase, various semantic and variable type checks are performed.
|
|
||||||
Additionally, we generate symbols which map AST nodes to stored values
|
|
||||||
computed from evaluated expressions.
|
|
||||||
|
|
||||||
## Symbol Generation
|
|
||||||
|
|
||||||
Implementation can be found in `query/frontend/semantic/symbol_generator.cpp`.
|
|
||||||
|
|
||||||
Symbols are generated for each AST node that represents data that needs to
|
|
||||||
have storage. Currently, these are:
|
|
||||||
|
|
||||||
* `NamedExpression`
|
|
||||||
* `CypherUnion`
|
|
||||||
* `Identifier`
|
|
||||||
* `Aggregation`
|
|
||||||
|
|
||||||
You may notice that the above AST nodes may not correspond to something named
|
|
||||||
by a user. For example, `Aggregation` can be a part of larger expression and
|
|
||||||
thus remain unnamed. The reason we still generate symbols is to have a uniform
|
|
||||||
behaviour when executing a query as well as allow for caching the results of
|
|
||||||
expression evaluation.
|
|
||||||
|
|
||||||
AST nodes do not actually store a `Symbol` instance, instead they have a
|
|
||||||
`int32_t` index identifying the symbol in the `SymbolTable` class. This is
|
|
||||||
done to minimize the size of AST types as well as allow easier sharing of same
|
|
||||||
symbols with multiple instances of AST nodes.
|
|
||||||
|
|
||||||
The storage for evaluated data is represented by the `Frame` class. Each
|
|
||||||
symbol determines a unique position in the frame. During interpretation,
|
|
||||||
evaluation of expressions which have a symbol will either read or store values
|
|
||||||
in the frame. For example, instance of an `Identifier` will use the symbol to
|
|
||||||
find and read the value from `Frame`. On the other hand, `NamedExpression`
|
|
||||||
will take the result of evaluating its own expression and store it in the
|
|
||||||
`Frame`.
|
|
||||||
|
|
||||||
When a symbol is created, context of creation is used to assign a type to that
|
|
||||||
symbol. This type is used for simple type checking operations. For example,
|
|
||||||
`MATCH (n)` will create a symbol for variable `n`. Since the `MATCH (n)`
|
|
||||||
represents finding a vertex in the graph, we can set `Symbol::Type::Vertex`
|
|
||||||
for that symbol. Later, for example in `MATCH ()-[n]-()` we see that variable
|
|
||||||
`n` is used as an edge. Since we already have a symbol for that variable, we
|
|
||||||
detect this type mismatch and raise a `SemanticException`.
|
|
||||||
|
|
||||||
Basic rule of symbol generation, is that variables inside `MATCH`, `CREATE`,
|
|
||||||
`MERGE`, `WITH ... AS` and `RETURN ... AS` clauses establish new symbols.
|
|
||||||
|
|
||||||
### Symbols in Patterns
|
|
||||||
|
|
||||||
Inside `MATCH`, symbols are created only if they didn't exist before. For
|
|
||||||
example, patterns in `MATCH (n {a: 5})--(m {b: 5}) RETURN n, m` will create 2
|
|
||||||
symbols: one for `n` and one for `m`. `RETURN` clause will, in turn, reference
|
|
||||||
those symbols. Symbols established in a part of pattern are immediately bound
|
|
||||||
and visible in later parts. For example, `MATCH (n)--(n)` will create a symbol
|
|
||||||
for variable `n` for 1st `(n)`. That symbol is referenced in 2nd `(n)`. Note
|
|
||||||
that the symbol is not bound inside 1st `(n)` itself. What this means is that,
|
|
||||||
for example, `MATCH (n {a: n.b})` should raise an error, because `n` is not
|
|
||||||
yet bound when encountering `n.b`. On the other hand,
|
|
||||||
`MATCH (n)--(n {a: n.b})` is fine.
|
|
||||||
|
|
||||||
The `CREATE` is similar to `MATCH`, but it *always* establishes symbols for
|
|
||||||
variables which create graph elements. What this means is that, for example
|
|
||||||
`MATCH (n) CREATE (n)` is not allowed. `CREATE` wants to create a new node,
|
|
||||||
for which we already have a symbol. In such a case, we need to throw an error
|
|
||||||
that the variable `n` is being redeclared. On the other hand `MATCH (n) CREATE
|
|
||||||
(n)-[r :r]->(n)` is fine, because `CREATE` will only create the edge `r`,
|
|
||||||
connecting the already existing node `n`. Remaining behaviour is the same as
|
|
||||||
in `MATCH`. This means that we can simplify `CREATE` to be like `MATCH` with 2
|
|
||||||
special cases.
|
|
||||||
|
|
||||||
1. Are we creating a node, i.e. `CREATE (n)`? If yes, then the symbol for
|
|
||||||
`n` must not have been created before. Otherwise, we reference the
|
|
||||||
existing symbol.
|
|
||||||
2. Are we creating an edge, i.e. we encounter a variable for an edge inside
|
|
||||||
`CREATE`? If yes, then that variable must not reference a symbol.
|
|
||||||
|
|
||||||
The `MERGE` clause is treated the same as `CREATE` with regards to symbol
|
|
||||||
generation. The only difference is that we allow bidirectional edges in the
|
|
||||||
pattern. When creating such a pattern, the direction of the created edge is
|
|
||||||
arbitrarily determined.
|
|
||||||
|
|
||||||
### Symbols in WITH and RETURN
|
|
||||||
|
|
||||||
In addition to patterns, new symbols are established in the `WITH` clause.
|
|
||||||
This clause makes the new symbols visible *only* to the rest of the query.
|
|
||||||
For example, `MATCH (old) WITH old AS new RETURN new, old` should raise an
|
|
||||||
error that `old` is unbound inside `RETURN`.
|
|
||||||
|
|
||||||
There is a special case with symbol visibility in `WHERE` and `ORDER BY`. They
|
|
||||||
need to see both the old and the new symbols. Therefore `MATCH (old) RETURN
|
|
||||||
old AS new ORDER BY old.prop` needs to work. On the other hand, if we perform
|
|
||||||
aggregations inside `WITH` or `RETURN`, then the old symbols should not be
|
|
||||||
visible neither in `WHERE` nor in `ORDER BY`. Since the aggregation has to go
|
|
||||||
through all the results in order to generate the final value, it makes no
|
|
||||||
sense to store old symbols and their values. A query like `MATCH (old) WITH
|
|
||||||
SUM(old.prop) AS sum WHERE old.prop = 42 RETURN sum` needs to raise an error
|
|
||||||
that `old` is unbound inside `WHERE`.
|
|
||||||
|
|
||||||
For cases when `SKIP` and `LIMIT` appear, we disallow any identifiers from
|
|
||||||
appearing in their expressions. Basically, `SKIP` and `LIMIT` can only be
|
|
||||||
constant expressions[^1]. For example, `MATCH (old) RETURN old AS new SKIP
|
|
||||||
new.prop` needs to raise that variables are not allowed in `SKIP`. It makes no
|
|
||||||
sense to allow variables, since their values may vary on each iteration. On
|
|
||||||
the other hand, we could support variables to constant expressions, but for
|
|
||||||
simplicity we do not. For example, `MATCH (old) RETURN old, 2 AS limit_var
|
|
||||||
LIMIT limit_var` would still throw an error.
|
|
||||||
|
|
||||||
Finally, we generate symbols for names created in `RETURN` clause. These
|
|
||||||
symbols are used for the final results of a query.
|
|
||||||
|
|
||||||
NOTE: New symbols in `WITH` and `RETURN` should be unique. This means that
|
|
||||||
`WITH a AS same, b AS same` is not allowed, neither is a construct like
|
|
||||||
`RETURN 2, 2`
|
|
||||||
|
|
||||||
### Symbols in Functions which Establish New Scope
|
|
||||||
|
|
||||||
Symbols can also be created in some functions. These functions usually take an
|
|
||||||
expression, bind a single variable and run the expression inside the newly
|
|
||||||
established scope.
|
|
||||||
|
|
||||||
The `all` function takes a list, creates a variable for list element and runs
|
|
||||||
the predicate expression. For example:
|
|
||||||
|
|
||||||
MATCH (n) RETURN n, all(n IN n.prop_list WHERE n < 42)
|
|
||||||
|
|
||||||
We create a new symbol for use inside `all`, this means that the `WHERE n <
|
|
||||||
42` uses the `n` which takes values from a `n.prop_list` elements. The
|
|
||||||
original `n` bound by `MATCH` is not visible inside the `all` function, but it
|
|
||||||
is visible outside. Therefore, the `RETURN n` and `n.prop_list` reference the
|
|
||||||
`n` from `MATCH`.
|
|
||||||
|
|
||||||
[^1]: Constant expressions are expressions for which the result can be
|
|
||||||
computed at compile time.
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
# Quick Start
|
|
||||||
|
|
||||||
A short chapter on downloading the Memgraph source, compiling and running.
|
|
||||||
|
|
||||||
## Obtaining the Source Code
|
|
||||||
|
|
||||||
Memgraph uses `git` for source version control. You will need to install `git`
|
|
||||||
on your machine before you can download the source code.
|
|
||||||
|
|
||||||
On Debian systems, you can do it inside a terminal with the following
|
|
||||||
command:
|
|
||||||
|
|
||||||
apt install git
|
|
||||||
|
|
||||||
After installing `git`, you are now ready to fetch your own copy of Memgraph
|
|
||||||
source code. Run the following command:
|
|
||||||
|
|
||||||
git clone https://github.com/memgraph/memgraph.git
|
|
||||||
|
|
||||||
The above will create a `memgraph` directory and put all source code there.
|
|
||||||
|
|
||||||
## Compiling Memgraph
|
|
||||||
|
|
||||||
With the source code, you are now ready to compile Memgraph. Well... Not
|
|
||||||
quite. You'll need to download Memgraph's dependencies first.
|
|
||||||
|
|
||||||
In your terminal, position yourself in the obtained memgraph directory.
|
|
||||||
|
|
||||||
cd memgraph
|
|
||||||
|
|
||||||
### Installing Dependencies
|
|
||||||
|
|
||||||
Dependencies that are required by the codebase should be checked by running the
|
|
||||||
`init` script:
|
|
||||||
|
|
||||||
./init
|
|
||||||
|
|
||||||
If the script fails, dependencies installation scripts could be found under
|
|
||||||
`environment/os/`. The directory contains dependencies management script for
|
|
||||||
each supported operating system. E.g. if your system is **Debian 10**, run the
|
|
||||||
following to install all required build packages:
|
|
||||||
|
|
||||||
./environment/os/debian-10.sh install MEMGRAPH_BUILD_DEPS
|
|
||||||
|
|
||||||
Once everything is installed, rerun the `init` script.
|
|
||||||
|
|
||||||
Once the `init` script is successfully finished, issue the following commands:
|
|
||||||
|
|
||||||
mkdir -p build
|
|
||||||
./libs/setup.sh
|
|
||||||
|
|
||||||
### Compiling
|
|
||||||
|
|
||||||
Memgraph is compiled using our own custom toolchain that can be obtained from
|
|
||||||
the toolchain repository. You should read the `environment/README.txt` file
|
|
||||||
in the repository and install the apropriate toolchain for your distribution.
|
|
||||||
After you have installed the toolchain you should read the instructions for the
|
|
||||||
toolchain in the toolchain install directory (`/opt/toolchain-vXYZ/README.md`)
|
|
||||||
and install dependencies that are necessary to run the toolchain.
|
|
||||||
|
|
||||||
When you want to compile Memgraph you should activate the toolchain using the
|
|
||||||
prepared toolchain activation script that is also described in the toolchain
|
|
||||||
`README`.
|
|
||||||
|
|
||||||
NOTE: You **must** activate the toolchain every time you want to compile
|
|
||||||
Memgraph!
|
|
||||||
|
|
||||||
You should now activate the toolchain in your console.
|
|
||||||
|
|
||||||
source /opt/toolchain-vXYZ/activate
|
|
||||||
|
|
||||||
With all of the dependencies installed and the build environment set-up, you
|
|
||||||
need to configure the build system. To do that, execute the following:
|
|
||||||
|
|
||||||
cd build
|
|
||||||
cmake ..
|
|
||||||
|
|
||||||
If everything went OK, you can now, finally, compile Memgraph.
|
|
||||||
|
|
||||||
make -j$(nproc)
|
|
||||||
|
|
||||||
### Running
|
|
||||||
|
|
||||||
After the compilation verify that Memgraph works:
|
|
||||||
|
|
||||||
./memgraph --version
|
|
||||||
|
|
||||||
To make extra sure, run the unit tests:
|
|
||||||
|
|
||||||
ctest -R unit -j$(nproc)
|
|
||||||
|
|
||||||
## Problems
|
|
||||||
|
|
||||||
If you have any trouble running the above commands, contact your nearest
|
|
||||||
developer who successfully built Memgraph. Ask for help and insist on getting
|
|
||||||
this document updated with correct steps!
|
|
||||||
|
|
||||||
## Next Steps
|
|
||||||
|
|
||||||
Familiarise yourself with our code conventions and guidelines:
|
|
||||||
|
|
||||||
* [C++ Code](cpp-code-conventions.md)
|
|
||||||
* [Other Code](other-code-conventions.md)
|
|
||||||
* [Code Review Guidelines](code-review.md)
|
|
||||||
|
|
||||||
Take a look at the list of [required reading](required-reading.md) for
|
|
||||||
brushing up on technical skills.
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
# Required Reading
|
|
||||||
|
|
||||||
This chapter lists a few books that should be read by everyone working on
|
|
||||||
Memgraph. Since Memgraph is developed primarily with C++, Python and Common
|
|
||||||
Lisp, books are oriented around those languages. Of course, there are plenty
|
|
||||||
of general books which will help you improve your technical skills (such as
|
|
||||||
"The Pragmatic Programmer", "The Mythical Man-Month", etc.), but they are not
|
|
||||||
listed here. This way the list should be kept short and the *required* part in
|
|
||||||
"Required Reading" more easily honored.
|
|
||||||
|
|
||||||
Some of these books you may find in our office, so feel free to pick them up.
|
|
||||||
If any are missing and you would like a physical copy, don't be afraid to
|
|
||||||
request the book for our office shelves.
|
|
||||||
|
|
||||||
Besides reading, don't get stuck in a rut and be a
|
|
||||||
[Blub Programmer](http://www.paulgraham.com/avg.html).
|
|
||||||
|
|
||||||
## Effective C++ by Scott Meyers
|
|
||||||
|
|
||||||
Required for C++ developers.
|
|
||||||
|
|
||||||
The book is a must-read as it explains most common gotchas of using C++. After
|
|
||||||
reading this book, you are good to write competent C++ which will pass code
|
|
||||||
reviews easily.
|
|
||||||
|
|
||||||
## Effective Modern C++ by Scott Meyers
|
|
||||||
|
|
||||||
Required for C++ developers.
|
|
||||||
|
|
||||||
This is a continuation of the previous book, it covers updates to C++ which
|
|
||||||
came with C++11 and later. The book isn't as imperative as the previous one,
|
|
||||||
but it will make you aware of modern features we are using in our codebase.
|
|
||||||
|
|
||||||
## Practical Common Lisp by Peter Siebel
|
|
||||||
|
|
||||||
Required for Common Lisp developers.
|
|
||||||
|
|
||||||
Free: http://www.gigamonkeys.com/book/
|
|
||||||
|
|
||||||
We use Common Lisp to generate C++ code and make our lives easier.
|
|
||||||
Unfortunately, not many developers are familiar with the language. This book
|
|
||||||
will make you familiar very quickly as it has tons of very practical
|
|
||||||
exercises. E.g. implementing unit testing library, serialization library and
|
|
||||||
bundling all that to create a mp3 music server.
|
|
||||||
|
|
||||||
## Effective Python by Brett Slatkin
|
|
||||||
|
|
||||||
(Almost) required reading for Python developers.
|
|
||||||
|
|
||||||
Why the "almost"? Well, Python is relatively easy to pick up and you will
|
|
||||||
probably learn all the gotchas during code review from someone more
|
|
||||||
experienced. This makes the book less necessary for a newcomer to Memgraph,
|
|
||||||
but the book is not advanced enough to delegate it to
|
|
||||||
[Advanced Reading](#advanced-reading). The book is written in similar vein as
|
|
||||||
the "Effective C++" ones and will make you familiar with nifty Python features
|
|
||||||
that make everyone's lives easier.
|
|
||||||
|
|
||||||
# Advanced Reading
|
|
||||||
|
|
||||||
The books listed below are not required reading, but you may want to read them
|
|
||||||
at some point when you feel comfortable enough.
|
|
||||||
|
|
||||||
## Design Patterns by Gamma et. al.
|
|
||||||
|
|
||||||
Recommended for C++ developers.
|
|
||||||
|
|
||||||
This book is highly divisive because it introduced a culture centered around
|
|
||||||
design patterns. The main issues is overuse of patterns which complicates the
|
|
||||||
code. This has made many Java programs to serve as examples of highly
|
|
||||||
complicated, "enterprise" code.
|
|
||||||
|
|
||||||
Unfortunately, design patterns are pretty much missing
|
|
||||||
language features. This is most evident in dynamic languages such as Python
|
|
||||||
and Lisp, as demonstrated by
|
|
||||||
[Peter Norvig](http://www.norvig.com/design-patterns/).
|
|
||||||
|
|
||||||
Or as [Paul Graham](http://www.paulgraham.com/icad.html) put it:
|
|
||||||
|
|
||||||
```
|
|
||||||
This practice is not only common, but institutionalized. For example, in the
|
|
||||||
OO world you hear a good deal about "patterns". I wonder if these patterns are
|
|
||||||
not sometimes evidence of case (c), the human compiler, at work. When I see
|
|
||||||
patterns in my programs, I consider it a sign of trouble. The shape of a
|
|
||||||
program should reflect only the problem it needs to solve. Any other
|
|
||||||
regularity in the code is a sign, to me at least, that I'm using abstractions
|
|
||||||
that aren't powerful enough-- often that I'm generating by hand the expansions
|
|
||||||
of some macro that I need to write
|
|
||||||
```
|
|
||||||
|
|
||||||
After presenting the book so negatively, why you should even read it then?
|
|
||||||
Well, it is good to be aware of those design patterns and use them when
|
|
||||||
appropriate. They can improve modularity and reuse of the code. You will also
|
|
||||||
find examples of such patterns in our code, primarily Strategy and Visitor
|
|
||||||
patterns. The book is also a good stepping stone to more advanced reading
|
|
||||||
about software design.
|
|
||||||
|
|
||||||
## Modern C++ Design by Andrei Alexandrescu
|
|
||||||
|
|
||||||
Recommended for C++ developers.
|
|
||||||
|
|
||||||
This book can be treated as a continuation of the previous "Design Patterns"
|
|
||||||
book. It introduced "dark arts of template meta-programming" to the world.
|
|
||||||
Many of the patterns are converted to use C++ templates which makes them even
|
|
||||||
better for reuse. But, like the previous book, there are downsides if used too
|
|
||||||
much. You should approach it with a critical eye and it will help you
|
|
||||||
understand ideas that are used in some parts of our codebase.
|
|
||||||
|
|
||||||
## Large Scale C++ Software Design by John Lakos
|
|
||||||
|
|
||||||
Recommended for C++ developers.
|
|
||||||
|
|
||||||
An old book, but well worth the read. Lakos presents a very pragmatic view of
|
|
||||||
writing modular software and how it affects both development time as well as
|
|
||||||
program runtime. Some things are outdated or controversial, but it will help
|
|
||||||
you understand how the whole C++ process of working in a large team, compiling
|
|
||||||
and linking affects development.
|
|
||||||
|
|
||||||
## On Lisp by Paul Graham
|
|
||||||
|
|
||||||
Recommended for Common Lisp developers.
|
|
||||||
|
|
||||||
Free: http://www.paulgraham.com/onlisp.html
|
|
||||||
|
|
||||||
An excellent continuation to "Practical Common Lisp". It starts of slow, as if
|
|
||||||
introducing the language, but very quickly picks up speed. The main meat of
|
|
||||||
the book are macros and their uses. From using macros to define cooperative
|
|
||||||
concurrency to including Prolog as if it's part of Common Lisp. The book will
|
|
||||||
help you understand more advanced macros that are occasionally used in our
|
|
||||||
Lisp C++ Preprocessor (LCP).
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
# DatabaseAccessor
|
|
||||||
|
|
||||||
A `DatabaseAccessor` actually wraps a transactional access to database
|
|
||||||
data, for a single transaction. In that sense the naming is bad. It
|
|
||||||
encapsulates references to the database and the transaction object.
|
|
||||||
|
|
||||||
It contains logic for working with database content (graph element
|
|
||||||
data) in the context of a single transaction. All CRUD operations are
|
|
||||||
performed within a single transaction (as Memgraph is a transactional
|
|
||||||
database), and therefore iteration over data, finding a specific graph
|
|
||||||
element etc are all functionalities of a `GraphDbAccessor`.
|
|
||||||
|
|
||||||
In single-node Memgraph the database accessor also defined the lifetime
|
|
||||||
of a transaction. Even though a `Transaction` object was owned by the
|
|
||||||
transactional engine, it was `GraphDbAccessor`'s lifetime that object
|
|
||||||
was bound to (the transaction was implicitly aborted in
|
|
||||||
`GraphDbAccessor`'s destructor, if it was not explicitly ended before
|
|
||||||
that).
|
|
||||||
|
|
||||||
# RecordAccessor
|
|
||||||
|
|
||||||
It is important to understand data organization and access in the
|
|
||||||
storage layer. This discussion pertains to vertices and edges as graph
|
|
||||||
elements that the end client works with.
|
|
||||||
|
|
||||||
Memgraph uses MVCC (documented on it's own page). This means that for
|
|
||||||
each graph element there could be different versions visible to
|
|
||||||
different currently executing transactions. When we talk about a
|
|
||||||
`Vertex` or `Edge` as a data structure we typically mean one of those
|
|
||||||
versions. In code this semantic is implemented so that both those classes
|
|
||||||
inherit `mvcc::Record`, which in turn inherits `mvcc::Version`.
|
|
||||||
|
|
||||||
Handling MVCC and visibility is not in itself trivial. Next to that,
|
|
||||||
there is other book-keeping to be performed when working with data. For
|
|
||||||
that reason, Memgraph uses "accessors" to define an API of working with
|
|
||||||
data in a safe way. Most of the code in Memgraph (for example the
|
|
||||||
interpretation code) should work with accessors. There is a
|
|
||||||
`RecordAccessor` as a base class for `VertexAccessor` and
|
|
||||||
`EdgeAccessor`. Following is an enumeration of their purpose.
|
|
||||||
|
|
||||||
### Data Access
|
|
||||||
|
|
||||||
The client interacts with Memgraph using the Cypher query language. That
|
|
||||||
language has certain semantics which imply that multiple versions of the
|
|
||||||
data need to be visible during the execution of a single query. For
|
|
||||||
example: expansion over the graph is always done over the graph state as
|
|
||||||
it was at the beginning of the transaction.
|
|
||||||
|
|
||||||
The `RecordAccessor` exposes functions to switch between the old and the new
|
|
||||||
versions of the same graph element (intelligently named `SwitchOld` and
|
|
||||||
`SwitchNew`) within a single transaction. In that way the client code
|
|
||||||
(mostly the interpreter) can avoid dealing with the underlying MVCC
|
|
||||||
version concepts.
|
|
||||||
|
|
||||||
### Updates
|
|
||||||
|
|
||||||
Data updates are also done through accessors. Meaning: there are methods
|
|
||||||
on the accessors that modify data, the client code should almost never
|
|
||||||
interact directly with `Vertex` or `Edge` objects.
|
|
||||||
|
|
||||||
The accessor layer takes care of creating version in the MVCC layer and
|
|
||||||
performing updates on appropriate versions.
|
|
||||||
|
|
||||||
Next, for many kinds of updates it is necessary to update the relevant
|
|
||||||
indexes. There are implicit indexes for vertex labels, as
|
|
||||||
well as user-created indexes for (label, property) pairs. The accessor
|
|
||||||
layer takes care of updating the indexes when these values are changed.
|
|
||||||
|
|
||||||
Each update also triggers a log statement in the write-ahead log. This
|
|
||||||
is also handled by the accessor layer.
|
|
||||||
|
|
||||||
### Distributed
|
|
||||||
|
|
||||||
In distributed Memgraph accessors also contain a lot of the remote graph
|
|
||||||
element handling logic. More info on that is available in the
|
|
||||||
documentation for distributed.
|
|
||||||
|
|
||||||
### Deferred MVCC Data Lookup for Edges
|
|
||||||
|
|
||||||
Vertices and edges are versioned using MVCC. This means that for each
|
|
||||||
transaction an MVCC lookup needs to be done to determine which version
|
|
||||||
is visible to that transaction. This tends to slow things down due to
|
|
||||||
cache invalidations (version lists and versions are stored in arbitrary
|
|
||||||
locations on the heap).
|
|
||||||
|
|
||||||
However, for edges, only the properties are mutable. The edge endpoints
|
|
||||||
and type are fixed once the edge is created. For that reason both edge
|
|
||||||
endpoints and type are available in vertex data, so that when expanding
|
|
||||||
it is not mandatory to do MVCC lookups of versioned, mutable data. This
|
|
||||||
logic is implemented in `RecordAccessor` and `EdgeAccessor`.
|
|
||||||
|
|
||||||
### Exposure
|
|
||||||
|
|
||||||
The original idea and implementation of graph element accessors was that
|
|
||||||
they'd prevent client code from ever interacting with raw `Vertex` or
|
|
||||||
`Edge` data. This however turned out to be impractical when implementing
|
|
||||||
distributed Memgraph and the raw data members have since been exposed
|
|
||||||
(through getters to old and new version pointers). However, refrain from
|
|
||||||
working with that data directly whenever possible! Always consider the
|
|
||||||
accessors to be the first go-to for interacting with data, especially
|
|
||||||
when in the context of a transaction.
|
|
||||||
|
|
||||||
# Skiplist Accessor
|
|
||||||
|
|
||||||
The term "accessor" is also used in the context of a skiplist. Every
|
|
||||||
operation on a skiplist must be performed within on an
|
|
||||||
accessor. The skiplist ensures that there will be no physical deletions
|
|
||||||
of an object during the lifetime of an accessor. This mechanism is used
|
|
||||||
to ensure deletion correctness in a highly concurrent container.
|
|
||||||
We only mention that here to avoid confusion regarding terminology.
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
# Storage v1
|
|
||||||
|
|
||||||
* [Accessors](accessors.md)
|
|
||||||
* [Indexes](indexes.md)
|
|
||||||
* [Property Storage](property-storage.md)
|
|
||||||
* [Durability](durability.md)
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
# Durability
|
|
||||||
|
|
||||||
## Write-ahead Logging
|
|
||||||
|
|
||||||
Typically WAL denotes the process of writing a "log" of database
|
|
||||||
operations (state changes) to persistent storage before committing the
|
|
||||||
transaction, thus ensuring that the state can be recovered (in the case
|
|
||||||
of a crash) for all the transactions which the database committed.
|
|
||||||
|
|
||||||
The WAL is a fine-grained durability format. It's purpose is to store
|
|
||||||
database changes fast. It's primary purpose is not to provide
|
|
||||||
space-efficient storage, nor to support fast recovery. For that reason
|
|
||||||
it's often used in combination with a different persistence mechanism
|
|
||||||
(in Memgraph's case the "snapshot") that has complementary
|
|
||||||
characteristics.
|
|
||||||
|
|
||||||
### Guarantees
|
|
||||||
|
|
||||||
Ensuring that the log is written before the transaction is committed can
|
|
||||||
slow down the database. For that reason this guarantee is most often
|
|
||||||
configurable in databases.
|
|
||||||
|
|
||||||
Memgraph offers two options for the WAL. The default option, where the WAL is
|
|
||||||
flushed to the disk periodically and transactions do not wait for this to
|
|
||||||
complete, introduces the risk of database inconsistency because an operating
|
|
||||||
system or hardware crash might lead to missing transactions in the WAL. Memgraph
|
|
||||||
will handle this as if those transactions never happened. The second option,
|
|
||||||
called synchronous commit, will instruct Memgraph to wait for the WAL to be
|
|
||||||
flushed to the disk when a transactions completes and the transaction will wait
|
|
||||||
for this to complete. This option can be turned on with the
|
|
||||||
`--synchronous-commit` command line flag.
|
|
||||||
|
|
||||||
### Format
|
|
||||||
|
|
||||||
The WAL file contains a series of DB state changes called `StateDelta`s.
|
|
||||||
Each of them describes what the state change is and in which transaction
|
|
||||||
it happened. Also some kinds of meta-information needed to ensure proper
|
|
||||||
state recovery are recorded (transaction beginnings and commits/abort).
|
|
||||||
|
|
||||||
The following is guaranteed w.r.t. `StateDelta` ordering in
|
|
||||||
a single WAL file:
|
|
||||||
- For two ops in the same transaction, if op A happened before B in the
|
|
||||||
database, that ordering is preserved in the log.
|
|
||||||
- Transaction begin/commit/abort messages also appear in exactly the
|
|
||||||
same order as they were executed in the transactional engine.
|
|
||||||
|
|
||||||
### Recovery
|
|
||||||
|
|
||||||
The database can recover from the WAL on startup. This works in
|
|
||||||
conjunction with snapshot recovery. The database attempts to recover from
|
|
||||||
the latest snapshot and then apply as much as possible from the WAL
|
|
||||||
files. Only those transactions that were not recovered from the snapshot
|
|
||||||
are recovered from the WAL, for speed efficiency. It is possible (but
|
|
||||||
inefficient) to recover the database from WAL only, provided all the WAL
|
|
||||||
files created from DB start are available. It is not possible to recover
|
|
||||||
partial database state (i.e. from some suffix of WAL files, without the
|
|
||||||
preceding snapshot).
|
|
||||||
|
|
||||||
## Snapshots
|
|
||||||
|
|
||||||
A "snapshot" is a record of the current database state stored in permanent
|
|
||||||
storage. Note that the term "snapshot" is used also in the context of
|
|
||||||
the transaction engine to denote a set of running transactions.
|
|
||||||
|
|
||||||
A snapshot is written to the file by Memgraph periodically if so
|
|
||||||
configured. The snapshot creation process is done within a transaction created
|
|
||||||
specifically for that purpose. The transaction is needed to ensure that
|
|
||||||
the stored state is internally consistent.
|
|
||||||
|
|
||||||
The database state can be recovered from the snapshot during startup, if
|
|
||||||
so configured. This recovery works in conjunction with write-ahead log
|
|
||||||
recovery.
|
|
||||||
|
|
||||||
A single snapshot contains all the data needed to recover a database. In
|
|
||||||
that sense snapshots are independent of each other and old snapshots can
|
|
||||||
be deleted once the new ones are safely stored, if it is not necessary
|
|
||||||
to revert the database to some older state.
|
|
||||||
|
|
||||||
The exact format of the snapshot file is defined inline in the snapshot
|
|
||||||
creation code.
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
# Label Indexes
|
|
||||||
|
|
||||||
These are unsorted indexes that contain all the vertices that have the label
|
|
||||||
the indexes are for (one index per label). These kinds of indexes get
|
|
||||||
automatically generated for each label used in the database.
|
|
||||||
|
|
||||||
### Updating the Indexes
|
|
||||||
|
|
||||||
Whenever something gets added to the record we update the index (add that
|
|
||||||
record to index). We keep an index which might contain garbage (not relevant
|
|
||||||
records, because the value got removed or something similar) but we will
|
|
||||||
filter it out when querying the index. We do it like this because we don't
|
|
||||||
have to do bookkeeping and deciding if we update the index on the end of the
|
|
||||||
transaction (commit/abort phase), moreover current interpreter advances the
|
|
||||||
command in transaction and as such assumes that the indexes now contain
|
|
||||||
objects added in the previous command inside this transaction, so we need to
|
|
||||||
update over the whole scope of transaction (whenever something is added to the
|
|
||||||
record).
|
|
||||||
|
|
||||||
### Index Entries Label
|
|
||||||
|
|
||||||
These kinds of indexes are internally keeping track of pair (record, vlist).
|
|
||||||
Why do we need to keep track of exactly those two things?
|
|
||||||
|
|
||||||
Problems with two different approaches
|
|
||||||
|
|
||||||
1) Keep track of just the record:
|
|
||||||
|
|
||||||
- We need the `VersionList` for creating an accessor (this in itself is a
|
|
||||||
deal-breaker).
|
|
||||||
- Semantically it makes sense. An edge/vertex maps bijectionally to a
|
|
||||||
`VersionList`.
|
|
||||||
- We might try to access some members of record while the record is being
|
|
||||||
modified from another thread.
|
|
||||||
- A vertex/edge could get updated, thus expiring the record in the index.
|
|
||||||
The newly created record should be present in the index, but it's not.
|
|
||||||
Without the `VersionList` we can't reach the newly created record.
|
|
||||||
- Probably there are even more reasons... It should be obvious by now that
|
|
||||||
we need the `VersionList` in the index.
|
|
||||||
|
|
||||||
2) Keep track of just the version list:
|
|
||||||
|
|
||||||
- Removing from an index is a problem for two major reasons. First, if we
|
|
||||||
only have the `VersionList`, checking if it should be removed implies
|
|
||||||
checking all the reachable records, which is not thread-safe. Second,
|
|
||||||
there are issues with concurrent removal and insertion. The cleanup thread
|
|
||||||
could determine the vertex/edge should be removed from the index and
|
|
||||||
remove it, while in between those ops another thread attempts to insert
|
|
||||||
the `VersionList` into the index. The insertion does nothing because the
|
|
||||||
`VersionList` is already in, but it gets removed immediately after.
|
|
||||||
|
|
||||||
Because of inability to keep track of just the record, or value, we need to
|
|
||||||
keep track of both of them. Resolution of problems mentioned above, in the
|
|
||||||
same order, with (record, vlist) pair
|
|
||||||
|
|
||||||
- simple `vlist.find(current transaction)` will get us the newest visible
|
|
||||||
record
|
|
||||||
- we'll never try to access some record if it's still being written since we
|
|
||||||
will always operate on vlist.find returned record
|
|
||||||
- newest record will contain that label
|
|
||||||
- since we have (record, vlist) pair as the key in the index when we update
|
|
||||||
and delete in the same time we will never delete the same record, vlist
|
|
||||||
pair we are adding because the record, vlist pair we are deleting is
|
|
||||||
already superseded by a newer record and as such won't be inserted while
|
|
||||||
it's being deleted
|
|
||||||
|
|
||||||
### Querying the Index
|
|
||||||
|
|
||||||
We run through the index for the given label and do `vlist.find` operation for
|
|
||||||
the current transaction, and check if the newest return record has that
|
|
||||||
label. If it has it then we return it. By now you are probably wondering
|
|
||||||
aren't we sometimes returning duplicate vlist entries? And you are wondering
|
|
||||||
correctly, we would be returning them, but we are making sure that the entires
|
|
||||||
in the index are sorted by their `vlist*` and as such we can filter consecutive
|
|
||||||
duplicate `vlist*` to only return one of those while still being able to create
|
|
||||||
an iterator to index.
|
|
||||||
|
|
||||||
### Cleaning the Index
|
|
||||||
|
|
||||||
Cleaning the index is not as straightforward as it seems as a lot of garbage
|
|
||||||
can accumulate, but it's hard to know when exactly can we delete some (record,
|
|
||||||
vlist) pair. First, let's assume that we are doing the cleaning process at
|
|
||||||
some `transaction_id`, `id` such that there doesn't exist an active transaction
|
|
||||||
with an id lower than `id`.
|
|
||||||
|
|
||||||
We scan through the whole index and for each (record, vlist) pair we first
|
|
||||||
check if it was deleted before the id (i.e. no transaction with an id >= `id`
|
|
||||||
will ever again see that record), if it was deleted before we might naively
|
|
||||||
say that it's safe to delete it, but, we must take into account that when some
|
|
||||||
new record is created from this record (update operation), that record still
|
|
||||||
contains the label but by deleting this record we won't be able to see that
|
|
||||||
vlist because that new record won't add again to index because we didn't
|
|
||||||
explicitly add that label again to it.
|
|
||||||
|
|
||||||
Because of this we have to 'update' this index (record, vlist) pair. We have
|
|
||||||
to update the record to now point to a newer record in vlist, the one that is
|
|
||||||
not deleted yet. We can do that by querying the `version_list` for the last
|
|
||||||
record inside (oldest it has — remember that `mvcc_gc` will re-link not
|
|
||||||
visible records so the last record will be visible for the current GC id).
|
|
||||||
When updating the record inside the index, it's not okay to just update the
|
|
||||||
pointer and leave the index as it is, because with updating the `record*` we
|
|
||||||
might change the relative order of entries inside the index. We first have to
|
|
||||||
re-insert it with new `record*`, and then delete the old entry. And we need to
|
|
||||||
do insertion before the remove operation! Otherwise it could happen that the
|
|
||||||
vlist with a newer record with that label won't exist while some transaction
|
|
||||||
is querying the index.
|
|
||||||
|
|
||||||
Records which we added as a consequence of deleting older records will be
|
|
||||||
eventually removed from the index if they don't contain label because if we
|
|
||||||
see that the record is not deleted we try to check if that record still
|
|
||||||
contains the label. We also need to be careful here because we can't check
|
|
||||||
that while the record is being potentially updated by some transaction (race
|
|
||||||
condition), so we need can check if records still contain label if it's
|
|
||||||
creation id is smaller than our `id`, as that implies that the creating
|
|
||||||
transaction either aborted or committed as our `id` is equal to the oldest
|
|
||||||
active transaction in time of starting the GC.
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
# Property Storage
|
|
||||||
|
|
||||||
Although the reader is probably familiar with properties in *Memgraph*, let's
|
|
||||||
briefly recap.
|
|
||||||
|
|
||||||
Both vertices and edges can store an arbitrary number of properties. Properties
|
|
||||||
are, in essence, ordered pairs of property names and property values. Each
|
|
||||||
property name within a single graph element (edge/node) can store a single
|
|
||||||
property value. Property names are represented as strings, while property values
|
|
||||||
must be one of the following types:
|
|
||||||
|
|
||||||
Type | Description
|
|
||||||
-----------|------------
|
|
||||||
`Null` | Denotes that the property has no value. This is the same as if the property does not exist.
|
|
||||||
`String` | A character string, i.e. text.
|
|
||||||
`Boolean` | A boolean value, either `true` or `false`.
|
|
||||||
`Integer` | An integer number.
|
|
||||||
`Float` | A floating-point number, i.e. a real number.
|
|
||||||
`List` | A list containing any number of property values of any supported type. It can be used to store multiple values under a single property name.
|
|
||||||
`Map` | A mapping of string keys to values of any supported type.
|
|
||||||
|
|
||||||
Property values are modeled in a class conveniently called `PropertyValue`.
|
|
||||||
|
|
||||||
## Mapping Between Property Names and Property Keys.
|
|
||||||
|
|
||||||
Although users think of property names in terms of descriptive strings
|
|
||||||
(e.g. "location" or "department"), *Memgraph* internally converts those names
|
|
||||||
into property keys which are, essentially, unsigned 16-bit integers.
|
|
||||||
|
|
||||||
Property keys are modelled by a not-so-conveniently named class called
|
|
||||||
`Property` which can be found in `storage/types.hpp`. The actual conversion
|
|
||||||
between property names and property keys is done within the `ConcurrentIdMapper`
|
|
||||||
but the internals of that implementation are out of scope for understanding
|
|
||||||
property storage.
|
|
||||||
|
|
||||||
## PropertyValueStore
|
|
||||||
|
|
||||||
Both `Edge` and `Vertex` objects contain an instance of `PropertyValueStore`
|
|
||||||
object which is responsible for storing properties of a corresponding graph
|
|
||||||
element.
|
|
||||||
|
|
||||||
An interface of `PropertyValueStore` is as follows:
|
|
||||||
|
|
||||||
Method | Description
|
|
||||||
-----------|------------
|
|
||||||
`at` | Returns the `PropertyValue` for a given `Property` (key).
|
|
||||||
`set` | Stores a given `PropertyValue` under a given `Property` (key).
|
|
||||||
`erase` | Deletes a given `Property` (key) alongside its corresponding `PropertyValue`.
|
|
||||||
`clear` | Clears the storage.
|
|
||||||
`iterator`| Provides an extension of `std::input_iterator` that iterates over storage.
|
|
||||||
|
|
||||||
## Storage Location
|
|
||||||
|
|
||||||
By default, *Memgraph* is an in-memory database and all properties are therefore
|
|
||||||
stored in working memory unless specified otherwise by the user. User has an
|
|
||||||
option to specify via the command line which properties they wish to be stored
|
|
||||||
on disk.
|
|
||||||
|
|
||||||
Storage location of each property is encapsulated within a `Property` object
|
|
||||||
which is ensured by the `ConcurrentIdMapper`. More precisely, the unsigned 16-bit
|
|
||||||
property key has the following format:
|
|
||||||
|
|
||||||
```
|
|
||||||
|---location--|------id------|
|
|
||||||
|-Memory|Disk-|-----2^15-----|
|
|
||||||
```
|
|
||||||
|
|
||||||
In other words, the most significant bit determines the location where the
|
|
||||||
property will be stored.
|
|
||||||
|
|
||||||
### In-memory Storage
|
|
||||||
|
|
||||||
The underlying implementation of in-memory storage for the time being is
|
|
||||||
`std::vector<std::pair<Property, PropertyValue>>`. Implementations of`at`, `set`
|
|
||||||
and `erase` are linear in time. This implementation is arguably more efficient
|
|
||||||
than `std::map` or `std::unordered_map` when the average number of properties of
|
|
||||||
a record is relatively small (up to 10) which seems to be the case.
|
|
||||||
|
|
||||||
### On-disk Storage
|
|
||||||
|
|
||||||
#### KVStore
|
|
||||||
|
|
||||||
Disk storage is modeled by an abstraction of key-value storage as implemented in
|
|
||||||
`storage/kvstore.hpp'. An interface of this abstraction is as follows:
|
|
||||||
|
|
||||||
Method | Description
|
|
||||||
----------------|------------
|
|
||||||
`Put` | Stores the given value under the given key.
|
|
||||||
`Get` | Obtains the given value stored under the given key.
|
|
||||||
`Delete` | Deletes a given (key, value) pair from storage..
|
|
||||||
`DeletePrefix` | Deletes all (key, value) pairs where key begins with a given prefix.
|
|
||||||
`Size` | Returns the size of the storage or, optionally, the number of stored pairs that begin with a given prefix.
|
|
||||||
`iterator` | Provides an extension of `std::input_iterator` that iterates over storage.
|
|
||||||
|
|
||||||
Keys and values in this context are of type `std::string`.
|
|
||||||
|
|
||||||
The actual underlying implementation of this abstraction uses
|
|
||||||
[RocksDB]{https://rocksdb.org} — a persistent key-value store for fast
|
|
||||||
storage.
|
|
||||||
|
|
||||||
It is worthy to note that the custom iterator implementation allows the user
|
|
||||||
to iterate over a given prefix. Otherwise, the implementation follows familiar
|
|
||||||
c++ constructs and can be used as follows:
|
|
||||||
|
|
||||||
```
|
|
||||||
KVStore storage = ...;
|
|
||||||
for (auto it = storage.begin(); it != storage.end(); ++it) {}
|
|
||||||
for (auto kv : storage) {}
|
|
||||||
for (auto it = storage.begin("prefix"); it != storage.end("prefix"); ++it) {}
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that it is not possible to scan over multiple prefixes. For instance, one
|
|
||||||
might assume that you can scan over all keys that fall in a certain
|
|
||||||
lexicographical range. Unfortunately, that is not the case and running the
|
|
||||||
following code will result in an infinite loop with a touch of undefined
|
|
||||||
behavior.
|
|
||||||
|
|
||||||
```
|
|
||||||
KVStore storage = ...;
|
|
||||||
for (auto it = storage.begin("alpha"); it != storage.end("omega"); ++it) {}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Data Organization on Disk
|
|
||||||
|
|
||||||
Each `PropertyValueStore` instance can access a static `KVStore` object that can
|
|
||||||
store `(key, value)` pairs on disk. The key of each property on disk consists of
|
|
||||||
two parts — a unique identifier (unsigned 64-bit integer) of the current
|
|
||||||
record version (see mvcc docummentation for further clarification) and a
|
|
||||||
property key as described above. The actual value of the property is serialized
|
|
||||||
into a bytestring using bolt `BaseEncoder`. Similarly, deserialization is
|
|
||||||
performed by bolt `Decoder`.
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Storage v2
|
|
||||||
|
|
||||||
TODO(gitbuda): Write documentation.
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
# Memgraph Workflow
|
|
||||||
|
|
||||||
This chapter describes the usual workflow for working on Memgraph.
|
|
||||||
|
|
||||||
## Git
|
|
||||||
|
|
||||||
Memgraph uses [git](https://git-scm.com/) for source version control. If you
|
|
||||||
obtained the source, you probably already have it installed. Before you can
|
|
||||||
track new changes, you need to setup some basic information.
|
|
||||||
|
|
||||||
First, tell git your name:
|
|
||||||
|
|
||||||
git config --global user.name "FirstName LastName"
|
|
||||||
|
|
||||||
Then, set your Memgraph email:
|
|
||||||
|
|
||||||
git config --global user.email "my.email@memgraph.com"
|
|
||||||
|
|
||||||
Finally, make git aware of your favourite editor:
|
|
||||||
|
|
||||||
git config --global core.editor "vim"
|
|
||||||
|
|
||||||
## Github
|
|
||||||
|
|
||||||
All of the code in Memgraph needs to go through code review before it can be
|
|
||||||
accepted in the codebase. This is done through [Github](https://github.com/).
|
|
||||||
You should already have it installed if you followed the steps in [Quick
|
|
||||||
Start](quick-start.md).
|
|
||||||
|
|
||||||
## Working on Your Feature Branch
|
|
||||||
|
|
||||||
Git has a concept of source code **branches**. The `master` branch contains all
|
|
||||||
of the changes which were reviewed and accepted in Memgraph's code base. The
|
|
||||||
`master` branch is selected by default.
|
|
||||||
|
|
||||||
### Creating a Branch
|
|
||||||
|
|
||||||
When working on a new feature or fixing a bug, you should create a new branch
|
|
||||||
out of the `master` branch. There are two branch types, **epic** and **task**
|
|
||||||
branches. The epic branch is created when introducing a new feature or any work
|
|
||||||
unit requiring more than one commit. More commits are required to split the
|
|
||||||
work into chunks to be able to easier review code or find a bug (in each
|
|
||||||
commit, there could be various problems, e.g., related to performance or
|
|
||||||
concurrency issues, which are the hardest to track down). Each commit on the
|
|
||||||
master or epic branch should be a compilable and well-documented set of
|
|
||||||
changes. Task branches should be created when a smaller work unit has to be
|
|
||||||
integrated into the codebase. The task branch could be branched out of the
|
|
||||||
master or an epic branch. We manage epics and tasks on the project management
|
|
||||||
tool called [Airtable](https://airtable.com/tblTUqycq8sHTTkBF). Each epic is
|
|
||||||
prefixed by `Exyz-MG`, on the other hand, each task has `Tabcd-MG` prefix.
|
|
||||||
Examples on how to create branches follow:
|
|
||||||
|
|
||||||
```
|
|
||||||
git checkout master
|
|
||||||
git checkout -b T0025-MG-fix-a-problem
|
|
||||||
...
|
|
||||||
git checkout master
|
|
||||||
git checkout -b E025-MG-huge-feature
|
|
||||||
...
|
|
||||||
git checkout E025-MG-huge-feature
|
|
||||||
git checkout -b T0123-MG-add-feature-part
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that a branch is created from the currently selected branch. So, if you
|
|
||||||
wish to create another branch from `master` you need to switch to `master`
|
|
||||||
first.
|
|
||||||
|
|
||||||
### Making and Committing Changes
|
|
||||||
|
|
||||||
When you have a branch for your new addition, you can now actually start
|
|
||||||
implementing it. After some amount of time, you may have created new files,
|
|
||||||
modified others and maybe even deleted unused files. You need to tell git to
|
|
||||||
track those changes. This is accomplished with `git add` and `git rm`
|
|
||||||
commands.
|
|
||||||
|
|
||||||
git add path-to-new-file path-to-modified-file
|
|
||||||
git rm path-to-deleted-file
|
|
||||||
|
|
||||||
To check that everything is correctly tracked, you may use the `git status`
|
|
||||||
command. It will also print the name of the currently selected branch.
|
|
||||||
|
|
||||||
If everything seems OK, you should commit these changes to git.
|
|
||||||
|
|
||||||
git commit
|
|
||||||
|
|
||||||
You will be presented with an editor where you need to type the commit
|
|
||||||
message. Writing a good commit message is an art in itself. You should take a
|
|
||||||
look at the links below. We try to follow these conventions as much as
|
|
||||||
possible.
|
|
||||||
|
|
||||||
* [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/)
|
|
||||||
* [A Note About Git Commit Messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
|
|
||||||
* [stopwritingramblingcommitmessages](http://stopwritingramblingcommitmessages.com/)
|
|
||||||
|
|
||||||
### Sending Changes on a Review
|
|
||||||
|
|
||||||
After finishing your work on your feature branch, you will want to send it on
|
|
||||||
code review. This is done by pushing the branch to Github and creating a pull
|
|
||||||
request. You can find all PRs
|
|
||||||
[here](https://github.com/memgraph/memgraph/pulls).
|
|
||||||
|
|
||||||
### Code Integration
|
|
||||||
|
|
||||||
When working, you have to integrate some changes to your work or push your work
|
|
||||||
to be available for others. To pull changes into a local `branch`, usually run
|
|
||||||
the following:
|
|
||||||
|
|
||||||
git checkout {{branch}}
|
|
||||||
git pull origin {{branch}}
|
|
||||||
|
|
||||||
To push your changes, usually run the following:
|
|
||||||
|
|
||||||
git checkout {{branch}}
|
|
||||||
git push origin {{branch}}
|
|
||||||
|
|
||||||
Sometimes, things could get a little bit more complicated. Diagram below shows
|
|
||||||
which git operation should be performed if a piece of code has to be integrated
|
|
||||||
from one branch to another. Note, `main_branch` is the **master** branch in our
|
|
||||||
case.
|
|
||||||
|
|
||||||
```
|
|
||||||
|<---------------------------|
|
|
||||||
| squash merge |
|
|
||||||
|--------------------------->|
|
|
||||||
| merge |
|
|
||||||
| |
|
|
||||||
|<-----------|<--------------|
|
|
||||||
| merge | squash merge |
|
|
||||||
| | |
|
|
||||||
|----------->|-------------->|
|
|
||||||
| rebase | merge |
|
|
||||||
| | rebase --onto |
|
|
||||||
| | |
|
|
||||||
main_branch epic_branch task_branch
|
|
||||||
```
|
|
||||||
|
|
||||||
There are a couple of cases:
|
|
||||||
|
|
||||||
* If a code has to be integrated from a task branch to the main branch, use
|
|
||||||
**squash merge**. While you were working on a task, you probably committed a
|
|
||||||
couple of cleanup commits that are not relevant to the main branch. In the
|
|
||||||
other direction, while integrating the main branch to a task branch, the
|
|
||||||
**regular merge** is ok because changes from the task branch will later be
|
|
||||||
squash merged.
|
|
||||||
|
|
||||||
* You should use **squash merge** when integrating changes from task to epic
|
|
||||||
branch (task might have irrelevant commits). On the other hand, you should
|
|
||||||
use a **regular merge** when an epic is completed and has to be integrated into
|
|
||||||
the main branch. Epic is a more significant piece of work, decoupled in
|
|
||||||
compilable and testable commits. All these commits should be preserved to be
|
|
||||||
able to find potential issues later on.
|
|
||||||
|
|
||||||
* You should use **rebase** when integrating changes from main to an epic
|
|
||||||
branch. The epic branch has to be as clean as possible, avoid pure merge
|
|
||||||
commits. Once you rebase epic on main, all commits on the epic branch will
|
|
||||||
change the hashes. The implications are: 1) you have to force push your local
|
|
||||||
branch to the origin, 2) if you made a task branch out of the epic branch, you
|
|
||||||
would have to use **rebase --onto** (please refer to `git help rebase` for
|
|
||||||
details). In simple cases, **regular merge** should be sufficient to integrate
|
|
||||||
changes from epic to a task branch (that can even be done via GitHub web
|
|
||||||
interface).
|
|
||||||
|
|
||||||
During any code integration, you may get reports that some files have
|
|
||||||
conflicting changes. If you need help resolving them, don't be afraid to ask
|
|
||||||
around! After you've resolved them, mark them as done with `git add` command.
|
|
||||||
You may then continue with `git {{action}} --continue`.
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# Feature Specifications
|
|
||||||
|
|
||||||
* [Python Query Modules](python-query-modules.md)
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
# Distributed Memgraph specs
|
|
||||||
This document describes reasnonings behind Memgraphs distributed concepts.
|
|
||||||
|
|
||||||
## Distributed state machine
|
|
||||||
Memgraphs distributed mode introduces two states of the cluster, recovering and
|
|
||||||
working. The change between states shouldn't happen often, but when it happens
|
|
||||||
it can take a while to make a transition from one to another.
|
|
||||||
|
|
||||||
### Recovering
|
|
||||||
This state is the default state for Memgraph when the cluster starts with
|
|
||||||
recovery flags. If the recovery finishes successfully, the state changes to
|
|
||||||
working. If recovery fails, the user will be presented with a message that
|
|
||||||
explains what happened and what are the next steps.
|
|
||||||
|
|
||||||
Another way to enter this state is failure. If the cluster encounters a failure,
|
|
||||||
the master will enter the Recovering mode. This time, it will wait for all
|
|
||||||
workers to respond with a message saying they are alive and well, and making
|
|
||||||
sure they all have consistent state.
|
|
||||||
|
|
||||||
### Working
|
|
||||||
This state should be the default state of Memgraph most of the time. When in
|
|
||||||
this state, Memgraph accepts connections from Bolt clients and allows query
|
|
||||||
execution.
|
|
||||||
|
|
||||||
If distributed execution fails for a transaction, that transaction, and all
|
|
||||||
other active transactions will be aborted and the cluster will enter the
|
|
||||||
Recovering state.
|
|
||||||
|
|
||||||
## Durability
|
|
||||||
One of the important concepts in distributed Memgraph is durability.
|
|
||||||
|
|
||||||
### Cluster configuration
|
|
||||||
When running Memgraph in distributed mode, the master will store cluster
|
|
||||||
metadata in a persistent store. If fore some reason the cluster shuts down,
|
|
||||||
recovering Memgraph from durability files shouldn't require any additional
|
|
||||||
flags.
|
|
||||||
|
|
||||||
### Database ID
|
|
||||||
Each new and clean run of Memgraph should generate a new globally unique
|
|
||||||
database id. This id will associate all files that have persisted with this
|
|
||||||
run. Adding the database id to snapshots, write-ahead logs and cluster metadata
|
|
||||||
files ties them a specific Memgraph run, and it makes recovery easier to reason
|
|
||||||
about.
|
|
||||||
|
|
||||||
When recovering, the cluster won't generate a new id, but will reuse the one
|
|
||||||
from the snapshot/wal that it was able to recover from.
|
|
||||||
|
|
||||||
### Durability files
|
|
||||||
Memgraph uses snapshots and write-ahead logs for durability.
|
|
||||||
|
|
||||||
When Memgraph recovers it has to make sure all machines in the cluster recover
|
|
||||||
to the same recovery point. This is done by finding a common snapshot and
|
|
||||||
finding common transactions in per-machine available write-ahead logs.
|
|
||||||
|
|
||||||
Since we can not be sure that each machine persisted durability files, we need
|
|
||||||
to be able to negotiate a common recovery point in the cluster. Possible
|
|
||||||
durability file failures could require to start the cluster from scratch,
|
|
||||||
purging everything from storage and recovering from existing durability files.
|
|
||||||
|
|
||||||
We need to ensure that we keep wal files containing information about
|
|
||||||
transactions between all existing snapshots. This will provide better durability
|
|
||||||
in the case of a random machine durability file failure, where the cluster can
|
|
||||||
find a common recovery point that all machines in the cluster have.
|
|
||||||
|
|
||||||
Also, we should suggest and make clear docs that anything less than two
|
|
||||||
snapshots isn't considered safe for recovery.
|
|
||||||
|
|
||||||
### Recovery
|
|
||||||
The recovery happens in following steps:
|
|
||||||
* Master enables worker registration.
|
|
||||||
* Master recovers cluster metadata from the persisted storage.
|
|
||||||
* Master waits all required workers to register.
|
|
||||||
* Master broadcasts a recovery request to all workers.
|
|
||||||
* Workers respond with with a set of possible recovery points.
|
|
||||||
* Master finds a common recovery point for the whole cluster.
|
|
||||||
* Master broadcasts a recovery request with the common recovery point.
|
|
||||||
* Master waits for the cluster to recover.
|
|
||||||
* After a successful cluster recovery, master can enter Working state.
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
# Dynamic Graph Partitioning (abbr. DGP)
|
|
||||||
|
|
||||||
## Implementation
|
|
||||||
|
|
||||||
Take a look under `dev/memgraph/distributed/dynamic_graph_partitioning.md`.
|
|
||||||
|
|
||||||
### Implemented parameters
|
|
||||||
|
|
||||||
--dynamic-graph-partitioner-enabled (If the dynamic graph partitioner should be
|
|
||||||
enabled.) type: bool default: false (start time)
|
|
||||||
--dgp-improvement-threshold (How much better should specific node score be
|
|
||||||
to consider a migration to another worker. This represents the minimal
|
|
||||||
difference between new score that the vertex will have when migrated
|
|
||||||
and the old one such that it's migrated.) type: int32 default: 10
|
|
||||||
(start time)
|
|
||||||
--dgp-max-batch-size (Maximal amount of vertices which should be migrated
|
|
||||||
in one dynamic graph partitioner step.) type: int32 default: 2000
|
|
||||||
(start time)
|
|
||||||
|
|
||||||
## Planning
|
|
||||||
|
|
||||||
### Design decisions
|
|
||||||
|
|
||||||
* Each partitioning session has to be a new transaction.
|
|
||||||
* When and how does an instance perform the moves?
|
|
||||||
* Periodically.
|
|
||||||
* Token sharing (round robin, exactly one instance at a time has an
|
|
||||||
opportunity to perform the moves).
|
|
||||||
* On server-side serialization error (when DGP receives an error).
|
|
||||||
-> Quit partitioning and wait for the next turn.
|
|
||||||
* On client-side serialization error (when end client receives an error).
|
|
||||||
-> The client should never receive an error because of any
|
|
||||||
internal operation.
|
|
||||||
-> For the first implementation, it's good enough to wait until data becomes
|
|
||||||
available again.
|
|
||||||
-> It would be nice to achieve that DGP has lower priority than end client
|
|
||||||
operations.
|
|
||||||
|
|
||||||
### End-user parameters
|
|
||||||
|
|
||||||
* --dynamic-graph-partitioner-enabled (execution time)
|
|
||||||
* --dgp-improvement-threshold (execution time)
|
|
||||||
* --dgp-max-batch-size (execution time)
|
|
||||||
* --dgp-min-batch-size (execution time)
|
|
||||||
-> Minimum number of nodes that will be moved in each step.
|
|
||||||
* --dgp-fitness-threshold (execution time)
|
|
||||||
-> Do not perform moves if partitioning is good enough.
|
|
||||||
* --dgp-delta-turn-time (execution time)
|
|
||||||
-> Time between each turn.
|
|
||||||
* --dgp-delta-step-time (execution time)
|
|
||||||
-> Time between each step.
|
|
||||||
* --dgp-step-time (execution time)
|
|
||||||
-> Time limit per each step.
|
|
||||||
|
|
||||||
### Testing
|
|
||||||
|
|
||||||
The implementation has to provide good enough results in terms of:
|
|
||||||
* How good the partitioning is (numeric value), aka goodness.
|
|
||||||
* Workload execution time.
|
|
||||||
* Stress test correctness.
|
|
||||||
|
|
||||||
Test cases:
|
|
||||||
* N not connected subgraphs
|
|
||||||
-> shuffle nodes to N instances
|
|
||||||
-> run partitioning
|
|
||||||
-> test perfect partitioning.
|
|
||||||
* N connected subgraph
|
|
||||||
-> shuffle nodes to N instance
|
|
||||||
-> run partitioning
|
|
||||||
-> test partitioning.
|
|
||||||
* Take realistic workload (Long Running, LDBC1, LDBC2, Card Fraud, BFS, WSP)
|
|
||||||
-> measure exec time
|
|
||||||
-> run partitioning
|
|
||||||
-> test partitioning
|
|
||||||
-> measure exec time (during and after partitioning).
|
|
||||||
@@ -1,275 +0,0 @@
|
|||||||
# High Availability (abbr. HA)
|
|
||||||
|
|
||||||
## High Level Context
|
|
||||||
|
|
||||||
High availability is a characteristic of a system which aims to ensure a
|
|
||||||
certain level of operational performance for a higher-than-normal period.
|
|
||||||
Although there are multiple ways to design highly available systems, Memgraph
|
|
||||||
strives to achieve HA by elimination of single points of failure. In essence,
|
|
||||||
this implies adding redundancy to the system so that a failure of a component
|
|
||||||
does not imply the failure of the entire system. To ensure this, HA Memgraph
|
|
||||||
implements the [Raft consensus algorithm](https://raft.github.io/).
|
|
||||||
|
|
||||||
Correct implementation of the algorithm guarantees that the cluster will be
|
|
||||||
fully functional (available) as long as any strong majority of the servers are
|
|
||||||
operational and can communicate with each other and with clients. For example,
|
|
||||||
clusters of three or four machines can tolerate the failure of a single server,
|
|
||||||
clusters of five and six machines can tolerate the failure of any two servers,
|
|
||||||
and so on. Therefore, we strongly recommend a setup of an odd-sized cluster.
|
|
||||||
|
|
||||||
### Performance Implications
|
|
||||||
|
|
||||||
Internally, Raft achieves high availability by keeping a consistent replicated
|
|
||||||
log on each server within the cluster. Therefore, we must successfully replicate
|
|
||||||
a transaction on the majority of servers within the cluster before we actually
|
|
||||||
commit it and report the result back to the client. This operation represents
|
|
||||||
a significant performance hit when compared with single node version of
|
|
||||||
Memgraph.
|
|
||||||
|
|
||||||
Luckily, the algorithm can be tweaked in a way which allows read-only
|
|
||||||
transactions to perform significantly better than those which modify the
|
|
||||||
database state. That being said, the performance of read-only operations
|
|
||||||
is still not going to be on par with single node Memgraph.
|
|
||||||
|
|
||||||
This section will be updated with exact numbers once we integrate HA with
|
|
||||||
new storage.
|
|
||||||
|
|
||||||
With the old storage, write throughput was almost five times lower than read
|
|
||||||
throughput (~30000 reads per second vs ~6000 writes per second).
|
|
||||||
|
|
||||||
## User Facing Setup
|
|
||||||
|
|
||||||
### How to Setup HA Memgraph Cluster?
|
|
||||||
|
|
||||||
First, the user needs to install `memgraph_ha` package on each machine
|
|
||||||
in their cluster. HA Memgraph should be available as a Debian package,
|
|
||||||
so its installation on each machine should be as simple as:
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
dpkg -i /path/to/memgraph_ha_<version>.deb
|
|
||||||
```
|
|
||||||
|
|
||||||
After successful installation of the `memgraph_ha` package, the user should
|
|
||||||
finish its configuration before attempting to start the cluster.
|
|
||||||
|
|
||||||
There are two main things that need to be configured on every node in order for
|
|
||||||
the cluster to be able to run:
|
|
||||||
|
|
||||||
1. The user has to edit the main configuration file and specify the unique node
|
|
||||||
ID to each server in the cluster
|
|
||||||
2. The user has to create a file that describes all IP addresses of all servers
|
|
||||||
that will be used in the cluster
|
|
||||||
|
|
||||||
The `memgraph_ha` binary loads all main configuration parameters from
|
|
||||||
`/etc/memgraph/memgraph_ha.conf`. On each node of the cluster, the user should
|
|
||||||
uncomment the `--server-id=0` parameter and change its value to the `server_id`
|
|
||||||
of that node.
|
|
||||||
|
|
||||||
The last step before starting the server is to create a `coordination`
|
|
||||||
configuration file. That file is already present as an example in
|
|
||||||
`/etc/memgraph/coordination.json.example` and you have to copy it to
|
|
||||||
`/etc/memgraph/coordination.json` and edit it according to your cluster
|
|
||||||
configuration. The file contains coordination info consisting of a list of
|
|
||||||
`server_id`, `ip_address` and `rpc_port` lists. The assumed contents of the
|
|
||||||
`coordination.json` file are:
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
[
|
|
||||||
[1, "192.168.0.1", 10000],
|
|
||||||
[2, "192.168.0.2", 10000],
|
|
||||||
[3, "192.168.0.3", 10000]
|
|
||||||
]
|
|
||||||
```
|
|
||||||
Here, each line corresponds to coordination of one server. The first entry is
|
|
||||||
that server's ID, the second is its IP address and the third is the RPC port it
|
|
||||||
listens to. This port should not be confused with the port used for client
|
|
||||||
interaction via the Bolt protocol.
|
|
||||||
|
|
||||||
The `ip_address` entered for each `server_id` *must* match the exact IP address
|
|
||||||
that belongs to that server and that will be used to communicate to other nodes
|
|
||||||
in the cluster. The coordination configuration file *must* be identical on all
|
|
||||||
nodes in the cluster.
|
|
||||||
|
|
||||||
After the user has set the `server_id` on each node in
|
|
||||||
`/etc/memgraph/memgraph_ha.conf` and provided the same
|
|
||||||
`/etc/memgraph/coordination.json` file to each node in the cluster, they can
|
|
||||||
start the Memgraph HA service by issuing the following command on each node in
|
|
||||||
the cluster:
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
systemctl start memgraph_ha
|
|
||||||
```
|
|
||||||
|
|
||||||
### How to Configure Raft Parameters?
|
|
||||||
|
|
||||||
All Raft configuration parameters can be controlled by modifying
|
|
||||||
`/etc/memgraph/raft.json`. The assumed contents of the `raft.json` file are:
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
{
|
|
||||||
"election_timeout_min": 750,
|
|
||||||
"election_timeout_max": 1000,
|
|
||||||
"heartbeat_interval": 100,
|
|
||||||
"replication_timeout": 20000,
|
|
||||||
"log_size_snapshot_threshold": 50000
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The meaning behind each entry is demystified in the following table:
|
|
||||||
|
|
||||||
Flag | Description
|
|
||||||
------------------------------|------------
|
|
||||||
`election_timeout_min` | Lower bound for the randomly sampled reelection timer given in milliseconds
|
|
||||||
`election_timeout_max` | Upper bound for the randomly sampled reelection timer given in milliseconds
|
|
||||||
`heartbeat_interval` | Time interval between consecutive heartbeats given in milliseconds
|
|
||||||
`replication_timeout` | Time interval allowed for data replication given in milliseconds
|
|
||||||
`log_size_snapshot_threshold` | Allowed number of entries in Raft log before its compaction
|
|
||||||
|
|
||||||
### How to Query HA Memgraph via Proxy?
|
|
||||||
|
|
||||||
This chapter describes how to query HA Memgraph using our proxy server.
|
|
||||||
Note that this is not intended to be a long-term solution. Instead, we will
|
|
||||||
implement a proper Memgraph HA client which is capable of communicating with
|
|
||||||
the HA cluster. Once our own client is implemented, it will no longer be
|
|
||||||
possible to query HA Memgraph using other clients (such as neo4j client).
|
|
||||||
|
|
||||||
The Bolt protocol that is exposed by each Memgraph HA node is an extended
|
|
||||||
version of the standard Bolt protocol. In order to be able to communicate with
|
|
||||||
the highly available cluster of Memgraph HA nodes, the client must have some
|
|
||||||
logic implemented in itself so that it can communicate correctly with all nodes
|
|
||||||
in the cluster. To facilitate a faster start with the HA cluster we will build
|
|
||||||
the Memgraph HA proxy binary that communicates with all nodes in the HA cluster
|
|
||||||
using the extended Bolt protocol and itself exposes a standard Bolt protocol to
|
|
||||||
the user. All standard Bolt clients (libraries and custom systems) can
|
|
||||||
communicate with the Memgraph HA proxy without any code modifications.
|
|
||||||
|
|
||||||
The HA proxy should be deployed on each client machine that is used to
|
|
||||||
communicate with the cluster. It can't be deployed on the Memgraph HA nodes!
|
|
||||||
|
|
||||||
When using the Memgraph HA proxy, the communication flow is described in the
|
|
||||||
following diagram:
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
Memgraph HA node 1 -----+
|
|
||||||
|
|
|
||||||
Memgraph HA node 2 -----+ Memgraph HA proxy <---> any standard Bolt client (C, Java, PHP, Python, etc.)
|
|
||||||
|
|
|
||||||
Memgraph HA node 3 -----+
|
|
||||||
```
|
|
||||||
|
|
||||||
To setup the Memgraph HA proxy the user should install the `memgraph_ha_proxy`
|
|
||||||
package.
|
|
||||||
|
|
||||||
After its successful installation, the user should enter all endpoints of the
|
|
||||||
HA Memgraph cluster servers into the configuration before attempting to start
|
|
||||||
the HA Memgraph proxy server.
|
|
||||||
|
|
||||||
The HA Memgraph proxy server loads all of its configuration from
|
|
||||||
`/etc/memgraph/memgraph_ha_proxy.conf`. Assuming that the cluster is set up
|
|
||||||
like in the previous examples, the user should uncomment and enter the following
|
|
||||||
value into the `--endpoints` parameter:
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
--endpoints=192.168.0.1:7687,192.168.0.2:7687,192.168.0.3:7687
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that the IP addresses used in the example match the individual cluster
|
|
||||||
nodes IP addresses, but the ports used are the Bolt server ports exposed by
|
|
||||||
each node (currently the default value of `7687`).
|
|
||||||
|
|
||||||
The user can now start the proxy by using the following command:
|
|
||||||
|
|
||||||
```plaintext
|
|
||||||
systemctl start memgraph_ha_proxy
|
|
||||||
```
|
|
||||||
|
|
||||||
After the proxy has been started, the user can query the HA cluster by
|
|
||||||
connecting to the HA Memgraph proxy IP address using their favorite Bolt
|
|
||||||
client.
|
|
||||||
|
|
||||||
## Integration with Memgraph
|
|
||||||
|
|
||||||
The first thing that should be defined is a single instruction within the
|
|
||||||
context of Raft (i.e. a single entry in a replicated log).
|
|
||||||
These instructions should be completely deterministic when applied
|
|
||||||
to the state machine. We have therefore decided that the appropriate level
|
|
||||||
of abstraction within Memgraph corresponds to `Delta`s (data structures
|
|
||||||
which describe a single change to the Memgraph state, used for durability
|
|
||||||
in WAL). Moreover, a single instruction in a replicated log will consist of a
|
|
||||||
batch of `Delta`s which correspond to a single transaction that's about
|
|
||||||
to be **committed**.
|
|
||||||
|
|
||||||
Apart from `Delta`s, there are certain operations within the storage called
|
|
||||||
`StorageGlobalOperations` which do not conform to usual transactional workflow
|
|
||||||
(e.g. Creating indices). Since our storage engine implementation guarantees
|
|
||||||
that at the moment of their execution no other transactions are active, we can
|
|
||||||
safely replicate them as well. In other words, no additional logic needs to be
|
|
||||||
implemented because of them.
|
|
||||||
|
|
||||||
Therefore, we will introduce a new `RaftDelta` object which can be constructed
|
|
||||||
both from storage `Delta` and `StorageGlobalOperation`. Instead of appending
|
|
||||||
these to WAL (as we do in single node), we will start to replicate them across
|
|
||||||
our cluster. Once we have replicated the corresponding Raft log entry on
|
|
||||||
majority of the cluster, we are able to safely commit the transaction or execute
|
|
||||||
a global operation. If for any reason the replication fails (leadership change,
|
|
||||||
worker failures, etc.) the transaction will be aborted.
|
|
||||||
|
|
||||||
In the follower mode, we need to be able to apply `RaftDelta`s we got from
|
|
||||||
the leader when the protocol allows us to do so. In that case, we will use the
|
|
||||||
same concepts from durability in storage v2, i.e., applying deltas maps
|
|
||||||
completely to recovery from WAL in storage v2.
|
|
||||||
|
|
||||||
## Test and Benchmark Strategy
|
|
||||||
|
|
||||||
We have already implemented some integration and stress tests. These are:
|
|
||||||
|
|
||||||
1. leader election -- Tests whether leader election works properly.
|
|
||||||
2. basic test -- Tests basic leader election and log replication.
|
|
||||||
3. term updates test -- Tests a specific corner case (which used to fail)
|
|
||||||
regarding term updates.
|
|
||||||
4. log compaction test -- Tests whether log compaction works properly.
|
|
||||||
5. large log entries -- Tests whether we can successfully replicate relatively
|
|
||||||
large log entries.
|
|
||||||
6. index test -- Tests whether index creation works in HA.
|
|
||||||
7. normal operation stress test -- Long running concurrent stress test under
|
|
||||||
normal conditions (no failures).
|
|
||||||
8. read benchmark -- Measures read throughput in HA.
|
|
||||||
9. write benchmark -- Measures write throughput in HA.
|
|
||||||
|
|
||||||
At the moment, our main goal is to pass existing tests and have a stable version
|
|
||||||
on our stress test. We should also implement a stress test which occasionally
|
|
||||||
introduces different types of failures in our cluster (we did this kind of
|
|
||||||
testing manually thus far). Passing these tests should convince us that we have
|
|
||||||
a "stable enough" version which we can start pushing to our customers.
|
|
||||||
|
|
||||||
Additional (proper) testing should probably involve some ideas from
|
|
||||||
[here](https://jepsen.io/analyses/dgraph-1-0-2)
|
|
||||||
|
|
||||||
## Possible Future Changes/Improvements/Extensions
|
|
||||||
|
|
||||||
There are two general directions in which we can alter HA Memgraph. The first
|
|
||||||
direction assumes we are going to stick with the Raft protocol. In that case
|
|
||||||
there are a few known ways to extend the basic algorithm in order to gain
|
|
||||||
better performance or achieve extra functionality. In no particular order,
|
|
||||||
these are:
|
|
||||||
|
|
||||||
1. Improving read performance using leader leases [Section 6.4 from Raft thesis]
|
|
||||||
2. Introducing cluster membership changes [Chapter 4 from Raft thesis]
|
|
||||||
3. Introducing a [learner mode](https://etcd.io/docs/v3.3.12/learning/learner/).
|
|
||||||
4. Consider different log compaction strategies [Chapter 5 from Raft thesis]
|
|
||||||
5. Removing HA proxy and implementing our own HA Memgraph client.
|
|
||||||
|
|
||||||
On the other hand, we might decide in the future to base our HA implementation
|
|
||||||
on a completely different protocol which might even offer different guarantees.
|
|
||||||
In that case we probably need to do a bit more of market research and weigh the
|
|
||||||
trade-offs of different solutions.
|
|
||||||
[This](https://www.postgresql.org/docs/9.5/different-replication-solutions.html)
|
|
||||||
might be a good starting point.
|
|
||||||
|
|
||||||
## Reading materials
|
|
||||||
|
|
||||||
1. [Raft paper](https://raft.github.io/raft.pdf)
|
|
||||||
2. [Raft thesis](https://github.com/ongardie/dissertation) (book.pdf)
|
|
||||||
3. [Raft playground](https://raft.github.io/)
|
|
||||||
4. [Leader Leases](https://blog.yugabyte.com/low-latency-reads-in-geo-distributed-sql-with-raft-leader-leases/)
|
|
||||||
5. [Improving Raft ETH](https://pub.tik.ee.ethz.ch/students/2017-FS/SA-2017-80.pdf)
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
# Kafka - openCypher clause
|
|
||||||
|
|
||||||
One must be able to specify the following when importing data from Kafka:
|
|
||||||
|
|
||||||
* Kafka URI
|
|
||||||
* Kafka topic
|
|
||||||
* Transform [script](transform.md) URI
|
|
||||||
|
|
||||||
|
|
||||||
Minimum required syntax looks like:
|
|
||||||
```opencypher
|
|
||||||
CREATE STREAM stream_name AS LOAD DATA KAFKA 'URI'
|
|
||||||
WITH TOPIC 'topic'
|
|
||||||
WITH TRANSFORM 'URI';
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
The full openCypher clause for creating a stream is:
|
|
||||||
```opencypher
|
|
||||||
CREATE STREAM stream_name AS
|
|
||||||
LOAD DATA KAFKA 'URI'
|
|
||||||
WITH TOPIC 'topic'
|
|
||||||
WITH TRANSFORM 'URI'
|
|
||||||
[BATCH_INTERVAL milliseconds]
|
|
||||||
[BATCH_SIZE count]
|
|
||||||
```
|
|
||||||
The `CREATE STREAM` clause happens in a transaction.
|
|
||||||
|
|
||||||
`WITH TOPIC` parameter specifies the Kafka topic from which we'll stream
|
|
||||||
data.
|
|
||||||
|
|
||||||
`WITH TRANSFORM` parameter should contain a URI of the transform script.
|
|
||||||
|
|
||||||
`BATCH_INTERVAL` parameter defines the time interval in milliseconds
|
|
||||||
which is the time between two successive stream importing operations.
|
|
||||||
|
|
||||||
`BATCH_SIZE` parameter defines the count of Kafka messages that will be
|
|
||||||
batched together before import.
|
|
||||||
|
|
||||||
If both `BATCH_INTERVAL` and `BATCH_SIZE` parameters are given, the condition
|
|
||||||
that is satisfied first will trigger the batched import.
|
|
||||||
|
|
||||||
Default value for `BATCH_INTERVAL` is 100 milliseconds, and the default value
|
|
||||||
for `BATCH_SIZE` is 10;
|
|
||||||
|
|
||||||
The `DROP` clause deletes a stream:
|
|
||||||
```opencypher
|
|
||||||
DROP STREAM stream_name;
|
|
||||||
```
|
|
||||||
|
|
||||||
The `SHOW` clause enables you to see all configured streams:
|
|
||||||
```opencypher
|
|
||||||
SHOW STREAMS;
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also start/stop streams with the `START` and `STOP` clauses:
|
|
||||||
```opencypher
|
|
||||||
START STREAM stream_name [LIMIT count BATCHES];
|
|
||||||
STOP STREAM stream_name;
|
|
||||||
```
|
|
||||||
A stream needs to be stopped in order to start it and it needs to be started in
|
|
||||||
order to stop it. Starting a started or stopping a stopped stream will not
|
|
||||||
affect that stream.
|
|
||||||
|
|
||||||
There are also convenience clauses to start and stop all streams:
|
|
||||||
```opencypher
|
|
||||||
START ALL STREAMS;
|
|
||||||
STOP ALL STREAMS;
|
|
||||||
```
|
|
||||||
|
|
||||||
Before the actual import, you can also test the stream with the `TEST
|
|
||||||
STREAM` clause:
|
|
||||||
```opencypher
|
|
||||||
TEST STREAM stream_name [LIMIT count BATCHES];
|
|
||||||
```
|
|
||||||
When a stream is tested, data extraction and transformation occurs, but no
|
|
||||||
output is inserted in the graph.
|
|
||||||
|
|
||||||
A stream needs to be stopped in order to test it. When the batch limit is
|
|
||||||
omitted, `TEST STREAM` will run for only one batch by default.
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
# Kafka - data transform
|
|
||||||
|
|
||||||
The transform script is a user defined script written in Python. The script
|
|
||||||
should be aware of the data format in the Kafka message.
|
|
||||||
|
|
||||||
Each Kafka message is byte length encoded, which means that the first eight
|
|
||||||
bytes of each message contain the length of the message.
|
|
||||||
|
|
||||||
A sample code for a streaming transform script could look like this:
|
|
||||||
|
|
||||||
```python
|
|
||||||
def create_vertex(vertex_id):
|
|
||||||
return ("CREATE (:Node {id: $id})", {"id": vertex_id})
|
|
||||||
|
|
||||||
|
|
||||||
def create_edge(from_id, to_id):
|
|
||||||
return ("MATCH (n:Node {id: $from_id}), (m:Node {id: $to_id}) "\
|
|
||||||
"CREATE (n)-[:Edge]->(m)", {"from_id": from_id, "to_id": to_id})
|
|
||||||
|
|
||||||
|
|
||||||
def stream(batch):
|
|
||||||
result = []
|
|
||||||
for item in batch:
|
|
||||||
message = item.decode('utf-8').strip().split()
|
|
||||||
if len(message) == 1:
|
|
||||||
result.append(create_vertex(message[0])))
|
|
||||||
else:
|
|
||||||
result.append(create_edge(message[0], message[1]))
|
|
||||||
return result
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
The script should output openCypher query strings based on the type of the
|
|
||||||
records.
|
|
||||||
@@ -1,185 +0,0 @@
|
|||||||
# Python 3 Query Modules
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
Memgraph exposes a C API for writing the so called Query Modules. These
|
|
||||||
modules contain definitions of procedures which can be invoked through the
|
|
||||||
query language using the `CALL ... YIELD ...` syntax. This mechanism allows
|
|
||||||
database users to extend Memgraph with their own algorithms and
|
|
||||||
functionalities.
|
|
||||||
|
|
||||||
Using a low level language like C can be quite cumbersome for writing modules,
|
|
||||||
so it seems natural to add support for a higher level language on top of the
|
|
||||||
existing C API.
|
|
||||||
|
|
||||||
There are languages written exactly for this purpose of extending C with high
|
|
||||||
level constructs, for example Lua and Guile. Instead of those, we have chosen
|
|
||||||
Python 3 to be the first high level language we will support. The primary reason
|
|
||||||
being that it's very popular, so more people should be able to write modules.
|
|
||||||
Another benefit of Python which comes out of its popularity is the large
|
|
||||||
ecosystem of libraries, especially graph algorithm related ones like NetworkX.
|
|
||||||
Python does have significant performance and implementation downsides compared
|
|
||||||
to Lua and Guile, but these are described in more detail later in this
|
|
||||||
document.
|
|
||||||
|
|
||||||
## Python 3 API Overview
|
|
||||||
|
|
||||||
The Python 3 API should be as user friendly as possible as well as look
|
|
||||||
Pythonic. This implies that some functions from the C API will not map to the
|
|
||||||
exact same functions. The most obvious case for a Pythonic approach is
|
|
||||||
registering procedures of a query module. Let's take a look at the C example
|
|
||||||
and its transformation to Python.
|
|
||||||
|
|
||||||
```c
|
|
||||||
static void procedure(const struct mgp_list *args,
|
|
||||||
const struct mgp_graph *graph, struct mgp_result *result,
|
|
||||||
struct mgp_memory *memory);
|
|
||||||
|
|
||||||
int mgp_init_module(struct mgp_module *module, struct mgp_memory *memory) {
|
|
||||||
struct mgp_proc *proc =
|
|
||||||
mgp_module_add_read_procedure(module, "procedure", procedure);
|
|
||||||
if (!proc) return 1;
|
|
||||||
if (!mgp_proc_add_arg(proc, "required_arg",
|
|
||||||
mgp_type_nullable(mgp_type_any())))
|
|
||||||
return 1;
|
|
||||||
struct mgp_value *null_value = mgp_value_make_null(memory);
|
|
||||||
if (!mgp_proc_add_opt_arg(proc, "optional_arg",
|
|
||||||
mgp_type_nullable(mgp_type_any()), null_value)) {
|
|
||||||
mgp_value_destroy(null_value);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
mgp_value_destroy(null_value);
|
|
||||||
if (!mgp_proc_add_result(proc, "result", mgp_type_string())) return 1;
|
|
||||||
if (!mgp_proc_add_result(proc, "args",
|
|
||||||
mgp_type_list(mgp_type_nullable(mgp_type_any()))))
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
In Python things should be a lot simpler.
|
|
||||||
|
|
||||||
```Python
|
|
||||||
# mgp.read_proc obtains the procedure name via __name__ attribute of a function.
|
|
||||||
@mgp.read_proc(# Arguments passed to multiple mgp_proc_add_arg calls
|
|
||||||
(('required_arg', mgp.Nullable(mgp.Any)), ('optional_arg', mgp.Nullable(mgp.Any), None)),
|
|
||||||
# Result fields passed to multiple mgp_proc_add_result calls
|
|
||||||
(('result', str), ('args', mgp.List(mgp.Nullable(mgp.Any)))))
|
|
||||||
def procedure(args, graph, result, memory):
|
|
||||||
pass
|
|
||||||
```
|
|
||||||
|
|
||||||
Here we have replaced `mgp_module_*` and `mgp_proc_*` C API with a much
|
|
||||||
simpler decorator function in Python -- `mgp.read_proc`. The types of
|
|
||||||
arguments and result fields can both be our types as well as Python builtin
|
|
||||||
types which can map to supported `mgp_value` types. The expected builtin types
|
|
||||||
we ought to support are: `bool`, `str`, `int`, `float` and `map`. While the
|
|
||||||
rest of the types are provided via our Python API. Optionally, we can add
|
|
||||||
convenience support for `object` type which would map to
|
|
||||||
`mgp.Nullable(mgp.Any)` and `list` which would map to
|
|
||||||
`mgp.List(mgp.Nullable(mgp.Any))`. Also, it makes sense to take a look if we
|
|
||||||
can leverage Python's `typing` module here.
|
|
||||||
|
|
||||||
Another Pythonic change is to remove `mgp_value` C API from Python altogether.
|
|
||||||
This means that the arguments a Python procedure receives are not `mgp_value`
|
|
||||||
instances but rather `PyObject` instances. In other words, our implementation
|
|
||||||
would immediately marshal `mgp_value` to corresponding type in Python.
|
|
||||||
Obviously we would need to provide our own Python types for non-builtin
|
|
||||||
things like `mgp.Vertex` (equivalent to `mgp_vertex`) and other.
|
|
||||||
|
|
||||||
Continuing from our example above, let's say the procedure was invoked through
|
|
||||||
Cypher using the following query.
|
|
||||||
|
|
||||||
MATCH (n) CALL py_module.procedure(42, n) YIELD *;
|
|
||||||
|
|
||||||
The Python procedure could then do the following and complete without throwing
|
|
||||||
neither the AssertionError nor the ValueError.
|
|
||||||
|
|
||||||
```Python
|
|
||||||
def procedure(args, graph, result, memory):
|
|
||||||
assert isinstance(args, list)
|
|
||||||
# Unpacking throws ValueError if args does not contain exactly 2 values.
|
|
||||||
required_arg, optional_arg = args
|
|
||||||
assert isintance(required_arg, int)
|
|
||||||
assert isinstance(optional_arg, mgp.Vertex)
|
|
||||||
```
|
|
||||||
|
|
||||||
The rest of the C API should naturally map to either top level functions or
|
|
||||||
class methods as appropriate.
|
|
||||||
|
|
||||||
## Loading Python Query Modules
|
|
||||||
|
|
||||||
Our current mechanism for loading the modules is to look for `.so` files in
|
|
||||||
the directory specified by `--query-modules` flag. This is done when Memgraph
|
|
||||||
is started. We can extend this mechanism to look for `.py` files in addition
|
|
||||||
to `.so` files in the same directory and import them in the embedded Python
|
|
||||||
interpreter. The only issue is embedding the interpreter in Memgraph. There
|
|
||||||
are multiple choices:
|
|
||||||
|
|
||||||
1. Building Memgraph and statically linking to Python.
|
|
||||||
2. Building Memgraph and dynamically linking to Python, and distributing
|
|
||||||
Python with Memgraph's installation.
|
|
||||||
3. Building Memgraph and dynamically linking to Python, but without
|
|
||||||
distributing the Python library.
|
|
||||||
4. Building Memgraph and optionally loading Python library by trying to
|
|
||||||
`dlopen` it.
|
|
||||||
|
|
||||||
The first two options are only viable if the Python license allows, and this
|
|
||||||
will need further investigation.
|
|
||||||
|
|
||||||
The third option adds Python as an installation dependency for Memgraph, and
|
|
||||||
without it Memgraph will not run. This is problematic for users which cannot
|
|
||||||
or do not want to install Python 3.
|
|
||||||
|
|
||||||
The fourth option avoids all of the issues present in the first 3 options, but
|
|
||||||
comes at a higher implementation cost. We would need to try to `dlopen` the
|
|
||||||
Python library and setup function pointers. If we succeed we would import
|
|
||||||
`.py` files from the `--query-modules` directory. On the other hand, if the
|
|
||||||
user does not have Python, `dlopen` would fail and Memgraph would run without
|
|
||||||
Python support.
|
|
||||||
|
|
||||||
After live discussion, we've decided to go with option 3. This way we don't
|
|
||||||
have to worry about mismatching Python versions we support and what the users
|
|
||||||
expect. Also, we should target Python 3.5 as that should be common between
|
|
||||||
Debian and CentOS for which we ship installation packages.
|
|
||||||
|
|
||||||
## Performance and Implementation Problems
|
|
||||||
|
|
||||||
As previously mentioned, embedding Python introduces usability issues compared
|
|
||||||
to other embeddable languages.
|
|
||||||
|
|
||||||
The first, major issue is Global Interpreter Lock (GIL). Initializing Python
|
|
||||||
will start a single global interpreter and running multiple threads will
|
|
||||||
require acquiring GIL. In practice, this means that when multiple users run a
|
|
||||||
procedure written in Python in parallel the execution will not actually be
|
|
||||||
parallel. Python's interpreter will jump between executing one user's
|
|
||||||
procedure and the other's. This can be quite an issue for long running
|
|
||||||
procedures when multiple users are querying Memgraph. The solution for this
|
|
||||||
issue is Python's API for sub-interpreters. Unfortunately, the support for
|
|
||||||
them is rather poor and the API contains a lot of critical bugs when we tried
|
|
||||||
to use them. For the time being, we will have to accept GIL and its downsides.
|
|
||||||
Perhaps in the future we will gain more knowledge on how we could reduce the
|
|
||||||
acquire rate of GIL or the sub-interpreter API will get improved.
|
|
||||||
|
|
||||||
Another major issue is memory allocation. Python's C API does not have support
|
|
||||||
for setting up a temporary allocator during execution of a single function.
|
|
||||||
It only has support for setting up a global heap allocator. This obviously
|
|
||||||
impacts our control of memory during a query procedure invocation. Besides
|
|
||||||
potential performance penalty, a procedure could allocate much more memory
|
|
||||||
than we would actually allow for execution of a single query. This means that
|
|
||||||
options controlling the memory limit during query execution are useless. On
|
|
||||||
the bright side, Python does use block style allocators and reference
|
|
||||||
counting, so the performance penalty and global memory usage should not be
|
|
||||||
that terrible.
|
|
||||||
|
|
||||||
The final issue that isn't as major as the ones above is the global state of
|
|
||||||
the interpreter. In practice this means that any registered procedure and
|
|
||||||
imported module has access to any other procedure and module. This may pollute
|
|
||||||
the namespace for other users, but it should not be much of a problem because
|
|
||||||
Python always has things under a module scope. The other, slightly bigger
|
|
||||||
downside is that a malicious user could use this knowledge to modify other
|
|
||||||
modules and procedures. This seems like a major issue, but if we take the
|
|
||||||
bigger picture into consideration, we already have a security issue in general
|
|
||||||
by invoking `dlopen` on `.so` and potentially running arbitrary code. This was
|
|
||||||
the trade off we chose to allow users to extend Memgraph. It's up to the users
|
|
||||||
to write sane extensions and protect their servers from access.
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
# Tensorflow Op - Technicalities
|
|
||||||
|
|
||||||
The final result should be a shared object (".so") file that can be
|
|
||||||
dynamically loaded by the Tensorflow runtime in order to directly
|
|
||||||
access the bolt client.
|
|
||||||
|
|
||||||
## About Tensorflow
|
|
||||||
|
|
||||||
Tensorflow is usually used with Python such that the Python code is used
|
|
||||||
to define a directed acyclic computation graph. Basically no computation
|
|
||||||
is done in Python. Instead, values from Python are copied into the graph
|
|
||||||
structure as constants to be used by other Ops. The directed acyclic graph
|
|
||||||
naturally ends up with two sets of border nodes, one for inputs, one for
|
|
||||||
outputs. These are sometimes called "feeds".
|
|
||||||
|
|
||||||
Following the Python definition of the graph, during training, the entire
|
|
||||||
data processing graph/pipeline is called from Python as a single expression.
|
|
||||||
This leads to lazy evaluation since the called result has already been
|
|
||||||
defined for a while.
|
|
||||||
|
|
||||||
Tensorflow internally works with tensors, i.e. n-dimensional arrays. That
|
|
||||||
means all of its inputs need to be matrices as well as its outputs. While
|
|
||||||
it is possible to feed data directly from Python's numpy matrices straight
|
|
||||||
into Tensorflow, this is less desirable than using the Tensorflow data API
|
|
||||||
(which defines data input and processing as a Tensorflow graph) because:
|
|
||||||
|
|
||||||
1. The data API is written in C++ and entirely avoids Python and as such
|
|
||||||
is faster
|
|
||||||
2. The data API, unlike Python is available in "Tensorflow serving". The
|
|
||||||
default way to serve Tensorflow models in production.
|
|
||||||
|
|
||||||
Once the entire input pipeline is defined via the tf.data API, its input
|
|
||||||
is basically a list of node IDs the model is supposed to work with. The
|
|
||||||
model, through the data API knows how to connect to Memgraph and execute
|
|
||||||
openCypher queries in order to get the remaining data it needs.
|
|
||||||
(For example features of neighbouring nodes.)
|
|
||||||
|
|
||||||
## The Interface
|
|
||||||
|
|
||||||
I think it's best you read the official guide...
|
|
||||||
<https://www.tensorflow.org/extend/adding_an_op>
|
|
||||||
And especially the addition that specifies how data ops are special
|
|
||||||
<https://www.tensorflow.org/extend/new_data_formats>
|
|
||||||
|
|
||||||
## Compiling the TF Op
|
|
||||||
|
|
||||||
There are two options for compiling a custom op.
|
|
||||||
One of them involves pulling the TF source, adding your code to it and
|
|
||||||
compiling via bazel.
|
|
||||||
This is probably awkward to do for us and would
|
|
||||||
significantly slow down compilation.
|
|
||||||
|
|
||||||
The other method involves installing Tensorflow as a Python package and
|
|
||||||
pulling the required headers from for example:
|
|
||||||
`/usr/local/lib/python3.6/site-packages/tensorflow/include`
|
|
||||||
We can then compile our Op with our regular build system.
|
|
||||||
|
|
||||||
This is practical since we can copy the required headers to our repo.
|
|
||||||
If necessary, we can have several versions of the headers to build several
|
|
||||||
versions of our Op for every TF version which we want to support.
|
|
||||||
(But this is unlikely to be required as the API should be stable).
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
# Example for Using the Bolt Client Tensorflow Op
|
|
||||||
|
|
||||||
## Dynamic Loading
|
|
||||||
|
|
||||||
``` python3
|
|
||||||
import tensorflow as tf
|
|
||||||
|
|
||||||
mg_ops = tf.load_op_library('/usr/bin/memgraph/tensorflow_ops.so')
|
|
||||||
```
|
|
||||||
|
|
||||||
## Basic Usage
|
|
||||||
|
|
||||||
``` python3
|
|
||||||
dataset = mg_ops.OpenCypherDataset(
|
|
||||||
# This is probably unfortunate as the username and password
|
|
||||||
# get hardcoded into the graph, but for the simple case it's fine
|
|
||||||
"hostname:7687", auth=("user", "pass"),
|
|
||||||
|
|
||||||
# Our query
|
|
||||||
'''
|
|
||||||
MATCH (n:Train) RETURN n.id, n.features
|
|
||||||
''',
|
|
||||||
|
|
||||||
# Cast return values to these types
|
|
||||||
(tf.string, tf.float32))
|
|
||||||
|
|
||||||
# Some Tensorflow data api boilerplate
|
|
||||||
iterator = dataset.make_one_shot_iterator()
|
|
||||||
next_element = iterator.get_next()
|
|
||||||
|
|
||||||
# Up to now we have only defined our computation graph which basically
|
|
||||||
# just connects to Memgraph
|
|
||||||
# `next_element` is not really data but a handle to a node in the Tensorflow
|
|
||||||
# graph, which we can and do evaluate
|
|
||||||
# It is a Tensorflow tensor with shape=(None, 2)
|
|
||||||
# and dtype=(tf.string, tf.float)
|
|
||||||
# shape `None` means the shape of the tensor is unknown at definition time
|
|
||||||
# and is dynamic and will only be known once the tensor has been evaluated
|
|
||||||
|
|
||||||
with tf.Session() as sess:
|
|
||||||
node_ids = sess.run(next_element)
|
|
||||||
# `node_ids` contains IDs and features of all the nodes
|
|
||||||
# in the graph with the label "Train"
|
|
||||||
# It is a numpy.ndarray with a shape ($n_matching_nodes, 2)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Memgraph Client as a Generic Tensorflow Op
|
|
||||||
|
|
||||||
Other than the Tensorflow Data Op, we'll want to support a generic Tensorflow
|
|
||||||
Op which can be put anywhere in the Tensorflow computation Graph. It takes in
|
|
||||||
an arbitrary tensor and produces a tensor. This would be used in the GraphSage
|
|
||||||
algorithm to fetch the lowest level features into Tensorflow
|
|
||||||
|
|
||||||
```python3
|
|
||||||
requested_ids = np.array([1, 2, 3])
|
|
||||||
ids_placeholder = tf.placeholder(tf.int32)
|
|
||||||
|
|
||||||
model = mg_ops.OpenCypher()
|
|
||||||
"hostname:7687", auth=("user", "pass"),
|
|
||||||
"""
|
|
||||||
UNWIND $node_ids as nid
|
|
||||||
MATCH (n:Train {id: nid})
|
|
||||||
RETURN n.features
|
|
||||||
""",
|
|
||||||
|
|
||||||
# What to call the input tensor as an openCypher parameter
|
|
||||||
parameter_name="node_ids",
|
|
||||||
|
|
||||||
# Type of our resulting tensor
|
|
||||||
dtype=(tf.float32)
|
|
||||||
)
|
|
||||||
|
|
||||||
features = model(ids_placeholder)
|
|
||||||
|
|
||||||
with tf.Session() as sess:
|
|
||||||
result = sess.run(features,
|
|
||||||
feed_dict={ids_placeholder: requested_ids})
|
|
||||||
```
|
|
||||||
|
|
||||||
This is probably easier to implement than the Data Op, so it might be a good
|
|
||||||
idea to start with.
|
|
||||||
|
|
||||||
## Production Usage
|
|
||||||
|
|
||||||
During training, in the GraphSage algorithm at least, Memgraph is at the
|
|
||||||
beginning and at the end of the Tensorflow computation graph.
|
|
||||||
At the beginning, the Data Op provides the node IDs which are fed into the
|
|
||||||
generic Tensorflow Op to find their neighbours and their neighbours and
|
|
||||||
their features.
|
|
||||||
|
|
||||||
Production usage differs in that we don't use the Data Op. The Data Op is
|
|
||||||
effectively cut off and the initial input is fed by Tensorflow serving,
|
|
||||||
with the data found in the request.
|
|
||||||
|
|
||||||
For example a JSON request to classify a node might look like:
|
|
||||||
|
|
||||||
`POST http://host:port/v1/models/GraphSage/versions/v1:classify`
|
|
||||||
|
|
||||||
With the contents:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"examples": [
|
|
||||||
{"node_id": 1},
|
|
||||||
{"node_id": 2}
|
|
||||||
],
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Every element of the "examples" list is an example to be computed. Each is
|
|
||||||
represented by a dict with keys matching names of feeds in the Tensorflow
|
|
||||||
graph and values being the values we want fed in for each example
|
|
||||||
|
|
||||||
The REST API then replies in kind with the classification result in JSON
|
|
||||||
|
|
||||||
Note about adding our custom Op to Tensorflow serving.
|
|
||||||
Our Ops .so can be added into the Bazel build to link with Tensorflow serving
|
|
||||||
or it can be dynamically loaded by starting Tensorflow serving with a flag
|
|
||||||
`--custom_op_paths`
|
|
||||||
|
|
||||||
## Considerations
|
|
||||||
|
|
||||||
There might be issues here that the url to connect to Memgraph is
|
|
||||||
hardcoded into the op and would thus be wrong when moved to production,
|
|
||||||
requiring some type of a hack to make work. We probably want to solve
|
|
||||||
this by having the client op take in another tf.Variable as an input
|
|
||||||
which would contain a connection url and username/password.
|
|
||||||
We have to research whether this makes it easy enough to move to
|
|
||||||
production, as the connection string variable is still a part of the
|
|
||||||
graph, but maybe easier to replace.
|
|
||||||
|
|
||||||
It is probably the best idea to utilize openCypher parameters to make
|
|
||||||
our queries flexible. The exact API as to how to declare the parameters
|
|
||||||
in Python is open to discussion.
|
|
||||||
|
|
||||||
The Data Op might not even be necessary to implement as it is not
|
|
||||||
key for production use. It can be replaced in training mode with
|
|
||||||
feed dicts and either
|
|
||||||
|
|
||||||
1. Getting the initial list of nodes via a Python Bolt client
|
|
||||||
2. Creating a separate Tensorflow computation graph that gets all the
|
|
||||||
relevant node IDs into Python
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
# Memgraph LaTeX Beamer Template
|
|
||||||
|
|
||||||
This folder contains all of the needed files for creating a presentation with
|
|
||||||
Memgraph styling. You should use this style for any public presentations.
|
|
||||||
|
|
||||||
Feel free to improve it according to style guidelines and raise issues if you
|
|
||||||
find any.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Copy the contents of this folder (excluding this README file) to where you
|
|
||||||
want to write your own presentation. After copying, you can start editing the
|
|
||||||
`template.tex` with your content.
|
|
||||||
|
|
||||||
To compile the presentation to a PDF, run `latexmk -pdf -xelatex`. Some
|
|
||||||
directives require XeLaTeX, so you need to pass `-xelatex` as the final option
|
|
||||||
of `latexmk`. You may also need to install some packages if the compilation
|
|
||||||
complains about missing packages.
|
|
||||||
|
|
||||||
To clean up the generated files, use `latexmk -C`. This will also delete the
|
|
||||||
generated PDF. If you wish to remove generated files except the PDF, use
|
|
||||||
`latexmk -c`.
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
\NeedsTeXFormat{LaTeX2e}
|
|
||||||
\ProvidesClass{mg-beamer}[2018/03/26 Memgraph Beamer]
|
|
||||||
|
|
||||||
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{beamer}}
|
|
||||||
|
|
||||||
\ProcessOptions \relax
|
|
||||||
|
|
||||||
\LoadClass{beamer}
|
|
||||||
|
|
||||||
\usetheme{Pittsburgh}
|
|
||||||
|
|
||||||
% Memgraph color palette
|
|
||||||
\definecolor{mg-purple}{HTML}{720096}
|
|
||||||
\definecolor{mg-red}{HTML}{DD2222}
|
|
||||||
\definecolor{mg-orange}{HTML}{FB6E00}
|
|
||||||
\definecolor{mg-yellow}{HTML}{FFC500}
|
|
||||||
\definecolor{mg-gray}{HTML}{857F87}
|
|
||||||
\definecolor{mg-black}{HTML}{231F20}
|
|
||||||
|
|
||||||
\RequirePackage{fontspec}
|
|
||||||
% Title fonts
|
|
||||||
\setbeamerfont{frametitle}{family={\fontspec[Path = ./mg-style/fonts/]{EncodeSansSemiCondensed-Regular.ttf}}}
|
|
||||||
\setbeamerfont{title}{family={\fontspec[Path = ./mg-style/fonts/]{EncodeSansSemiCondensed-Regular.ttf}}}
|
|
||||||
% Body font
|
|
||||||
\RequirePackage[sfdefault,light]{roboto}
|
|
||||||
% Roboto is pretty bad for monospace font. We will find a replacement.
|
|
||||||
% \setmonofont{RobotoMono-Regular.ttf}[Path = ./mg-style/fonts/]
|
|
||||||
|
|
||||||
% Title slide styles
|
|
||||||
% \setbeamerfont{frametitle}{size=\huge}
|
|
||||||
% \setbeamerfont{title}{size=\huge}
|
|
||||||
% \setbeamerfont{date}{size=\tiny}
|
|
||||||
|
|
||||||
% Other typography styles
|
|
||||||
\setbeamertemplate{frametitle}[default][center]
|
|
||||||
\setbeamercolor{frametitle}{fg=mg-black}
|
|
||||||
\setbeamercolor{title}{fg=mg-black}
|
|
||||||
\setbeamercolor{section in toc}{fg=mg-black}
|
|
||||||
\setbeamercolor{local structure}{fg=mg-orange}
|
|
||||||
\setbeamercolor{alert text}{fg=mg-red}
|
|
||||||
|
|
||||||
% Commands
|
|
||||||
\newcommand{\mgalert}[1]{{\usebeamercolor[fg]{alert text}#1}}
|
|
||||||
\newcommand{\titleframe}{\frame[plain]{\titlepage}}
|
|
||||||
\newcommand{\mgtexttt}[1]{{\textcolor{mg-gray}{\texttt{#1}}}}
|
|
||||||
|
|
||||||
% Title slide background
|
|
||||||
\RequirePackage{tikz,calc}
|
|
||||||
% Use title-slide-169 if aspect ration is 16:9
|
|
||||||
\pgfdeclareimage[interpolate=true,width=\paperwidth,height=\paperheight]{logo}{mg-style/title-slide-169}
|
|
||||||
\setbeamertemplate{background}{
|
|
||||||
\begin{tikzpicture}
|
|
||||||
\useasboundingbox (0,0) rectangle (\the\paperwidth,\the\paperheight);
|
|
||||||
\pgftext[at=\pgfpoint{0}{0},left,base]{\pgfuseimage{logo}};
|
|
||||||
\ifnum\thepage>1\relax
|
|
||||||
\useasboundingbox (0,0) rectangle (\the\paperwidth,\the\paperheight);
|
|
||||||
\fill[white, opacity=1](0,\the\paperheight)--(\the\paperwidth,\the\paperheight)--(\the\paperwidth,0)--(0,0)--(0,\the\paperheight);
|
|
||||||
\fi
|
|
||||||
\end{tikzpicture}
|
|
||||||
}
|
|
||||||
|
|
||||||
% Footline content
|
|
||||||
\setbeamertemplate{navigation symbols}{}%remove navigation symbols
|
|
||||||
\setbeamertemplate{footline}{
|
|
||||||
\begin{beamercolorbox}[ht=1.6cm,wd=\paperwidth]{footlinecolor}
|
|
||||||
\vspace{0.1cm}
|
|
||||||
\hfill
|
|
||||||
\begin{minipage}[c]{3cm}
|
|
||||||
\begin{center}
|
|
||||||
\includegraphics[height=0.8cm]{mg-style/memgraph-logo.png}
|
|
||||||
\end{center}
|
|
||||||
\end{minipage}
|
|
||||||
\begin{minipage}[c]{7cm}
|
|
||||||
\insertshorttitle\ --- \insertsection
|
|
||||||
\end{minipage}
|
|
||||||
\begin{minipage}[c]{2cm}
|
|
||||||
\tiny{\insertframenumber{} of \inserttotalframenumber}
|
|
||||||
\end{minipage}
|
|
||||||
\end{beamercolorbox}
|
|
||||||
}
|
|
||||||
|
|
||||||
\endinput
|
|
||||||
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 26 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 185 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 189 KiB |
@@ -1,40 +0,0 @@
|
|||||||
% Set 16:9 aspect ratio
|
|
||||||
\documentclass[aspectratio=169]{mg-beamer}
|
|
||||||
% Default directive sets the regular 4:3 aspect ratio
|
|
||||||
% \documentclass{mg-beamer}
|
|
||||||
\mode<presentation>
|
|
||||||
|
|
||||||
% requires xelatex
|
|
||||||
\usepackage{ccicons}
|
|
||||||
|
|
||||||
\title{Insert Presentation Title}
|
|
||||||
\titlegraphic{\ccbyncnd}
|
|
||||||
\author{Insert Name}
|
|
||||||
|
|
||||||
% Institute doesn't look good in our current styling class.
|
|
||||||
% \institute[Memgraph Ltd.]{\pgfimage[height=1.5cm]{mg-logo.png}}
|
|
||||||
|
|
||||||
% Date is autogenerated on compilation, so no need to set it explicitly,
|
|
||||||
% unless you wish to override it with a different date.
|
|
||||||
% \date{March 23, 2018}
|
|
||||||
|
|
||||||
\begin{document}
|
|
||||||
|
|
||||||
\titleframe
|
|
||||||
|
|
||||||
\section{Intro}
|
|
||||||
|
|
||||||
\begin{frame}{Contents}
|
|
||||||
\tableofcontents
|
|
||||||
\end{frame}
|
|
||||||
|
|
||||||
\begin{frame}{Memgraph Markup Test}
|
|
||||||
\begin{itemize}
|
|
||||||
\item \mgtexttt{Prefer \\mgtexttt for monospace}
|
|
||||||
\item Replace this slide with your own
|
|
||||||
\item Add even more slides in different sections
|
|
||||||
\item Make sure you spellcheck your presentation
|
|
||||||
\end{itemize}
|
|
||||||
\end{frame}
|
|
||||||
|
|
||||||
\end{document}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
# Memgraph Build and Run Environments
|
|
||||||
|
|
||||||
## Toolchain Installation Procedure
|
|
||||||
|
|
||||||
1) Download the toolchain for your operating system from one of the following
|
|
||||||
links (current active toolchain is `toolchain-v2`):
|
|
||||||
|
|
||||||
* [CentOS 7](https://s3-eu-west-1.amazonaws.com/deps.memgraph.io/toolchain-v2/toolchain-v2-binaries-centos-7.tar.gz)
|
|
||||||
* [CentOS 8](https://s3-eu-west-1.amazonaws.com/deps.memgraph.io/toolchain-v2/toolchain-v2-binaries-centos-8.tar.gz)
|
|
||||||
* [Debian 9](https://s3-eu-west-1.amazonaws.com/deps.memgraph.io/toolchain-v2/toolchain-v2-binaries-debian-9.tar.gz)
|
|
||||||
* [Debian 10](https://s3-eu-west-1.amazonaws.com/deps.memgraph.io/toolchain-v2/toolchain-v2-binaries-debian-10.tar.gz)
|
|
||||||
* [Ubuntu 18.04](https://s3-eu-west-1.amazonaws.com/deps.memgraph.io/toolchain-v2/toolchain-v2-binaries-ubuntu-18.04.tar.gz)
|
|
||||||
* [Ubuntu 20.04](https://s3-eu-west-1.amazonaws.com/deps.memgraph.io/toolchain-v2/toolchain-v2-binaries-ubuntu-20.04.tar.gz)
|
|
||||||
|
|
||||||
2) Extract the toolchain with the following command:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
tar xzvf {{toolchain-archive}}.tar.gz -C /opt
|
|
||||||
```
|
|
||||||
|
|
||||||
3) Check and install required toolchain runtime dependencies by executing
|
|
||||||
(e.g., on **Debian 10**):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./environment/os/debian-10.sh check TOOLCHAIN_RUN_DEPS
|
|
||||||
./environment/os/debian-10.sh install TOOLCHAIN_RUN_DEPS
|
|
||||||
```
|
|
||||||
|
|
||||||
4) Activate the toolchain:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
source /opt/toolchain-v2/activate
|
|
||||||
```
|
|
||||||
|
|
||||||
## Toolchain Upgrade Procedure
|
|
||||||
|
|
||||||
1) Build a new toolchain for each supported OS (latest versions).
|
|
||||||
2) If the new toolchain doesn't compile on some supported OS, the last
|
|
||||||
compilable toolchain has to be used instead. In other words, the project has
|
|
||||||
to compile on the oldest active toolchain as well. Suppose some
|
|
||||||
changes/improvements were added when migrating to the latest toolchain; in
|
|
||||||
that case, the maintainer has to ensure that the project still compiles on
|
|
||||||
previous toolchains (everything from `init` script to the actual code has to
|
|
||||||
work on all supported operating systems).
|
|
||||||
@@ -5,19 +5,29 @@ set -Eeuo pipefail
|
|||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||||
source "$DIR/../util.sh"
|
source "$DIR/../util.sh"
|
||||||
|
|
||||||
|
check_operating_system "centos-7"
|
||||||
|
check_architecture "x86_64"
|
||||||
|
|
||||||
TOOLCHAIN_BUILD_DEPS=(
|
TOOLCHAIN_BUILD_DEPS=(
|
||||||
coreutils gcc gcc-c++ make # generic build tools
|
coreutils gcc gcc-c++ make # generic build tools
|
||||||
wget # used for archive download
|
wget # used for archive download
|
||||||
gnupg2 # used for archive signature verification
|
gnupg2 # used for archive signature verification
|
||||||
tar gzip bzip2 xz unzip # used for archive unpacking
|
tar gzip bzip2 xz unzip # used for archive unpacking
|
||||||
zlib-devel # zlib library used for all builds
|
zlib-devel # zlib library used for all builds
|
||||||
expat-devel libipt-devel libbabeltrace-devel xz-devel python3-devel # gdb
|
expat-devel libipt libipt-devel libbabeltrace-devel xz-devel python3-devel # gdb
|
||||||
texinfo # gdb
|
texinfo # gdb
|
||||||
libcurl-devel # cmake
|
libcurl-devel # cmake
|
||||||
|
curl # snappy
|
||||||
readline-devel # cmake and llvm
|
readline-devel # cmake and llvm
|
||||||
libffi-devel libxml2-devel perl-Digest-MD5 # llvm
|
libffi-devel libxml2-devel perl-Digest-MD5 # llvm
|
||||||
libedit-devel pcre-devel automake bison # swig
|
libedit-devel pcre-devel automake bison # swig
|
||||||
|
file
|
||||||
|
openssl-devel
|
||||||
|
gmp-devel
|
||||||
|
gperf
|
||||||
|
patch
|
||||||
)
|
)
|
||||||
|
|
||||||
TOOLCHAIN_RUN_DEPS=(
|
TOOLCHAIN_RUN_DEPS=(
|
||||||
make # generic build tools
|
make # generic build tools
|
||||||
tar gzip bzip2 xz # used for archive unpacking
|
tar gzip bzip2 xz # used for archive unpacking
|
||||||
@@ -25,9 +35,10 @@ TOOLCHAIN_RUN_DEPS=(
|
|||||||
expat libipt libbabeltrace xz-libs python3 # for gdb
|
expat libipt libbabeltrace xz-libs python3 # for gdb
|
||||||
readline # for cmake and llvm
|
readline # for cmake and llvm
|
||||||
libffi libxml2 # for llvm
|
libffi libxml2 # for llvm
|
||||||
|
openssl-devel
|
||||||
)
|
)
|
||||||
|
|
||||||
MEMGRAPH_BUILD_DEPS=(
|
MEMGRAPH_BUILD_DEPS=(
|
||||||
git # source code control
|
|
||||||
make pkgconfig # build system
|
make pkgconfig # build system
|
||||||
curl wget # for downloading libs
|
curl wget # for downloading libs
|
||||||
libuuid-devel java-11-openjdk # required by antlr
|
libuuid-devel java-11-openjdk # required by antlr
|
||||||
@@ -46,10 +57,14 @@ MEMGRAPH_BUILD_DEPS=(
|
|||||||
rpm-build rpmlint # for RPM package building
|
rpm-build rpmlint # for RPM package building
|
||||||
doxygen graphviz # source documentation generators
|
doxygen graphviz # source documentation generators
|
||||||
which mono-complete dotnet-sdk-3.1 golang nodejs zip unzip java-11-openjdk-devel # for driver tests
|
which mono-complete dotnet-sdk-3.1 golang nodejs zip unzip java-11-openjdk-devel # for driver tests
|
||||||
|
autoconf # for jemalloc code generation
|
||||||
|
libtool # for protobuf code generation
|
||||||
)
|
)
|
||||||
|
|
||||||
list() {
|
list() {
|
||||||
echo "$1"
|
echo "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
check() {
|
check() {
|
||||||
local missing=""
|
local missing=""
|
||||||
for pkg in $1; do
|
for pkg in $1; do
|
||||||
@@ -74,16 +89,13 @@ check() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
install() {
|
install() {
|
||||||
cd "$DIR"
|
cd "$DIR"
|
||||||
if [ "$EUID" -ne 0 ]; then
|
if [ "$EUID" -ne 0 ]; then
|
||||||
echo "Please run as root."
|
echo "Please run as root."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
if [ "$SUDO_USER" == "" ]; then
|
|
||||||
echo "Please run as sudo."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# If GitHub Actions runner is installed, append LANG to the environment.
|
# If GitHub Actions runner is installed, append LANG to the environment.
|
||||||
# Python related tests doesn't work the LANG export.
|
# Python related tests doesn't work the LANG export.
|
||||||
if [ -d "/home/gh/actions-runner" ]; then
|
if [ -d "/home/gh/actions-runner" ]; then
|
||||||
@@ -92,8 +104,12 @@ install() {
|
|||||||
echo "NOTE: export LANG=en_US.utf8"
|
echo "NOTE: export LANG=en_US.utf8"
|
||||||
fi
|
fi
|
||||||
yum install -y epel-release
|
yum install -y epel-release
|
||||||
|
yum remove -y ius-release
|
||||||
|
yum install -y \
|
||||||
|
https://repo.ius.io/ius-release-el7.rpm
|
||||||
yum update -y
|
yum update -y
|
||||||
yum install -y wget git python3 python3-pip
|
yum install -y wget python3 python3-pip
|
||||||
|
yum install -y git
|
||||||
for pkg in $1; do
|
for pkg in $1; do
|
||||||
if [ "$pkg" == libipt ]; then
|
if [ "$pkg" == libipt ]; then
|
||||||
if ! yum list installed libipt >/dev/null 2>/dev/null; then
|
if ! yum list installed libipt >/dev/null 2>/dev/null; then
|
||||||
@@ -117,11 +133,16 @@ install() {
|
|||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
if [ "$pkg" == PyYAML ]; then
|
if [ "$pkg" == PyYAML ]; then
|
||||||
sudo -H -u "$SUDO_USER" bash -c "pip3 install --user PyYAML"
|
if [ -z ${SUDO_USER+x} ]; then # Running as root (e.g. Docker).
|
||||||
|
pip3 install --user PyYAML
|
||||||
|
else # Running using sudo.
|
||||||
|
sudo -H -u "$SUDO_USER" bash -c "pip3 install --user PyYAML"
|
||||||
|
fi
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
yum install -y "$pkg"
|
yum install -y "$pkg"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
deps=$2"[*]"
|
deps=$2"[*]"
|
||||||
"$1" "${!deps}"
|
"$1" "${!deps}"
|
||||||
|
|||||||
@@ -5,36 +5,49 @@ set -Eeuo pipefail
|
|||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||||
source "$DIR/../util.sh"
|
source "$DIR/../util.sh"
|
||||||
|
|
||||||
|
check_operating_system "centos-9"
|
||||||
|
check_architecture "x86_64"
|
||||||
|
|
||||||
TOOLCHAIN_BUILD_DEPS=(
|
TOOLCHAIN_BUILD_DEPS=(
|
||||||
coreutils gcc gcc-c++ make # generic build tools
|
coreutils-common gcc gcc-c++ make # generic build tools
|
||||||
wget # used for archive download
|
wget # used for archive download
|
||||||
gnupg2 # used for archive signature verification
|
gnupg2 # used for archive signature verification
|
||||||
tar gzip bzip2 xz unzip # used for archive unpacking
|
tar gzip bzip2 xz unzip # used for archive unpacking
|
||||||
zlib-devel # zlib library used for all builds
|
zlib-devel # zlib library used for all builds
|
||||||
expat-devel libipt-devel libbabeltrace-devel xz-devel python36-devel texinfo # for gdb
|
expat-devel xz-devel python3-devel texinfo libbabeltrace-devel # for gdb
|
||||||
libcurl-devel # for cmake
|
|
||||||
readline-devel # for cmake and llvm
|
readline-devel # for cmake and llvm
|
||||||
libffi-devel libxml2-devel # for llvm
|
libffi-devel libxml2-devel # for llvm
|
||||||
libedit-devel pcre-devel automake bison # for swig
|
libedit-devel pcre-devel automake bison # for swig
|
||||||
|
file
|
||||||
|
openssl-devel
|
||||||
|
gmp-devel
|
||||||
|
gperf
|
||||||
|
diffutils
|
||||||
|
libipt libipt-devel # intel
|
||||||
|
patch
|
||||||
)
|
)
|
||||||
|
|
||||||
TOOLCHAIN_RUN_DEPS=(
|
TOOLCHAIN_RUN_DEPS=(
|
||||||
make # generic build tools
|
make # generic build tools
|
||||||
tar gzip bzip2 xz # used for archive unpacking
|
tar gzip bzip2 xz # used for archive unpacking
|
||||||
zlib # zlib library used for all builds
|
zlib # zlib library used for all builds
|
||||||
expat libipt libbabeltrace xz-libs python36 # for gdb
|
expat xz-libs python3 # for gdb
|
||||||
readline # for cmake and llvm
|
readline # for cmake and llvm
|
||||||
libffi libxml2 # for llvm
|
libffi libxml2 # for llvm
|
||||||
|
openssl-devel
|
||||||
|
perl # for openssl
|
||||||
)
|
)
|
||||||
|
|
||||||
MEMGRAPH_BUILD_DEPS=(
|
MEMGRAPH_BUILD_DEPS=(
|
||||||
git # source code control
|
git # source code control
|
||||||
make pkgconf-pkg-config # build system
|
make pkgconf-pkg-config # build system
|
||||||
curl wget # for downloading libs
|
wget # for downloading libs
|
||||||
libuuid-devel java-11-openjdk # required by antlr
|
libuuid-devel java-11-openjdk # required by antlr
|
||||||
readline-devel # for memgraph console
|
readline-devel # for memgraph console
|
||||||
python36-devel # for query modules
|
python3-devel # for query modules
|
||||||
openssl-devel
|
openssl-devel
|
||||||
libseccomp-devel
|
libseccomp-devel
|
||||||
python36 python3-virtualenv python3-pip nmap-ncat # for qa, macro_benchmark and stress tests
|
python3 python3-pip python3-virtualenv nmap-ncat # for qa, macro_benchmark and stress tests
|
||||||
#
|
#
|
||||||
# IMPORTANT: python3-yaml does NOT exist on CentOS
|
# IMPORTANT: python3-yaml does NOT exist on CentOS
|
||||||
# Install it manually using `pip3 install PyYAML`
|
# Install it manually using `pip3 install PyYAML`
|
||||||
@@ -43,12 +56,16 @@ MEMGRAPH_BUILD_DEPS=(
|
|||||||
libcurl-devel # mg-requests
|
libcurl-devel # mg-requests
|
||||||
rpm-build rpmlint # for RPM package building
|
rpm-build rpmlint # for RPM package building
|
||||||
doxygen graphviz # source documentation generators
|
doxygen graphviz # source documentation generators
|
||||||
which mono-complete dotnet-sdk-3.1 nodejs golang zip unzip java-11-openjdk-devel # for driver tests
|
which nodejs golang zip unzip java-11-openjdk-devel # for driver tests
|
||||||
sbcl # for custom Lisp C++ preprocessing
|
sbcl # for custom Lisp C++ preprocessing
|
||||||
|
autoconf # for jemalloc code generation
|
||||||
|
libtool # for protobuf code generation
|
||||||
)
|
)
|
||||||
|
|
||||||
list() {
|
list() {
|
||||||
echo "$1"
|
echo "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
check() {
|
check() {
|
||||||
local missing=""
|
local missing=""
|
||||||
for pkg in $1; do
|
for pkg in $1; do
|
||||||
@@ -58,6 +75,9 @@ check() {
|
|||||||
fi
|
fi
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
if [ "$pkg" == "python3-virtualenv" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
if ! yum list installed "$pkg" >/dev/null 2>/dev/null; then
|
if ! yum list installed "$pkg" >/dev/null 2>/dev/null; then
|
||||||
missing="$pkg $missing"
|
missing="$pkg $missing"
|
||||||
fi
|
fi
|
||||||
@@ -67,16 +87,13 @@ check() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
install() {
|
install() {
|
||||||
cd "$DIR"
|
cd "$DIR"
|
||||||
if [ "$EUID" -ne 0 ]; then
|
if [ "$EUID" -ne 0 ]; then
|
||||||
echo "Please run as root."
|
echo "Please run as root."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
if [ "$SUDO_USER" == "" ]; then
|
|
||||||
echo "Please run as sudo."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# If GitHub Actions runner is installed, append LANG to the environment.
|
# If GitHub Actions runner is installed, append LANG to the environment.
|
||||||
# Python related tests doesn't work the LANG export.
|
# Python related tests doesn't work the LANG export.
|
||||||
if [ -d "/home/gh/actions-runner" ]; then
|
if [ -d "/home/gh/actions-runner" ]; then
|
||||||
@@ -84,11 +101,13 @@ install() {
|
|||||||
else
|
else
|
||||||
echo "NOTE: export LANG=en_US.utf8"
|
echo "NOTE: export LANG=en_US.utf8"
|
||||||
fi
|
fi
|
||||||
dnf install -y epel-release
|
yum update -y
|
||||||
dnf config-manager --set-enabled PowerTools # Required to install texinfo.
|
yum install -y wget git python3 python3-pip
|
||||||
dnf update -y
|
|
||||||
dnf install -y wget git python36 python3-pip
|
|
||||||
for pkg in $1; do
|
for pkg in $1; do
|
||||||
|
# Since there is no support for libipt-devel for CentOS 9 we install
|
||||||
|
# Fedoras version of same libs, they are the same version but released
|
||||||
|
# for different OS
|
||||||
|
# TODO Update when libipt-devel releases for CentOS 9
|
||||||
if [ "$pkg" == libipt ]; then
|
if [ "$pkg" == libipt ]; then
|
||||||
if ! dnf list installed libipt >/dev/null 2>/dev/null; then
|
if ! dnf list installed libipt >/dev/null 2>/dev/null; then
|
||||||
dnf install -y http://repo.okay.com.mx/centos/8/x86_64/release/libipt-1.6.1-8.el8.x86_64.rpm
|
dnf install -y http://repo.okay.com.mx/centos/8/x86_64/release/libipt-1.6.1-8.el8.x86_64.rpm
|
||||||
@@ -96,19 +115,14 @@ install() {
|
|||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
if [ "$pkg" == libipt-devel ]; then
|
if [ "$pkg" == libipt-devel ]; then
|
||||||
if ! yum list installed libipt-devel >/dev/null 2>/dev/null; then
|
if ! dnf list installed libipt-devel >/dev/null 2>/dev/null; then
|
||||||
dnf install -y http://repo.okay.com.mx/centos/8/x86_64/release/libipt-devel-1.6.1-8.el8.x86_64.rpm
|
dnf install -y http://repo.okay.com.mx/centos/8/x86_64/release/libipt-devel-1.6.1-8.el8.x86_64.rpm
|
||||||
fi
|
fi
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
# Install GDB dependencies not present in the standard repos.
|
|
||||||
# https://bugs.centos.org/view.php?id=17068
|
|
||||||
# https://centos.pkgs.org
|
|
||||||
# Since 2020, there is Babeltrace2 (https://babeltrace.org). Not used
|
|
||||||
# within GDB yet (an assumption).
|
|
||||||
if [ "$pkg" == libbabeltrace-devel ]; then
|
if [ "$pkg" == libbabeltrace-devel ]; then
|
||||||
if ! dnf list installed libbabeltrace-devel >/dev/null 2>/dev/null; then
|
if ! dnf list installed libbabeltrace-devel >/dev/null 2>/dev/null; then
|
||||||
dnf install -y http://repo.okay.com.mx/centos/8/x86_64/release/libbabeltrace-devel-1.5.4-2.el8.x86_64.rpm
|
dnf install -y http://mirror.stream.centos.org/9-stream/CRB/x86_64/os/Packages/libbabeltrace-devel-1.5.8-10.el9.x86_64.rpm
|
||||||
fi
|
fi
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
@@ -124,21 +138,27 @@ install() {
|
|||||||
fi
|
fi
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
if [ "$pkg" == dotnet-sdk-3.1 ]; then
|
if [ "$pkg" == PyYAML ]; then
|
||||||
if ! dnf list installed dotnet-sdk-3.1 >/dev/null 2>/dev/null; then
|
if [ -z ${SUDO_USER+x} ]; then # Running as root (e.g. Docker).
|
||||||
wget -nv https://packages.microsoft.com/config/centos/8/packages-microsoft-prod.rpm -O packages-microsoft-prod.rpm
|
pip3 install --user PyYAML
|
||||||
rpm -Uvh https://packages.microsoft.com/config/centos/8/packages-microsoft-prod.rpm
|
else # Running using sudo.
|
||||||
dnf update -y
|
sudo -H -u "$SUDO_USER" bash -c "pip3 install --user PyYAML"
|
||||||
dnf install -y dotnet-sdk-3.1
|
|
||||||
fi
|
fi
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
if [ "$pkg" == PyYAML ]; then
|
if [ "$pkg" == python3-virtualenv ]; then
|
||||||
sudo -H -u "$SUDO_USER" bash -c "pip3 install --user PyYAML"
|
if [ -z ${SUDO_USER+x} ]; then # Running as root (e.g. Docker).
|
||||||
|
pip3 install virtualenv
|
||||||
|
pip3 install virtualenvwrapper
|
||||||
|
else # Running using sudo.
|
||||||
|
sudo -H -u "$SUDO_USER" bash -c "pip3 install virtualenv"
|
||||||
|
sudo -H -u "$SUDO_USER" bash -c "pip3 install virtualenvwrapper"
|
||||||
|
fi
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
dnf install -y "$pkg"
|
yum install -y "$pkg"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
deps=$2"[*]"
|
deps=$2"[*]"
|
||||||
"$1" "${!deps}"
|
"$1" "${!deps}"
|
||||||
@@ -5,6 +5,9 @@ set -Eeuo pipefail
|
|||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||||
source "$DIR/../util.sh"
|
source "$DIR/../util.sh"
|
||||||
|
|
||||||
|
check_operating_system "debian-10"
|
||||||
|
check_architecture "x86_64"
|
||||||
|
|
||||||
TOOLCHAIN_BUILD_DEPS=(
|
TOOLCHAIN_BUILD_DEPS=(
|
||||||
coreutils gcc g++ build-essential make # generic build tools
|
coreutils gcc g++ build-essential make # generic build tools
|
||||||
wget # used for archive download
|
wget # used for archive download
|
||||||
@@ -15,8 +18,15 @@ TOOLCHAIN_BUILD_DEPS=(
|
|||||||
libcurl4-openssl-dev # for cmake
|
libcurl4-openssl-dev # for cmake
|
||||||
libreadline-dev # for cmake and llvm
|
libreadline-dev # for cmake and llvm
|
||||||
libffi-dev libxml2-dev # for llvm
|
libffi-dev libxml2-dev # for llvm
|
||||||
|
curl # snappy
|
||||||
|
file # for libunwind
|
||||||
|
libssl-dev # for libevent
|
||||||
|
libgmp-dev # for gdb
|
||||||
|
gperf # for proxygen
|
||||||
|
git # for fbthrift
|
||||||
libedit-dev libpcre3-dev automake bison # for swig
|
libedit-dev libpcre3-dev automake bison # for swig
|
||||||
)
|
)
|
||||||
|
|
||||||
TOOLCHAIN_RUN_DEPS=(
|
TOOLCHAIN_RUN_DEPS=(
|
||||||
make # generic build tools
|
make # generic build tools
|
||||||
tar gzip bzip2 xz-utils # used for archive unpacking
|
tar gzip bzip2 xz-utils # used for archive unpacking
|
||||||
@@ -25,7 +35,9 @@ TOOLCHAIN_RUN_DEPS=(
|
|||||||
libcurl4 # for cmake
|
libcurl4 # for cmake
|
||||||
libreadline7 # for cmake and llvm
|
libreadline7 # for cmake and llvm
|
||||||
libffi6 libxml2 # for llvm
|
libffi6 libxml2 # for llvm
|
||||||
|
libssl-dev # for libevent
|
||||||
)
|
)
|
||||||
|
|
||||||
MEMGRAPH_BUILD_DEPS=(
|
MEMGRAPH_BUILD_DEPS=(
|
||||||
git # source code control
|
git # source code control
|
||||||
make pkg-config # build system
|
make pkg-config # build system
|
||||||
@@ -43,13 +55,18 @@ MEMGRAPH_BUILD_DEPS=(
|
|||||||
doxygen graphviz # source documentation generators
|
doxygen graphviz # source documentation generators
|
||||||
mono-runtime mono-mcs zip unzip default-jdk-headless # for driver tests
|
mono-runtime mono-mcs zip unzip default-jdk-headless # for driver tests
|
||||||
dotnet-sdk-3.1 golang nodejs npm
|
dotnet-sdk-3.1 golang nodejs npm
|
||||||
|
autoconf # for jemalloc code generation
|
||||||
|
libtool # for protobuf code generation
|
||||||
)
|
)
|
||||||
|
|
||||||
list() {
|
list() {
|
||||||
echo "$1"
|
echo "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
check() {
|
check() {
|
||||||
check_all_dpkg "$1"
|
check_all_dpkg "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
install() {
|
install() {
|
||||||
cat >/etc/apt/sources.list <<EOF
|
cat >/etc/apt/sources.list <<EOF
|
||||||
deb http://deb.debian.org/debian/ buster main non-free contrib
|
deb http://deb.debian.org/debian/ buster main non-free contrib
|
||||||
@@ -60,7 +77,7 @@ deb http://security.debian.org/debian-security buster/updates main contrib non-f
|
|||||||
deb-src http://security.debian.org/debian-security buster/updates main contrib non-free
|
deb-src http://security.debian.org/debian-security buster/updates main contrib non-free
|
||||||
EOF
|
EOF
|
||||||
cd "$DIR"
|
cd "$DIR"
|
||||||
apt update
|
apt --allow-releaseinfo-change update
|
||||||
# If GitHub Actions runner is installed, append LANG to the environment.
|
# If GitHub Actions runner is installed, append LANG to the environment.
|
||||||
# Python related tests doesn't work the LANG export.
|
# Python related tests doesn't work the LANG export.
|
||||||
if [ -d "/home/gh/actions-runner" ]; then
|
if [ -d "/home/gh/actions-runner" ]; then
|
||||||
@@ -82,5 +99,6 @@ EOF
|
|||||||
apt install -y "$pkg"
|
apt install -y "$pkg"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
deps=$2"[*]"
|
deps=$2"[*]"
|
||||||
"$1" "${!deps}"
|
"$1" "${!deps}"
|
||||||
|
|||||||
98
environment/os/debian-11-arm.sh
Executable file
98
environment/os/debian-11-arm.sh
Executable file
@@ -0,0 +1,98 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||||
|
source "$DIR/../util.sh"
|
||||||
|
|
||||||
|
check_operating_system "debian-11"
|
||||||
|
check_architecture "arm64"
|
||||||
|
|
||||||
|
TOOLCHAIN_BUILD_DEPS=(
|
||||||
|
coreutils gcc g++ build-essential make # generic build tools
|
||||||
|
wget # used for archive download
|
||||||
|
gnupg # used for archive signature verification
|
||||||
|
tar gzip bzip2 xz-utils unzip # used for archive unpacking
|
||||||
|
zlib1g-dev # zlib library used for all builds
|
||||||
|
libexpat1-dev liblzma-dev python3-dev texinfo # for gdb
|
||||||
|
libcurl4-openssl-dev # for cmake
|
||||||
|
libreadline-dev # for cmake and llvm
|
||||||
|
libffi-dev libxml2-dev # for llvm
|
||||||
|
libedit-dev libpcre3-dev automake bison # for swig
|
||||||
|
curl # snappy
|
||||||
|
file # for libunwind
|
||||||
|
libssl-dev # for libevent
|
||||||
|
libgmp-dev
|
||||||
|
gperf # for proxygen
|
||||||
|
git # for fbthrift
|
||||||
|
)
|
||||||
|
|
||||||
|
TOOLCHAIN_RUN_DEPS=(
|
||||||
|
make # generic build tools
|
||||||
|
tar gzip bzip2 xz-utils # used for archive unpacking
|
||||||
|
zlib1g # zlib library used for all builds
|
||||||
|
libexpat1 liblzma5 python3 # for gdb
|
||||||
|
libcurl4 # for cmake
|
||||||
|
file # for CPack
|
||||||
|
libreadline8 # for cmake and llvm
|
||||||
|
libffi7 libxml2 # for llvm
|
||||||
|
libssl-dev # for libevent
|
||||||
|
)
|
||||||
|
|
||||||
|
MEMGRAPH_BUILD_DEPS=(
|
||||||
|
git # source code control
|
||||||
|
make pkg-config # build system
|
||||||
|
curl wget # for downloading libs
|
||||||
|
uuid-dev default-jre-headless # required by antlr
|
||||||
|
libreadline-dev # for memgraph console
|
||||||
|
libpython3-dev python3-dev # for query modules
|
||||||
|
libssl-dev
|
||||||
|
libseccomp-dev
|
||||||
|
netcat # tests are using nc to wait for memgraph
|
||||||
|
python3 virtualenv python3-virtualenv python3-pip # for qa, macro_benchmark and stress tests
|
||||||
|
python3-yaml # for the configuration generator
|
||||||
|
libcurl4-openssl-dev # mg-requests
|
||||||
|
sbcl # for custom Lisp C++ preprocessing
|
||||||
|
doxygen graphviz # source documentation generators
|
||||||
|
mono-runtime mono-mcs zip unzip default-jdk-headless # for driver tests
|
||||||
|
golang nodejs npm
|
||||||
|
autoconf # for jemalloc code generation
|
||||||
|
libtool # for protobuf code generation
|
||||||
|
)
|
||||||
|
|
||||||
|
list() {
|
||||||
|
echo "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
check() {
|
||||||
|
check_all_dpkg "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cat >/etc/apt/sources.list <<EOF
|
||||||
|
deb http://deb.debian.org/debian bullseye main
|
||||||
|
deb-src http://deb.debian.org/debian bullseye main
|
||||||
|
|
||||||
|
deb http://deb.debian.org/debian-security/ bullseye-security main
|
||||||
|
deb-src http://deb.debian.org/debian-security/ bullseye-security main
|
||||||
|
|
||||||
|
deb http://deb.debian.org/debian bullseye-updates main
|
||||||
|
deb-src http://deb.debian.org/debian bullseye-updates main
|
||||||
|
EOF
|
||||||
|
cd "$DIR"
|
||||||
|
apt update
|
||||||
|
# If GitHub Actions runner is installed, append LANG to the environment.
|
||||||
|
# Python related tests doesn't work the LANG export.
|
||||||
|
if [ -d "/home/gh/actions-runner" ]; then
|
||||||
|
echo "LANG=en_US.utf8" >> /home/gh/actions-runner/.env
|
||||||
|
else
|
||||||
|
echo "NOTE: export LANG=en_US.utf8"
|
||||||
|
fi
|
||||||
|
apt install -y wget
|
||||||
|
for pkg in $1; do
|
||||||
|
apt install -y "$pkg"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
deps=$2"[*]"
|
||||||
|
"$1" "${!deps}"
|
||||||
107
environment/os/debian-11.sh
Executable file
107
environment/os/debian-11.sh
Executable file
@@ -0,0 +1,107 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||||
|
source "$DIR/../util.sh"
|
||||||
|
|
||||||
|
check_operating_system "debian-11"
|
||||||
|
check_architecture "x86_64"
|
||||||
|
|
||||||
|
TOOLCHAIN_BUILD_DEPS=(
|
||||||
|
coreutils gcc g++ build-essential make # generic build tools
|
||||||
|
wget # used for archive download
|
||||||
|
gnupg # used for archive signature verification
|
||||||
|
tar gzip bzip2 xz-utils unzip # used for archive unpacking
|
||||||
|
zlib1g-dev # zlib library used for all builds
|
||||||
|
libexpat1-dev libipt-dev libbabeltrace-dev liblzma-dev python3-dev texinfo # for gdb
|
||||||
|
libcurl4-openssl-dev # for cmake
|
||||||
|
libreadline-dev # for cmake and llvm
|
||||||
|
libffi-dev libxml2-dev # for llvm
|
||||||
|
libedit-dev libpcre3-dev automake bison # for swig
|
||||||
|
curl # snappy
|
||||||
|
file # for libunwind
|
||||||
|
libssl-dev # for libevent
|
||||||
|
libgmp-dev
|
||||||
|
gperf # for proxygen
|
||||||
|
git # for fbthrift
|
||||||
|
)
|
||||||
|
|
||||||
|
TOOLCHAIN_RUN_DEPS=(
|
||||||
|
make # generic build tools
|
||||||
|
tar gzip bzip2 xz-utils # used for archive unpacking
|
||||||
|
zlib1g # zlib library used for all builds
|
||||||
|
libexpat1 libipt2 libbabeltrace1 liblzma5 python3 # for gdb
|
||||||
|
libcurl4 # for cmake
|
||||||
|
file # for CPack
|
||||||
|
libreadline8 # for cmake and llvm
|
||||||
|
libffi7 libxml2 # for llvm
|
||||||
|
libssl-dev # for libevent
|
||||||
|
)
|
||||||
|
|
||||||
|
MEMGRAPH_BUILD_DEPS=(
|
||||||
|
git # source code control
|
||||||
|
make pkg-config # build system
|
||||||
|
curl wget # for downloading libs
|
||||||
|
uuid-dev default-jre-headless # required by antlr
|
||||||
|
libreadline-dev # for memgraph console
|
||||||
|
libpython3-dev python3-dev # for query modules
|
||||||
|
libssl-dev
|
||||||
|
libseccomp-dev
|
||||||
|
netcat # tests are using nc to wait for memgraph
|
||||||
|
python3 virtualenv python3-virtualenv python3-pip # for qa, macro_benchmark and stress tests
|
||||||
|
python3-yaml # for the configuration generator
|
||||||
|
libcurl4-openssl-dev # mg-requests
|
||||||
|
sbcl # for custom Lisp C++ preprocessing
|
||||||
|
doxygen graphviz # source documentation generators
|
||||||
|
mono-runtime mono-mcs zip unzip default-jdk-headless # for driver tests
|
||||||
|
dotnet-sdk-3.1 golang nodejs npm
|
||||||
|
autoconf # for jemalloc code generation
|
||||||
|
libtool # for protobuf code generation
|
||||||
|
)
|
||||||
|
|
||||||
|
list() {
|
||||||
|
echo "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
check() {
|
||||||
|
check_all_dpkg "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cat >/etc/apt/sources.list <<EOF
|
||||||
|
deb http://deb.debian.org/debian bullseye main
|
||||||
|
deb-src http://deb.debian.org/debian bullseye main
|
||||||
|
|
||||||
|
deb http://deb.debian.org/debian-security/ bullseye-security main
|
||||||
|
deb-src http://deb.debian.org/debian-security/ bullseye-security main
|
||||||
|
|
||||||
|
deb http://deb.debian.org/debian bullseye-updates main
|
||||||
|
deb-src http://deb.debian.org/debian bullseye-updates main
|
||||||
|
EOF
|
||||||
|
cd "$DIR"
|
||||||
|
apt update
|
||||||
|
# If GitHub Actions runner is installed, append LANG to the environment.
|
||||||
|
# Python related tests doesn't work the LANG export.
|
||||||
|
if [ -d "/home/gh/actions-runner" ]; then
|
||||||
|
echo "LANG=en_US.utf8" >> /home/gh/actions-runner/.env
|
||||||
|
else
|
||||||
|
echo "NOTE: export LANG=en_US.utf8"
|
||||||
|
fi
|
||||||
|
apt install -y wget
|
||||||
|
for pkg in $1; do
|
||||||
|
if [ "$pkg" == dotnet-sdk-3.1 ]; then
|
||||||
|
if ! dpkg -s "$pkg" 2>/dev/null >/dev/null; then
|
||||||
|
wget -nv https://packages.microsoft.com/config/debian/10/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
|
||||||
|
dpkg -i packages-microsoft-prod.deb
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y apt-transport-https dotnet-sdk-3.1
|
||||||
|
fi
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
apt install -y "$pkg"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
deps=$2"[*]"
|
||||||
|
"$1" "${!deps}"
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -Eeuo pipefail
|
|
||||||
|
|
||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
|
||||||
source "$DIR/../util.sh"
|
|
||||||
|
|
||||||
TOOLCHAIN_BUILD_DEPS=(
|
|
||||||
coreutils gcc g++ build-essential make # generic build tools
|
|
||||||
wget # used for archive download
|
|
||||||
gnupg # used for archive signature verification
|
|
||||||
tar gzip bzip2 xz-utils unzip # used for archive unpacking
|
|
||||||
zlib1g-dev # zlib library used for all builds
|
|
||||||
libexpat1-dev libipt-dev libbabeltrace-dev libbabeltrace-ctf-dev liblzma-dev python3-dev texinfo # for gdb
|
|
||||||
libcurl4-openssl-dev # for cmake
|
|
||||||
libreadline-dev # for cmake and llvm
|
|
||||||
libffi-dev libxml2-dev # for llvm
|
|
||||||
libedit-dev libpcre3-dev automake bison # for swig
|
|
||||||
)
|
|
||||||
TOOLCHAIN_RUN_DEPS=(
|
|
||||||
make # generic build tools
|
|
||||||
tar gzip bzip2 xz-utils # used for archive unpacking
|
|
||||||
zlib1g # zlib library used for all builds
|
|
||||||
libexpat1 libipt1 libbabeltrace1 libbabeltrace-ctf1 liblzma5 python3 # for gdb
|
|
||||||
libcurl3 # for cmake
|
|
||||||
libreadline7 # for cmake and llvm
|
|
||||||
libffi6 libxml2 # for llvm
|
|
||||||
)
|
|
||||||
MEMGRAPH_BUILD_DEPS=(
|
|
||||||
git # source code control
|
|
||||||
make pkg-config # build system
|
|
||||||
curl wget # for downloading libs
|
|
||||||
uuid-dev default-jre-headless # required by antlr
|
|
||||||
libreadline-dev # for memgraph console
|
|
||||||
libpython3-dev python3-dev # for query modules
|
|
||||||
libssl-dev
|
|
||||||
libseccomp-dev
|
|
||||||
python3 python-virtualenv python3-pip # for qa, macro_benchmark and stress tests
|
|
||||||
python3-yaml # for the configuration generator
|
|
||||||
libcurl4-openssl-dev # mg-requests
|
|
||||||
sbcl # for custom Lisp C++ preprocessing
|
|
||||||
doxygen graphviz # source documentation generators
|
|
||||||
mono-runtime mono-mcs nodejs zip unzip default-jdk-headless # for driver tests
|
|
||||||
)
|
|
||||||
list() {
|
|
||||||
echo "$1"
|
|
||||||
}
|
|
||||||
check() {
|
|
||||||
check_all_dpkg "$1"
|
|
||||||
}
|
|
||||||
install() {
|
|
||||||
install_all_apt "$1"
|
|
||||||
}
|
|
||||||
deps=$2"[*]"
|
|
||||||
"$1" "${!deps}"
|
|
||||||
@@ -5,26 +5,34 @@ set -Eeuo pipefail
|
|||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||||
source "$DIR/../util.sh"
|
source "$DIR/../util.sh"
|
||||||
|
|
||||||
|
check_operating_system "todo-os-name"
|
||||||
|
|
||||||
TOOLCHAIN_BUILD_DEPS=(
|
TOOLCHAIN_BUILD_DEPS=(
|
||||||
pkg
|
pkg
|
||||||
)
|
)
|
||||||
|
|
||||||
TOOLCHAIN_RUN_DEPS=(
|
TOOLCHAIN_RUN_DEPS=(
|
||||||
pkg
|
pkg
|
||||||
)
|
)
|
||||||
|
|
||||||
MEMGRAPH_BUILD_DEPS=(
|
MEMGRAPH_BUILD_DEPS=(
|
||||||
pkg
|
pkg
|
||||||
)
|
)
|
||||||
|
|
||||||
list() {
|
list() {
|
||||||
echo "$1"
|
echo "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
check() {
|
check() {
|
||||||
echo "TODO: Implement ${FUNCNAME[0]}."
|
echo "TODO: Implement ${FUNCNAME[0]}."
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
install() {
|
install() {
|
||||||
echo "TODO: Implement ${FUNCNAME[0]}."
|
echo "TODO: Implement ${FUNCNAME[0]}."
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# http://ahmed.amayem.com/bash-indirect-expansion-exploration
|
# http://ahmed.amayem.com/bash-indirect-expansion-exploration
|
||||||
deps=$2"[*]"
|
deps=$2"[*]"
|
||||||
"$1" "${!deps}"
|
"$1" "${!deps}"
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ set -Eeuo pipefail
|
|||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||||
source "$DIR/../util.sh"
|
source "$DIR/../util.sh"
|
||||||
|
|
||||||
|
check_operating_system "ubuntu-18.04"
|
||||||
|
check_architecture "x86_64"
|
||||||
|
|
||||||
TOOLCHAIN_BUILD_DEPS=(
|
TOOLCHAIN_BUILD_DEPS=(
|
||||||
coreutils gcc g++ build-essential make # generic build tools
|
coreutils gcc g++ build-essential make # generic build tools
|
||||||
wget # archive download
|
wget # archive download
|
||||||
@@ -16,8 +19,15 @@ TOOLCHAIN_BUILD_DEPS=(
|
|||||||
libcurl4-openssl-dev # cmake
|
libcurl4-openssl-dev # cmake
|
||||||
libreadline-dev # cmake and llvm
|
libreadline-dev # cmake and llvm
|
||||||
libffi-dev libxml2-dev # llvm
|
libffi-dev libxml2-dev # llvm
|
||||||
|
curl # snappy
|
||||||
|
file
|
||||||
|
git # for thrift
|
||||||
|
libgmp-dev # for gdb
|
||||||
|
gperf # for proxygen
|
||||||
|
libssl-dev
|
||||||
libedit-dev libpcre3-dev automake bison # swig
|
libedit-dev libpcre3-dev automake bison # swig
|
||||||
)
|
)
|
||||||
|
|
||||||
TOOLCHAIN_RUN_DEPS=(
|
TOOLCHAIN_RUN_DEPS=(
|
||||||
make # generic build tools
|
make # generic build tools
|
||||||
tar gzip bzip2 xz-utils # used for archive unpacking
|
tar gzip bzip2 xz-utils # used for archive unpacking
|
||||||
@@ -26,7 +36,9 @@ TOOLCHAIN_RUN_DEPS=(
|
|||||||
libcurl4 # for cmake
|
libcurl4 # for cmake
|
||||||
libreadline7 # for cmake and llvm
|
libreadline7 # for cmake and llvm
|
||||||
libffi6 libxml2 # for llvm
|
libffi6 libxml2 # for llvm
|
||||||
|
libssl-dev # for libevent
|
||||||
)
|
)
|
||||||
|
|
||||||
MEMGRAPH_BUILD_DEPS=(
|
MEMGRAPH_BUILD_DEPS=(
|
||||||
git # source code control
|
git # source code control
|
||||||
make pkg-config # build system
|
make pkg-config # build system
|
||||||
@@ -42,15 +54,21 @@ MEMGRAPH_BUILD_DEPS=(
|
|||||||
sbcl # custom Lisp C++ preprocessing
|
sbcl # custom Lisp C++ preprocessing
|
||||||
doxygen graphviz # source documentation generators
|
doxygen graphviz # source documentation generators
|
||||||
mono-runtime mono-mcs nodejs zip unzip default-jdk-headless # driver tests
|
mono-runtime mono-mcs nodejs zip unzip default-jdk-headless # driver tests
|
||||||
|
autoconf # for jemalloc code generation
|
||||||
|
libtool # for protobuf code generation
|
||||||
)
|
)
|
||||||
|
|
||||||
list() {
|
list() {
|
||||||
echo "$1"
|
echo "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
check() {
|
check() {
|
||||||
check_all_dpkg "$1"
|
check_all_dpkg "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
install() {
|
install() {
|
||||||
apt install -y $1
|
apt install -y $1
|
||||||
}
|
}
|
||||||
|
|
||||||
deps=$2"[*]"
|
deps=$2"[*]"
|
||||||
"$1" "${!deps}"
|
"$1" "${!deps}"
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ set -Eeuo pipefail
|
|||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||||
source "$DIR/../util.sh"
|
source "$DIR/../util.sh"
|
||||||
|
|
||||||
|
check_operating_system "ubuntu-20.04"
|
||||||
|
check_architecture "x86_64"
|
||||||
|
|
||||||
TOOLCHAIN_BUILD_DEPS=(
|
TOOLCHAIN_BUILD_DEPS=(
|
||||||
coreutils gcc g++ build-essential make # generic build tools
|
coreutils gcc g++ build-essential make # generic build tools
|
||||||
wget # used for archive download
|
wget # used for archive download
|
||||||
@@ -15,8 +18,15 @@ TOOLCHAIN_BUILD_DEPS=(
|
|||||||
libcurl4-openssl-dev # for cmake
|
libcurl4-openssl-dev # for cmake
|
||||||
libreadline-dev # for cmake and llvm
|
libreadline-dev # for cmake and llvm
|
||||||
libffi-dev libxml2-dev # for llvm
|
libffi-dev libxml2-dev # for llvm
|
||||||
|
curl # snappy
|
||||||
|
file
|
||||||
|
git # for thrift
|
||||||
|
libgmp-dev # for gdb
|
||||||
|
gperf # for proxygen
|
||||||
|
libssl-dev
|
||||||
libedit-dev libpcre3-dev automake bison # for swig
|
libedit-dev libpcre3-dev automake bison # for swig
|
||||||
)
|
)
|
||||||
|
|
||||||
TOOLCHAIN_RUN_DEPS=(
|
TOOLCHAIN_RUN_DEPS=(
|
||||||
make # generic build tools
|
make # generic build tools
|
||||||
tar gzip bzip2 xz-utils # used for archive unpacking
|
tar gzip bzip2 xz-utils # used for archive unpacking
|
||||||
@@ -25,7 +35,9 @@ TOOLCHAIN_RUN_DEPS=(
|
|||||||
libcurl4 # for cmake
|
libcurl4 # for cmake
|
||||||
libreadline8 # for cmake and llvm
|
libreadline8 # for cmake and llvm
|
||||||
libffi7 libxml2 # for llvm
|
libffi7 libxml2 # for llvm
|
||||||
|
libssl-dev # for libevent
|
||||||
)
|
)
|
||||||
|
|
||||||
MEMGRAPH_BUILD_DEPS=(
|
MEMGRAPH_BUILD_DEPS=(
|
||||||
git # source code control
|
git # source code control
|
||||||
make pkg-config # build system
|
make pkg-config # build system
|
||||||
@@ -43,13 +55,18 @@ MEMGRAPH_BUILD_DEPS=(
|
|||||||
doxygen graphviz # source documentation generators
|
doxygen graphviz # source documentation generators
|
||||||
mono-runtime mono-mcs zip unzip default-jdk-headless # for driver tests
|
mono-runtime mono-mcs zip unzip default-jdk-headless # for driver tests
|
||||||
dotnet-sdk-3.1 golang nodejs npm
|
dotnet-sdk-3.1 golang nodejs npm
|
||||||
|
autoconf # for jemalloc code generation
|
||||||
|
libtool # for protobuf code generation
|
||||||
)
|
)
|
||||||
|
|
||||||
list() {
|
list() {
|
||||||
echo "$1"
|
echo "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
check() {
|
check() {
|
||||||
check_all_dpkg "$1"
|
check_all_dpkg "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
install() {
|
install() {
|
||||||
cd "$DIR"
|
cd "$DIR"
|
||||||
apt update
|
apt update
|
||||||
@@ -74,5 +91,6 @@ install() {
|
|||||||
apt install -y "$pkg"
|
apt install -y "$pkg"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
deps=$2"[*]"
|
deps=$2"[*]"
|
||||||
"$1" "${!deps}"
|
"$1" "${!deps}"
|
||||||
|
|||||||
96
environment/os/ubuntu-22.04.sh
Executable file
96
environment/os/ubuntu-22.04.sh
Executable file
@@ -0,0 +1,96 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||||
|
source "$DIR/../util.sh"
|
||||||
|
|
||||||
|
check_operating_system "ubuntu-22.04"
|
||||||
|
check_architecture "x86_64"
|
||||||
|
|
||||||
|
TOOLCHAIN_BUILD_DEPS=(
|
||||||
|
coreutils gcc g++ build-essential make # generic build tools
|
||||||
|
wget # used for archive download
|
||||||
|
gnupg # used for archive signature verification
|
||||||
|
tar gzip bzip2 xz-utils unzip # used for archive unpacking
|
||||||
|
zlib1g-dev # zlib library used for all builds
|
||||||
|
libexpat1-dev libipt-dev libbabeltrace-dev liblzma-dev python3-dev texinfo # for gdb
|
||||||
|
libcurl4-openssl-dev # for cmake
|
||||||
|
libreadline-dev # for cmake and llvm
|
||||||
|
libffi-dev libxml2-dev # for llvm
|
||||||
|
curl # snappy
|
||||||
|
file
|
||||||
|
git # for thrift
|
||||||
|
libgmp-dev # for gdb
|
||||||
|
gperf # for proxygen
|
||||||
|
libssl-dev
|
||||||
|
libedit-dev libpcre3-dev automake bison # for swig
|
||||||
|
)
|
||||||
|
|
||||||
|
TOOLCHAIN_RUN_DEPS=(
|
||||||
|
make # generic build tools
|
||||||
|
tar gzip bzip2 xz-utils # used for archive unpacking
|
||||||
|
zlib1g # zlib library used for all builds
|
||||||
|
libexpat1 libipt2 libbabeltrace1 liblzma5 python3 # for gdb
|
||||||
|
libcurl4 # for cmake
|
||||||
|
libreadline8 # for cmake and llvm
|
||||||
|
libffi7 libxml2 # for llvm
|
||||||
|
libssl-dev # for libevent
|
||||||
|
)
|
||||||
|
|
||||||
|
MEMGRAPH_BUILD_DEPS=(
|
||||||
|
git # source code control
|
||||||
|
make pkg-config # build system
|
||||||
|
curl wget # for downloading libs
|
||||||
|
uuid-dev default-jre-headless # required by antlr
|
||||||
|
libreadline-dev # for memgraph console
|
||||||
|
libpython3-dev python3-dev # for query modules
|
||||||
|
libssl-dev
|
||||||
|
libseccomp-dev
|
||||||
|
netcat # tests are using nc to wait for memgraph
|
||||||
|
python3 python3-virtualenv python3-pip # for qa, macro_benchmark and stress tests
|
||||||
|
python3-yaml # for the configuration generator
|
||||||
|
libcurl4-openssl-dev # mg-requests
|
||||||
|
sbcl # for custom Lisp C++ preprocessing
|
||||||
|
doxygen graphviz # source documentation generators
|
||||||
|
mono-runtime mono-mcs zip unzip default-jdk-headless # for driver tests
|
||||||
|
dotnet-sdk-6.0 golang nodejs npm
|
||||||
|
autoconf # for jemalloc code generation
|
||||||
|
libtool # for protobuf code generation
|
||||||
|
)
|
||||||
|
|
||||||
|
list() {
|
||||||
|
echo "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
check() {
|
||||||
|
check_all_dpkg "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cd "$DIR"
|
||||||
|
apt update
|
||||||
|
# If GitHub Actions runner is installed, append LANG to the environment.
|
||||||
|
# Python related tests doesn't work the LANG export.
|
||||||
|
if [ -d "/home/gh/actions-runner" ]; then
|
||||||
|
echo "LANG=en_US.utf8" >> /home/gh/actions-runner/.env
|
||||||
|
else
|
||||||
|
echo "NOTE: export LANG=en_US.utf8"
|
||||||
|
fi
|
||||||
|
apt install -y wget
|
||||||
|
for pkg in $1; do
|
||||||
|
if [ "$pkg" == dotnet-sdk-6.0 ]; then
|
||||||
|
if ! dpkg -s dotnet-sdk-6.0 2>/dev/null >/dev/null; then
|
||||||
|
wget -nv https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
|
||||||
|
dpkg -i packages-microsoft-prod.deb
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y apt-transport-https dotnet-sdk-6.0
|
||||||
|
fi
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
apt install -y "$pkg"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
deps=$2"[*]"
|
||||||
|
"$1" "${!deps}"
|
||||||
41
environment/toolchain/folly.patch
Normal file
41
environment/toolchain/folly.patch
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
diff -ur a/folly/CMakeLists.txt b/folly/CMakeLists.txt
|
||||||
|
--- a/folly/CMakeLists.txt 2021-12-12 23:10:42.000000000 +0100
|
||||||
|
+++ b/folly/CMakeLists.txt 2022-02-03 15:19:41.349693134 +0100
|
||||||
|
@@ -28,7 +28,6 @@
|
||||||
|
)
|
||||||
|
|
||||||
|
add_subdirectory(experimental/exception_tracer)
|
||||||
|
-add_subdirectory(logging/example)
|
||||||
|
|
||||||
|
if (PYTHON_EXTENSIONS)
|
||||||
|
# Create tree of symbolic links in structure required for successful
|
||||||
|
diff -ur a/folly/experimental/exception_tracer/ExceptionTracerLib.cpp b/folly/experimental/exception_tracer/ExceptionTracerLib.cpp
|
||||||
|
--- a/folly/experimental/exception_tracer/ExceptionTracerLib.cpp 2021-12-12 23:10:42.000000000 +0100
|
||||||
|
+++ b/folly/experimental/exception_tracer/ExceptionTracerLib.cpp 2022-02-03 15:19:11.003368891 +0100
|
||||||
|
@@ -96,6 +96,7 @@
|
||||||
|
#define __builtin_unreachable()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#if 0
|
||||||
|
namespace __cxxabiv1 {
|
||||||
|
|
||||||
|
void __cxa_throw(
|
||||||
|
@@ -154,5 +155,5 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
-
|
||||||
|
+#endif
|
||||||
|
#endif // defined(__GLIBCXX__)
|
||||||
|
diff -ur a/folly/Portability.h b/folly/Portability.h
|
||||||
|
--- a/folly/Portability.h 2021-12-12 23:10:42.000000000 +0100
|
||||||
|
+++ b/folly/Portability.h 2022-02-03 15:19:11.003368891 +0100
|
||||||
|
@@ -566,7 +566,7 @@
|
||||||
|
#define FOLLY_HAS_COROUTINES 0
|
||||||
|
#elif (__cpp_coroutines >= 201703L || __cpp_impl_coroutine >= 201902L) && \
|
||||||
|
(__has_include(<coroutine>) || __has_include(<experimental/coroutine>))
|
||||||
|
-#define FOLLY_HAS_COROUTINES 1
|
||||||
|
+#define FOLLY_HAS_COROUTINES 0
|
||||||
|
// This is mainly to workaround bugs triggered by LTO, when stack allocated
|
||||||
|
// variables in await_suspend end up on a coroutine frame.
|
||||||
|
#define FOLLY_CORO_AWAIT_SUSPEND_NONTRIVIAL_ATTRIBUTES FOLLY_NOINLINE
|
||||||
11
environment/toolchain/proxygen.patch
Normal file
11
environment/toolchain/proxygen.patch
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
diff -ur a/cmake/proxygen-config.cmake.in b/cmake/proxygen-config.cmake.in
|
||||||
|
--- a/cmake/proxygen-config.cmake.in 2021-12-13 02:37:05.000000000 +0100
|
||||||
|
+++ b/cmake/proxygen-config.cmake.in 2022-01-27 17:14:28.284810621 +0100
|
||||||
|
@@ -21,7 +21,6 @@
|
||||||
|
find_dependency(folly)
|
||||||
|
find_dependency(wangle)
|
||||||
|
find_dependency(Fizz)
|
||||||
|
-find_dependency(mvfst)
|
||||||
|
# For now, anything that depends on Proxygen has to copy its FindZstd.cmake
|
||||||
|
# and issue a `find_package(Zstd)`. Uncommenting this won't work because
|
||||||
|
# this Zstd module exposes a library called `zstd`. The right fix is
|
||||||
29
environment/toolchain/snappy.patch
Normal file
29
environment/toolchain/snappy.patch
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
diff -ur a/CMakeLists.txt b/CMakeLists.txt
|
||||||
|
--- a/CMakeLists.txt 2021-05-05 00:53:34.000000000 +0200
|
||||||
|
+++ b/CMakeLists.txt 2022-01-27 17:18:34.758302398 +0100
|
||||||
|
@@ -52,9 +52,9 @@
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHs-c-")
|
||||||
|
add_definitions(-D_HAS_EXCEPTIONS=0)
|
||||||
|
|
||||||
|
- # Disable RTTI.
|
||||||
|
- string(REGEX REPLACE "/GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||||
|
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-")
|
||||||
|
+ # # Disable RTTI.
|
||||||
|
+ # string(REGEX REPLACE "/GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||||
|
+ # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-")
|
||||||
|
else(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
|
# Use -Wall for clang and gcc.
|
||||||
|
if(NOT CMAKE_CXX_FLAGS MATCHES "-Wall")
|
||||||
|
@@ -77,9 +77,9 @@
|
||||||
|
string(REGEX REPLACE "-fexceptions" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
|
||||||
|
|
||||||
|
- # Disable RTTI.
|
||||||
|
- string(REGEX REPLACE "-frtti" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||||
|
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
|
||||||
|
+ # # Disable RTTI.
|
||||||
|
+ # string(REGEX REPLACE "-frtti" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||||
|
+ # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
|
||||||
|
endif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
|
|
||||||
|
# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to make
|
||||||
556
environment/toolchain/v3.sh
Executable file
556
environment/toolchain/v3.sh
Executable file
@@ -0,0 +1,556 @@
|
|||||||
|
#!/bin/bash -e
|
||||||
|
|
||||||
|
# helpers
|
||||||
|
pushd () { command pushd "$@" > /dev/null; }
|
||||||
|
popd () { command popd "$@" > /dev/null; }
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||||
|
CPUS=$( grep -c processor < /proc/cpuinfo )
|
||||||
|
cd "$DIR"
|
||||||
|
|
||||||
|
source "$DIR/../util.sh"
|
||||||
|
DISTRO="$(operating_system)"
|
||||||
|
|
||||||
|
# toolchain version
|
||||||
|
TOOLCHAIN_VERSION=3
|
||||||
|
|
||||||
|
# package versions used
|
||||||
|
GCC_VERSION=11.1.0
|
||||||
|
BINUTILS_VERSION=2.36.1
|
||||||
|
case "$DISTRO" in
|
||||||
|
centos-7) # because GDB >= 9 does NOT compile with readline6.
|
||||||
|
GDB_VERSION=8.3
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
GDB_VERSION=10.2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
CMAKE_VERSION=3.20.5
|
||||||
|
CPPCHECK_VERSION=2.4.1
|
||||||
|
LLVM_VERSION=12.0.1rc4
|
||||||
|
LLVM_VERSION_LONG=12.0.1-rc4
|
||||||
|
SWIG_VERSION=4.0.2 # used only for LLVM compilation
|
||||||
|
|
||||||
|
# Check for the dependencies.
|
||||||
|
echo "ALL BUILD PACKAGES: $($DIR/../os/$DISTRO.sh list TOOLCHAIN_BUILD_DEPS)"
|
||||||
|
$DIR/../os/$DISTRO.sh check TOOLCHAIN_BUILD_DEPS
|
||||||
|
echo "ALL RUN PACKAGES: $($DIR/../os/$DISTRO.sh list TOOLCHAIN_RUN_DEPS)"
|
||||||
|
$DIR/../os/$DISTRO.sh check TOOLCHAIN_RUN_DEPS
|
||||||
|
|
||||||
|
# check installation directory
|
||||||
|
NAME=toolchain-v$TOOLCHAIN_VERSION
|
||||||
|
PREFIX=/opt/$NAME
|
||||||
|
mkdir -p $PREFIX >/dev/null 2>/dev/null || true
|
||||||
|
if [ ! -d $PREFIX ] || [ ! -w $PREFIX ]; then
|
||||||
|
echo "Please make sure that the directory '$PREFIX' exists and is writable by the current user!"
|
||||||
|
echo
|
||||||
|
echo "If unsure, execute these commands as root:"
|
||||||
|
echo " mkdir $PREFIX && chown $USER:$USER $PREFIX"
|
||||||
|
echo
|
||||||
|
echo "Press <return> when you have created the directory and granted permissions."
|
||||||
|
# wait for the directory to be created
|
||||||
|
while true; do
|
||||||
|
read
|
||||||
|
if [ ! -d $PREFIX ] || [ ! -w $PREFIX ]; then
|
||||||
|
echo
|
||||||
|
echo "You can't continue before you have created the directory and granted permissions!"
|
||||||
|
echo
|
||||||
|
echo "Press <return> when you have created the directory and granted permissions."
|
||||||
|
else
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# create archives directory
|
||||||
|
mkdir -p archives
|
||||||
|
|
||||||
|
# download all archives
|
||||||
|
pushd archives
|
||||||
|
if [ ! -f gcc-$GCC_VERSION.tar.gz ]; then
|
||||||
|
wget https://ftp.gnu.org/gnu/gcc/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.gz
|
||||||
|
fi
|
||||||
|
if [ ! -f binutils-$BINUTILS_VERSION.tar.gz ]; then
|
||||||
|
wget https://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS_VERSION.tar.gz
|
||||||
|
fi
|
||||||
|
if [ ! -f gdb-$GDB_VERSION.tar.gz ]; then
|
||||||
|
wget https://ftp.gnu.org/gnu/gdb/gdb-$GDB_VERSION.tar.gz
|
||||||
|
fi
|
||||||
|
if [ ! -f cmake-$CMAKE_VERSION.tar.gz ]; then
|
||||||
|
wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION.tar.gz
|
||||||
|
fi
|
||||||
|
if [ ! -f swig-$SWIG_VERSION.tar.gz ]; then
|
||||||
|
wget https://github.com/swig/swig/archive/rel-$SWIG_VERSION.tar.gz -O swig-$SWIG_VERSION.tar.gz
|
||||||
|
fi
|
||||||
|
if [ ! -f cppcheck-$CPPCHECK_VERSION.tar.gz ]; then
|
||||||
|
wget https://github.com/danmar/cppcheck/archive/$CPPCHECK_VERSION.tar.gz -O cppcheck-$CPPCHECK_VERSION.tar.gz
|
||||||
|
fi
|
||||||
|
if [ ! -f llvm-$LLVM_VERSION.src.tar.xz ]; then
|
||||||
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/llvm-$LLVM_VERSION.src.tar.xz
|
||||||
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/clang-$LLVM_VERSION.src.tar.xz
|
||||||
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/lld-$LLVM_VERSION.src.tar.xz
|
||||||
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/clang-tools-extra-$LLVM_VERSION.src.tar.xz
|
||||||
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/compiler-rt-$LLVM_VERSION.src.tar.xz
|
||||||
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/libunwind-$LLVM_VERSION.src.tar.xz
|
||||||
|
fi
|
||||||
|
if [ ! -f pahole-gdb-master.zip ]; then
|
||||||
|
wget https://github.com/PhilArmstrong/pahole-gdb/archive/master.zip -O pahole-gdb-master.zip
|
||||||
|
fi
|
||||||
|
|
||||||
|
# verify all archives
|
||||||
|
# NOTE: Verification can fail if the archive is signed by another developer. I
|
||||||
|
# haven't added commands to download all developer GnuPG keys because the
|
||||||
|
# download is very slow. If the verification fails for you, figure out who has
|
||||||
|
# signed the archive and download their public key instead.
|
||||||
|
GPG="gpg --homedir .gnupg"
|
||||||
|
KEYSERVER="hkp://keyserver.ubuntu.com"
|
||||||
|
|
||||||
|
mkdir -p .gnupg
|
||||||
|
chmod 700 .gnupg
|
||||||
|
# verify gcc
|
||||||
|
if [ ! -f gcc-$GCC_VERSION.tar.gz.sig ]; then
|
||||||
|
wget https://ftp.gnu.org/gnu/gcc/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.gz.sig
|
||||||
|
fi
|
||||||
|
# list of valid gcc gnupg keys: https://gcc.gnu.org/mirrors.html
|
||||||
|
$GPG --keyserver $KEYSERVER --recv-keys 0x6C35B99309B5FA62
|
||||||
|
$GPG --verify gcc-$GCC_VERSION.tar.gz.sig gcc-$GCC_VERSION.tar.gz
|
||||||
|
# verify binutils
|
||||||
|
if [ ! -f binutils-$BINUTILS_VERSION.tar.gz.sig ]; then
|
||||||
|
wget https://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS_VERSION.tar.gz.sig
|
||||||
|
fi
|
||||||
|
$GPG --keyserver $KEYSERVER --recv-keys 0xDD9E3C4F
|
||||||
|
$GPG --verify binutils-$BINUTILS_VERSION.tar.gz.sig binutils-$BINUTILS_VERSION.tar.gz
|
||||||
|
# verify gdb
|
||||||
|
if [ ! -f gdb-$GDB_VERSION.tar.gz.sig ]; then
|
||||||
|
wget https://ftp.gnu.org/gnu/gdb/gdb-$GDB_VERSION.tar.gz.sig
|
||||||
|
fi
|
||||||
|
$GPG --keyserver $KEYSERVER --recv-keys 0xFF325CF3
|
||||||
|
$GPG --verify gdb-$GDB_VERSION.tar.gz.sig gdb-$GDB_VERSION.tar.gz
|
||||||
|
# verify cmake
|
||||||
|
if [ ! -f cmake-$CMAKE_VERSION-SHA-256.txt ] || [ ! -f cmake-$CMAKE_VERSION-SHA-256.txt.asc ]; then
|
||||||
|
wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-SHA-256.txt
|
||||||
|
wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-SHA-256.txt.asc
|
||||||
|
# Because CentOS 7 doesn't have the `--ignore-missing` flag for `sha256sum`
|
||||||
|
# we filter out the missing files from the sums here manually.
|
||||||
|
cat cmake-$CMAKE_VERSION-SHA-256.txt | grep "cmake-$CMAKE_VERSION.tar.gz" > cmake-$CMAKE_VERSION-SHA-256-filtered.txt
|
||||||
|
fi
|
||||||
|
$GPG --keyserver $KEYSERVER --recv-keys 0xC6C265324BBEBDC350B513D02D2CEF1034921684
|
||||||
|
sha256sum -c cmake-$CMAKE_VERSION-SHA-256-filtered.txt
|
||||||
|
$GPG --verify cmake-$CMAKE_VERSION-SHA-256.txt.asc cmake-$CMAKE_VERSION-SHA-256.txt
|
||||||
|
# verify llvm, cfe, lld, clang-tools-extra
|
||||||
|
if [ ! -f llvm-$LLVM_VERSION.src.tar.xz.sig ]; then
|
||||||
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/llvm-$LLVM_VERSION.src.tar.xz.sig
|
||||||
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/clang-$LLVM_VERSION.src.tar.xz.sig
|
||||||
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/lld-$LLVM_VERSION.src.tar.xz.sig
|
||||||
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/clang-tools-extra-$LLVM_VERSION.src.tar.xz.sig
|
||||||
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/compiler-rt-$LLVM_VERSION.src.tar.xz.sig
|
||||||
|
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION_LONG/libunwind-$LLVM_VERSION.src.tar.xz.sig
|
||||||
|
fi
|
||||||
|
# list of valid llvm gnupg keys: https://releases.llvm.org/download.html
|
||||||
|
$GPG --keyserver $KEYSERVER --recv-keys 0x474E22316ABF4785A88C6E8EA2C794A986419D8A
|
||||||
|
$GPG --verify llvm-$LLVM_VERSION.src.tar.xz.sig llvm-$LLVM_VERSION.src.tar.xz
|
||||||
|
$GPG --verify clang-$LLVM_VERSION.src.tar.xz.sig clang-$LLVM_VERSION.src.tar.xz
|
||||||
|
$GPG --verify lld-$LLVM_VERSION.src.tar.xz.sig lld-$LLVM_VERSION.src.tar.xz
|
||||||
|
$GPG --verify clang-tools-extra-$LLVM_VERSION.src.tar.xz.sig clang-tools-extra-$LLVM_VERSION.src.tar.xz
|
||||||
|
$GPG --verify compiler-rt-$LLVM_VERSION.src.tar.xz.sig compiler-rt-$LLVM_VERSION.src.tar.xz
|
||||||
|
$GPG --verify libunwind-$LLVM_VERSION.src.tar.xz.sig libunwind-$LLVM_VERSION.src.tar.xz
|
||||||
|
popd
|
||||||
|
|
||||||
|
# create build directory
|
||||||
|
mkdir -p build
|
||||||
|
pushd build
|
||||||
|
|
||||||
|
# compile gcc
|
||||||
|
if [ ! -f $PREFIX/bin/gcc ]; then
|
||||||
|
if [ -d gcc-$GCC_VERSION ]; then
|
||||||
|
rm -rf gcc-$GCC_VERSION
|
||||||
|
fi
|
||||||
|
tar -xvf ../archives/gcc-$GCC_VERSION.tar.gz
|
||||||
|
pushd gcc-$GCC_VERSION
|
||||||
|
./contrib/download_prerequisites
|
||||||
|
mkdir build && pushd build
|
||||||
|
# influenced by: https://buildd.debian.org/status/fetch.php?pkg=gcc-8&arch=amd64&ver=8.3.0-6&stamp=1554588545
|
||||||
|
../configure -v \
|
||||||
|
--build=x86_64-linux-gnu \
|
||||||
|
--host=x86_64-linux-gnu \
|
||||||
|
--target=x86_64-linux-gnu \
|
||||||
|
--prefix=$PREFIX \
|
||||||
|
--disable-multilib \
|
||||||
|
--with-system-zlib \
|
||||||
|
--enable-checking=release \
|
||||||
|
--enable-languages=c,c++,fortran \
|
||||||
|
--enable-gold=yes \
|
||||||
|
--enable-ld=yes \
|
||||||
|
--enable-lto \
|
||||||
|
--enable-bootstrap \
|
||||||
|
--disable-vtable-verify \
|
||||||
|
--disable-werror \
|
||||||
|
--without-included-gettext \
|
||||||
|
--enable-threads=posix \
|
||||||
|
--enable-nls \
|
||||||
|
--enable-clocale=gnu \
|
||||||
|
--enable-libstdcxx-debug \
|
||||||
|
--enable-libstdcxx-time=yes \
|
||||||
|
--enable-gnu-unique-object \
|
||||||
|
--enable-libmpx \
|
||||||
|
--enable-plugin \
|
||||||
|
--enable-default-pie \
|
||||||
|
--with-target-system-zlib \
|
||||||
|
--with-tune=generic \
|
||||||
|
--without-cuda-driver
|
||||||
|
#--program-suffix=$( printf "$GCC_VERSION" | cut -d '.' -f 1,2 ) \
|
||||||
|
make -j$CPUS
|
||||||
|
# make -k check # run test suite
|
||||||
|
make install
|
||||||
|
popd && popd
|
||||||
|
fi
|
||||||
|
|
||||||
|
# activate toolchain
|
||||||
|
export PATH=$PREFIX/bin:$PATH
|
||||||
|
export LD_LIBRARY_PATH=$PREFIX/lib64
|
||||||
|
|
||||||
|
# compile binutils
|
||||||
|
if [ ! -f $PREFIX/bin/ld.gold ]; then
|
||||||
|
if [ -d binutils-$BINUTILS_VERSION ]; then
|
||||||
|
rm -rf binutils-$BINUTILS_VERSION
|
||||||
|
fi
|
||||||
|
tar -xvf ../archives/binutils-$BINUTILS_VERSION.tar.gz
|
||||||
|
pushd binutils-$BINUTILS_VERSION
|
||||||
|
mkdir build && pushd build
|
||||||
|
# influenced by: https://buildd.debian.org/status/fetch.php?pkg=binutils&arch=amd64&ver=2.32-7&stamp=1553247092
|
||||||
|
env \
|
||||||
|
CC=gcc \
|
||||||
|
CXX=g++ \
|
||||||
|
CFLAGS="-g -O2" \
|
||||||
|
CXXFLAGS="-g -O2" \
|
||||||
|
LDFLAGS="" \
|
||||||
|
../configure \
|
||||||
|
--build=x86_64-linux-gnu \
|
||||||
|
--host=x86_64-linux-gnu \
|
||||||
|
--prefix=$PREFIX \
|
||||||
|
--enable-ld=default \
|
||||||
|
--enable-gold \
|
||||||
|
--enable-lto \
|
||||||
|
--enable-plugins \
|
||||||
|
--enable-shared \
|
||||||
|
--enable-threads \
|
||||||
|
--with-system-zlib \
|
||||||
|
--enable-deterministic-archives \
|
||||||
|
--disable-compressed-debug-sections \
|
||||||
|
--enable-new-dtags \
|
||||||
|
--disable-werror
|
||||||
|
make -j$CPUS
|
||||||
|
# make -k check # run test suite
|
||||||
|
make install
|
||||||
|
popd && popd
|
||||||
|
fi
|
||||||
|
|
||||||
|
# compile gdb
|
||||||
|
if [ ! -f $PREFIX/bin/gdb ]; then
|
||||||
|
if [ -d gdb-$GDB_VERSION ]; then
|
||||||
|
rm -rf gdb-$GDB_VERSION
|
||||||
|
fi
|
||||||
|
tar -xvf ../archives/gdb-$GDB_VERSION.tar.gz
|
||||||
|
pushd gdb-$GDB_VERSION
|
||||||
|
mkdir build && pushd build
|
||||||
|
# https://buildd.debian.org/status/fetch.php?pkg=gdb&arch=amd64&ver=8.2.1-2&stamp=1550831554&raw=0
|
||||||
|
env \
|
||||||
|
CC=gcc \
|
||||||
|
CXX=g++ \
|
||||||
|
CFLAGS="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security" \
|
||||||
|
CXXFLAGS="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security" \
|
||||||
|
CPPFLAGS="-Wdate-time -D_FORTIFY_SOURCE=2 -fPIC" \
|
||||||
|
LDFLAGS="-Wl,-z,relro" \
|
||||||
|
PYTHON="" \
|
||||||
|
../configure \
|
||||||
|
--build=x86_64-linux-gnu \
|
||||||
|
--host=x86_64-linux-gnu \
|
||||||
|
--prefix=$PREFIX \
|
||||||
|
--disable-maintainer-mode \
|
||||||
|
--disable-dependency-tracking \
|
||||||
|
--disable-silent-rules \
|
||||||
|
--disable-gdbtk \
|
||||||
|
--disable-shared \
|
||||||
|
--without-guile \
|
||||||
|
--with-system-gdbinit=$PREFIX/etc/gdb/gdbinit \
|
||||||
|
--with-system-readline \
|
||||||
|
--with-expat \
|
||||||
|
--with-system-zlib \
|
||||||
|
--with-lzma \
|
||||||
|
--with-babeltrace \
|
||||||
|
--with-intel-pt \
|
||||||
|
--enable-tui \
|
||||||
|
--with-python=python3
|
||||||
|
make -j$CPUS
|
||||||
|
make install
|
||||||
|
popd && popd
|
||||||
|
fi
|
||||||
|
|
||||||
|
# install pahole
|
||||||
|
if [ ! -d $PREFIX/share/pahole-gdb ]; then
|
||||||
|
unzip ../archives/pahole-gdb-master.zip
|
||||||
|
mv pahole-gdb-master $PREFIX/share/pahole-gdb
|
||||||
|
fi
|
||||||
|
|
||||||
|
# setup system gdbinit
|
||||||
|
if [ ! -f $PREFIX/etc/gdb/gdbinit ]; then
|
||||||
|
mkdir -p $PREFIX/etc/gdb
|
||||||
|
cat >$PREFIX/etc/gdb/gdbinit <<EOF
|
||||||
|
# improve formatting
|
||||||
|
set print pretty on
|
||||||
|
set print object on
|
||||||
|
set print static-members on
|
||||||
|
set print vtbl on
|
||||||
|
set print demangle on
|
||||||
|
set demangle-style gnu-v3
|
||||||
|
set print sevenbit-strings off
|
||||||
|
|
||||||
|
# load libstdc++ pretty printers
|
||||||
|
add-auto-load-scripts-directory $PREFIX/lib64
|
||||||
|
add-auto-load-safe-path $PREFIX
|
||||||
|
|
||||||
|
# load pahole
|
||||||
|
python
|
||||||
|
sys.path.insert(0, "$PREFIX/share/pahole-gdb")
|
||||||
|
import offsets
|
||||||
|
import pahole
|
||||||
|
end
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# compile cmake
|
||||||
|
if [ ! -f $PREFIX/bin/cmake ]; then
|
||||||
|
if [ -d cmake-$CMAKE_VERSION ]; then
|
||||||
|
rm -rf cmake-$CMAKE_VERSION
|
||||||
|
fi
|
||||||
|
tar -xvf ../archives/cmake-$CMAKE_VERSION.tar.gz
|
||||||
|
pushd cmake-$CMAKE_VERSION
|
||||||
|
# influenced by: https://buildd.debian.org/status/fetch.php?pkg=cmake&arch=amd64&ver=3.13.4-1&stamp=1549799837
|
||||||
|
echo 'set(CMAKE_SKIP_RPATH ON CACHE BOOL "Skip rpath" FORCE)' >> build-flags.cmake
|
||||||
|
echo 'set(CMAKE_USE_RELATIVE_PATHS ON CACHE BOOL "Use relative paths" FORCE)' >> build-flags.cmake
|
||||||
|
echo 'set(CMAKE_C_FLAGS "-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2" CACHE STRING "C flags" FORCE)' >> build-flags.cmake
|
||||||
|
echo 'set(CMAKE_CXX_FLAGS "-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2" CACHE STRING "C++ flags" FORCE)' >> build-flags.cmake
|
||||||
|
echo 'set(CMAKE_SKIP_BOOTSTRAP_TEST ON CACHE BOOL "Skip BootstrapTest" FORCE)' >> build-flags.cmake
|
||||||
|
echo 'set(BUILD_CursesDialog ON CACHE BOOL "Build curses GUI" FORCE)' >> build-flags.cmake
|
||||||
|
mkdir build && pushd build
|
||||||
|
../bootstrap \
|
||||||
|
--prefix=$PREFIX \
|
||||||
|
--init=../build-flags.cmake \
|
||||||
|
--parallel=$CPUS \
|
||||||
|
--system-curl
|
||||||
|
make -j$CPUS
|
||||||
|
# make test # run test suite
|
||||||
|
make install
|
||||||
|
popd && popd
|
||||||
|
fi
|
||||||
|
|
||||||
|
# compile cppcheck
|
||||||
|
if [ ! -f $PREFIX/bin/cppcheck ]; then
|
||||||
|
if [ -d cppcheck-$CPPCHECK_VERSION ]; then
|
||||||
|
rm -rf cppcheck-$CPPCHECK_VERSION
|
||||||
|
fi
|
||||||
|
tar -xvf ../archives/cppcheck-$CPPCHECK_VERSION.tar.gz
|
||||||
|
pushd cppcheck-$CPPCHECK_VERSION
|
||||||
|
# this was fixed in cppcheck 2.5, remove this in toolchain-v4 after the lib is updated
|
||||||
|
# to 2.5+ version.
|
||||||
|
sed -i '/#include <iostream>/ a #include <limits>' lib/symboldatabase.cpp
|
||||||
|
env \
|
||||||
|
CC=gcc \
|
||||||
|
CXX=g++ \
|
||||||
|
PREFIX=$PREFIX \
|
||||||
|
FILESDIR=$PREFIX/share/cppcheck \
|
||||||
|
CFGDIR=$PREFIX/share/cppcheck/cfg \
|
||||||
|
make -j$CPUS
|
||||||
|
env \
|
||||||
|
CC=gcc \
|
||||||
|
CXX=g++ \
|
||||||
|
PREFIX=$PREFIX \
|
||||||
|
FILESDIR=$PREFIX/share/cppcheck \
|
||||||
|
CFGDIR=$PREFIX/share/cppcheck/cfg \
|
||||||
|
make install
|
||||||
|
popd
|
||||||
|
fi
|
||||||
|
|
||||||
|
# compile swig
|
||||||
|
if [ ! -d swig-$SWIG_VERSION/install ]; then
|
||||||
|
if [ -d swig-$SWIG_VERSION ]; then
|
||||||
|
rm -rf swig-$SWIG_VERSION
|
||||||
|
fi
|
||||||
|
tar -xvf ../archives/swig-$SWIG_VERSION.tar.gz
|
||||||
|
mv swig-rel-$SWIG_VERSION swig-$SWIG_VERSION
|
||||||
|
pushd swig-$SWIG_VERSION
|
||||||
|
./autogen.sh
|
||||||
|
mkdir build && pushd build
|
||||||
|
../configure --prefix=$DIR/build/swig-$SWIG_VERSION/install
|
||||||
|
make -j$CPUS
|
||||||
|
make install
|
||||||
|
popd && popd
|
||||||
|
fi
|
||||||
|
|
||||||
|
# compile llvm
|
||||||
|
if [ ! -f $PREFIX/bin/clang ]; then
|
||||||
|
if [ -d llvm-$LLVM_VERSION ]; then
|
||||||
|
rm -rf llvm-$LLVM_VERSION
|
||||||
|
fi
|
||||||
|
tar -xvf ../archives/llvm-$LLVM_VERSION.src.tar.xz
|
||||||
|
mv llvm-$LLVM_VERSION.src llvm-$LLVM_VERSION
|
||||||
|
tar -xvf ../archives/clang-$LLVM_VERSION.src.tar.xz
|
||||||
|
mv clang-$LLVM_VERSION.src llvm-$LLVM_VERSION/tools/clang
|
||||||
|
tar -xvf ../archives/lld-$LLVM_VERSION.src.tar.xz
|
||||||
|
mv lld-$LLVM_VERSION.src/ llvm-$LLVM_VERSION/tools/lld
|
||||||
|
tar -xvf ../archives/clang-tools-extra-$LLVM_VERSION.src.tar.xz
|
||||||
|
mv clang-tools-extra-$LLVM_VERSION.src/ llvm-$LLVM_VERSION/tools/clang/tools/extra
|
||||||
|
tar -xvf ../archives/compiler-rt-$LLVM_VERSION.src.tar.xz
|
||||||
|
mv compiler-rt-$LLVM_VERSION.src/ llvm-$LLVM_VERSION/projects/compiler-rt
|
||||||
|
tar -xvf ../archives/libunwind-$LLVM_VERSION.src.tar.xz
|
||||||
|
mv libunwind-$LLVM_VERSION.src/include/mach-o llvm-$LLVM_VERSION/tools/lld/include
|
||||||
|
pushd llvm-$LLVM_VERSION
|
||||||
|
mkdir build && pushd build
|
||||||
|
# activate swig
|
||||||
|
export PATH=$DIR/build/swig-$SWIG_VERSION/install/bin:$PATH
|
||||||
|
# influenced by: https://buildd.debian.org/status/fetch.php?pkg=llvm-toolchain-7&arch=amd64&ver=1%3A7.0.1%7E%2Brc2-1%7Eexp1&stamp=1541506173&raw=0
|
||||||
|
cmake .. \
|
||||||
|
-DCMAKE_C_COMPILER=$PREFIX/bin/gcc \
|
||||||
|
-DCMAKE_CXX_COMPILER=$PREFIX/bin/g++ \
|
||||||
|
-DCMAKE_CXX_LINK_FLAGS="-L$PREFIX/lib64 -Wl,-rpath,$PREFIX/lib64" \
|
||||||
|
-DCMAKE_INSTALL_PREFIX=$PREFIX \
|
||||||
|
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||||
|
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO="-O2 -DNDEBUG" \
|
||||||
|
-DCMAKE_CXX_FLAGS=' -fuse-ld=gold -fPIC -Wno-unused-command-line-argument -Wno-unknown-warning-option' \
|
||||||
|
-DCMAKE_C_FLAGS=' -fuse-ld=gold -fPIC -Wno-unused-command-line-argument -Wno-unknown-warning-option' \
|
||||||
|
-DLLVM_LINK_LLVM_DYLIB=ON \
|
||||||
|
-DLLVM_INSTALL_UTILS=ON \
|
||||||
|
-DLLVM_VERSION_SUFFIX= \
|
||||||
|
-DLLVM_BUILD_LLVM_DYLIB=ON \
|
||||||
|
-DLLVM_ENABLE_RTTI=ON \
|
||||||
|
-DLLVM_ENABLE_FFI=ON \
|
||||||
|
-DLLVM_BINUTILS_INCDIR=$PREFIX/include/ \
|
||||||
|
-DLLVM_USE_PERF=yes
|
||||||
|
make -j$CPUS
|
||||||
|
make -j$CPUS check-clang # run clang test suite
|
||||||
|
make -j$CPUS check-lld # run lld test suite
|
||||||
|
make install
|
||||||
|
popd && popd
|
||||||
|
fi
|
||||||
|
|
||||||
|
# create README
|
||||||
|
if [ ! -f $PREFIX/README.md ]; then
|
||||||
|
cat >$PREFIX/README.md <<EOF
|
||||||
|
# Memgraph Toolchain v$TOOLCHAIN_VERSION
|
||||||
|
|
||||||
|
## Included tools
|
||||||
|
|
||||||
|
- GCC $GCC_VERSION
|
||||||
|
- Binutils $BINUTILS_VERSION
|
||||||
|
- GDB $GDB_VERSION
|
||||||
|
- CMake $CMAKE_VERSION
|
||||||
|
- Cppcheck $CPPCHECK_VERSION
|
||||||
|
- LLVM (Clang, LLD, compiler-rt, Clang tools extra) $LLVM_VERSION
|
||||||
|
|
||||||
|
## Required libraries
|
||||||
|
|
||||||
|
In order to be able to run all of these tools you should install the following
|
||||||
|
packages:
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
$($DIR/../os/$DISTRO.sh list TOOLCHAIN_RUN_DEPS)
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
In order to use the toolchain you just have to source the activation script:
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
source $PREFIX/activate
|
||||||
|
\`\`\`
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# create activation script
|
||||||
|
if [ ! -f $PREFIX/activate ]; then
|
||||||
|
cat >$PREFIX/activate <<EOF
|
||||||
|
# This file must be used with "source $PREFIX/activate" *from bash*
|
||||||
|
# You can't run it directly!
|
||||||
|
|
||||||
|
env_error="You already have an active virtual environment!"
|
||||||
|
|
||||||
|
# zsh does not recognize the option -t of the command type
|
||||||
|
# therefore we use the alternative whence -w
|
||||||
|
if [[ "\$ZSH_NAME" == "zsh" ]]; then
|
||||||
|
# check for active virtual environments
|
||||||
|
if [ "\$( whence -w deactivate )" != "deactivate: none" ]; then
|
||||||
|
echo \$env_error
|
||||||
|
return 0;
|
||||||
|
fi
|
||||||
|
# any other shell
|
||||||
|
else
|
||||||
|
# check for active virtual environments
|
||||||
|
if [ "\$( type -t deactivate )" != "" ]; then
|
||||||
|
echo \$env_error
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check that we aren't root
|
||||||
|
if [[ "\$USER" == "root" ]]; then
|
||||||
|
echo "You shouldn't use the toolchain as root!"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# save original environment
|
||||||
|
export ORIG_PATH=\$PATH
|
||||||
|
export ORIG_PS1=\$PS1
|
||||||
|
export ORIG_LD_LIBRARY_PATH=\$LD_LIBRARY_PATH
|
||||||
|
|
||||||
|
# activate new environment
|
||||||
|
export PATH=$PREFIX/bin:\$PATH
|
||||||
|
export PS1="($NAME) \$PS1"
|
||||||
|
export LD_LIBRARY_PATH=$PREFIX/lib:$PREFIX/lib64
|
||||||
|
|
||||||
|
# disable root
|
||||||
|
function su () {
|
||||||
|
echo "You don't want to use root functions while using the toolchain!"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
function sudo () {
|
||||||
|
echo "You don't want to use root functions while using the toolchain!"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# create deactivation function
|
||||||
|
function deactivate() {
|
||||||
|
export PATH=\$ORIG_PATH
|
||||||
|
export PS1=\$ORIG_PS1
|
||||||
|
export LD_LIBRARY_PATH=\$ORIG_LD_LIBRARY_PATH
|
||||||
|
unset ORIG_PATH ORIG_PS1 ORIG_LD_LIBRARY_PATH
|
||||||
|
unset -f su sudo deactivate
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# create toolchain archive
|
||||||
|
if [ ! -f $NAME-binaries-$DISTRO.tar.gz ]; then
|
||||||
|
tar --owner=root --group=root -cpvzf $NAME-binaries-$DISTRO.tar.gz -C /opt $NAME
|
||||||
|
fi
|
||||||
|
|
||||||
|
# output final instructions
|
||||||
|
echo -e "\n\n"
|
||||||
|
echo "All tools have been built. They are installed in '$PREFIX'."
|
||||||
|
echo "In order to distribute the tools to someone else, an archive with the toolchain was created in the 'build' directory."
|
||||||
|
echo "If you want to install the packed tools you should execute the following command:"
|
||||||
|
echo
|
||||||
|
echo " tar -xvzf build/$NAME-binaries.tar.gz -C /opt"
|
||||||
|
echo
|
||||||
|
echo "Because the tools were built on this machine, you should probably change the permissions of the installation directory using:"
|
||||||
|
echo
|
||||||
|
echo " OPTIONAL: chown -R root:root $PREFIX"
|
||||||
|
echo
|
||||||
|
echo "In order to use all of the newly compiled tools you should use the prepared activation script:"
|
||||||
|
echo
|
||||||
|
echo " source $PREFIX/activate"
|
||||||
|
echo
|
||||||
|
echo "Or, for more advanced uses, you can add the following lines to your script:"
|
||||||
|
echo
|
||||||
|
echo " export PATH=$PREFIX/bin:\$PATH"
|
||||||
|
echo " export LD_LIBRARY_PATH=$PREFIX/lib:$PREFIX/lib64"
|
||||||
|
echo
|
||||||
|
echo "Enjoy!"
|
||||||
1220
environment/toolchain/v4.sh
Executable file
1220
environment/toolchain/v4.sh
Executable file
File diff suppressed because it is too large
Load Diff
75
environment/toolchain/xz_pgp.txt
Normal file
75
environment/toolchain/xz_pgp.txt
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
mQINBEzEOZIBEACxg/IuXERlDB48JBWmF4NxNUuuup1IhJAJyFGFSKh3OGAO2Ard
|
||||||
|
sNuRLjANsFXA7m7P5eTFcG+BoHHuAVYmKnI3PPZtHVLnUt4pGItPczQZ2BE1WpcI
|
||||||
|
ayjGTBJeKItX3Npqg9D/odO9WWS1i3FQPVdrLn0YH37/BA66jeMQCRo7g7GLpaNf
|
||||||
|
IrvYGsqTbxCwsmA37rpE7oyU4Yrf74HT091WBsRIoq/MelhbxTDMR8eu/dUGZQVc
|
||||||
|
Kj3lN55RepwWwUUKyqarY0zMt4HkFJ7v7yRL+Cvzy92Ouv4Wf2FlhNtEs5LE4Tax
|
||||||
|
W0PO5AEmUoKjX87SezQK0f652018b4u6Ex52cY7p+n5TII/UyoowH6+tY8UHo9yb
|
||||||
|
fStrqgNE/mY2bhA6+AwCaOUGsFzVVPTbjtxL3HacUP/jlA1h78V8VTvTs5d55iG7
|
||||||
|
jSqR9o05wje8rwNiXXK0xtiJahyNzL97Kn/DgPSqPIi45G+8nxWSPFM5eunBKRl9
|
||||||
|
vAnsvwrdPRsR6YR3uMHTuVhQX9/CY891MHkaZJ6wydWtKt3yQwJLYqwo5d4DwnUX
|
||||||
|
CduUwSKv+6RmtWI5ZmTQYOcBRcZyGKml9X9Q8iSbm6cnpFXmLrNQwCJN+D3SiYGc
|
||||||
|
MtbltZo0ysPMa6Xj5xFaYqWk/BI4iLb2Gs+ByGo/+a0Eq4XYBMOpitNniQARAQAB
|
||||||
|
tCdMYXNzZSBDb2xsaW4gPGxhc3NlLmNvbGxpbkB0dWthYW5pLm9yZz6JAlEEEwEK
|
||||||
|
ADsCGwMCHgECF4AECwkIBwMVCggFFgIDAQAWIQQ2kMJAzlG0Zw0wrRw47nV9aRhG
|
||||||
|
IAUCYEt9dQUJFxeR4wAKCRA47nV9aRhGIBNDEACxD6vJ+enZwe3IgkJh5JtLsC9b
|
||||||
|
MWCQRlPW1EVMsg96Cb5Rtron1eN1pp1TlzENJu1/C7C/VEsr9WwOPg26Men7fNf/
|
||||||
|
O21QM9IBWd/uB0Pu333WqKh92ESS5x9ST9DrG39nVGSPkQQBMuia72VrA+crPnwT
|
||||||
|
/h/u1IN6/sff5VDIU24rUiqW2Npy733dANruj7Ny0scRXVPltnVdhqwPHt6qNjC1
|
||||||
|
t+/cCnwHgW1BR1RYXBPpB42z/m29dL9rPrG0YPGWs2Bc+EATUICfEE6eIvwfciue
|
||||||
|
IJTjKT9Y9DrogJC2AYFhjC7N04OKdCB2hFs4BjexJwr4X0GJO7LhFl03c951AsIE
|
||||||
|
GHwrucRPB5bo2vmvQ8IvZn7CmtdUJzXv9JlyU6p+MIK1pz7TK6GgSOSffQIXZn6e
|
||||||
|
nUPtm9mEwuncOfmW8/ODYPs1gCWYgyiFJx8h7eEu+M4MxHSFBs7MwXf/Ae2fSp+M
|
||||||
|
P/p198qB8fC5oVBnF95qb0Qi0uc1D+Gb+gpBF+ymMb+s/VBOR3QWiym7AzBrJ62g
|
||||||
|
UnbC9jMLGnSRI+7p7raUfMTgXr5/oQoBw7ExJVltSSRrim2YH/t4CV47mO6dR9J3
|
||||||
|
1RtsTFIRNhz+07XPsETcuCV/dgqeC8fOFLt9MY17Sufhb1DcGy4urZBOIhXcpTV7
|
||||||
|
vHVj5IYH5nYOT49NRYkCOAQTAQIAIgUCTMQ5kgIbAwYLCQgHAwIGFQgCCQoLBBYC
|
||||||
|
AwECHgECF4AACgkQOO51fWkYRiAg4A/7BXKwoRaXrMbMPOW7vuVF7c2IKB2Yqzn1
|
||||||
|
vLBCwuEHkqY237lDcXY4/5LR+1gcZ3Duw1n/BRSm0FBdvyX/JTWiWNSDUkKAO/0l
|
||||||
|
T2Tg44YLrDT3bzwu8dbU9xQt6kH+SCOHvv5Oe4k79l5mro6fF3H1M0bN63x/YoFY
|
||||||
|
ojy09D7/JptY82oR4f/VdKnfZLJcCViCb0wp8SD2NkDAudKg+K+7PD8HlTWklQQg
|
||||||
|
TZdRXxVZKIJeU42aJDqnRbAhJd64YHyClhqut9F5LUmiP5qfLfNhkKDhNOwk2Blr
|
||||||
|
BGBJkSd7wPyzcX4Mun/L6YspHjbeVMt9TD7HQlo+OOd2OjAHCx6pqwkXnzeLPEaE
|
||||||
|
cPdQ1SHgrBViAxX3DNPubLP0Knw8XwFu96EuhHZgexE1W7bB4LFsJyXAc5k1PqPD
|
||||||
|
CLsAauxmvI2OfI7opG/8wyxDvNgoPjG8fZNAgY0REqPC0JnTXChH31IxUmhNotH8
|
||||||
|
tD3DDTZOHw05n5MwwUrEE9xiETVDfFQcMLfxZ9KLz+BC2g1t5LYublRgnCMNJzFg
|
||||||
|
sNUMM02CphABzl/LCLnumr0eyQQ/weV4twEhLwSDmqLYHL0EdYW0Y3CnnU9vmYxQ
|
||||||
|
cXKbstS71sEJJYBBmSBbf9GxkOY8BRNtwVwY0kPgxv1WqdVBiAFvfB+pyAsrax9B
|
||||||
|
3UeB7ZSwRD6JAhwEEAEKAAYFAlS25GwACgkQlbYYGy0z6ew92Q//ZA9/6piQtoW4
|
||||||
|
PwP/1DtWGyKU8hwR+9FG669iPk/dAG+yoEJtFMOUpg/FUFmCX8Bc4oEHsCVyLxKt
|
||||||
|
DcCVUIRcYNSFi5hTZaBEbwsOlDT37gtlfIIu34hhHRccKaLnN/N9gNMNw8wGh9xg
|
||||||
|
Q/KtxZwcbk/bZIlDkKTJkFBRAekdEGAFDWb/AZOy+LQxS8ZAh1eWkfV0i8opmK9k
|
||||||
|
gPXtLE0WSsqtYyGs58z+BFE9NH3tEUwK6jSvtuLwQl4UrICNbKthcpb8WwH6UXzb
|
||||||
|
q3QNSYVOpf/cqRdBJA6bvb/ku/xyKVL08lGmxD9v1b137R7mafDAFPTsvH2Mt/0V
|
||||||
|
YuhtWav3r1Bl9QksDxt2DTS8wiWDUBetGqOVdcw7vBrXPEWDNBmxeJXsiJ7zJlR+
|
||||||
|
9wrJOm6RV2+l1IPxu96EaPS+kTNBijKrhxb67bww8BTEWTd0wcdJmgWRkM8SIstp
|
||||||
|
IKqd0L2TFYph2/NtrBhRg+DIEPJPpSTGsUMcCEXCZPQ+cIdlQKsWpk0tZ62DlvEl
|
||||||
|
r7E+wgUSQolRfx5KrpZifiS2zQlhzdXv28CJhsVbLyw5fUAWUKIH/dCo5NKsNLk2
|
||||||
|
Lc5DH9VWnFgxAAtW290FqeK/4ulMq7Vs1dQSwyHM2Ni3QqqeaiOrh8gbSY5CMLFN
|
||||||
|
Y3HYRwuTYPa3AobsozCzBj0Zdf/6AFe5Ag0ETMQ5kgEQAL/FwKdjxgPxtSpgq1SM
|
||||||
|
zgZtTTyLqhgGD3NZfadHWHYRIL38NDV3JeTA79Y2zj2dj7KQPDT+0aqeizTV2E3j
|
||||||
|
P3iCQ53VOT4consBaQAgKexpptnS+T1DobtICFJ0GGzf0HRj6KO2zSOuOitWPWlU
|
||||||
|
wbvX7M0LLI2+hqlx0jTPqbJFZ/Za6KTtbS6xdCPVUpUqYZQpokEZcwQmUp8Q+lGo
|
||||||
|
JD2sNYCZyap63X/aAOgCGr2RXYddOH5e8vGzGW+mwtCv+WQ9Ay35mGqI5MqkbZd1
|
||||||
|
Qbuv2b1647E/QEEucfRHVbJVKGGPpFMUJtcItyyIt5jo+r9CCL4Cs47dF/9/RNwu
|
||||||
|
NvpvHXUyqMBQdWNZRMx4k/NGD/WviPi9m6mIMui6rOQsSOaqYdcUX4Nq2Orr3Oaz
|
||||||
|
2JPQdUfeI23iot1vK8hxvUCQTV3HfJghizN6spVl0yQOKBiE8miJRgrjHilH3hTb
|
||||||
|
xoo42xDkNAq+CQo3QAm1ibDxKCDq0RcWPjcCRAN/Q5MmpcodpdKkzV0yGIS4g7s5
|
||||||
|
frVrgV/kox2r4/Yxsr8K909+4H82AjTKGX/BmsQFCTAqBk6p7I0zxjIqJ/w33TZB
|
||||||
|
Q0Pn4r3WIlUPafzY6a9/LAvN1fHRxf9SpCByJsszD03Qu5f5TB8gthsdnVmTo7jj
|
||||||
|
iordEKMtw2aEMLzdWWTQ/TNVABEBAAGJAjwEGAEKACYCGwwWIQQ2kMJAzlG0Zw0w
|
||||||
|
rRw47nV9aRhGIAUCYEt9YAUJFxeRzgAKCRA47nV9aRhGIMLtD/9HuKM4pngImcuz
|
||||||
|
YwzQmdv4j26YYyh4jVsKEmVWTiRcehEgUIlrWkCu3qzd5NK+RetS7kJ8MPnzEUfj
|
||||||
|
YbpdC6yrF6n1mSrZZ4VJMkV2ev37bIgXM+Wp1mCAGbjNxQnjn9RabT/gjIqmGuRn
|
||||||
|
AP7RsSeOSuO/gO9h2Pteciz23ussTilB+8cTooQEQQZe6Kv/zukvL+ccSehLHsZ7
|
||||||
|
qVfRUAmtt8nFkXXE+s8jfLfhqstaI2/RJu5witaPcXM8Mnz2E95aASAbZy0eQot9
|
||||||
|
0Pvf07n9yuC3tueTvzvlXx3h5U3yT44tIOmzANIQjay1TGdm+RBJ2ZYyhyLawlZ2
|
||||||
|
NVUXXSp4QZZXPA0UWbF+pb7Q9cdKDNFVuvGBljuea0Yd0T2o+ibDq43HziX9ll+l
|
||||||
|
SXk9mqvW1UcDOaxWrSsm1Gc1O9g3wqH5xHAhtY8GPh/7VgAawskPkmnlkMW6pYPy
|
||||||
|
zibbeISJL1gd1jIT63y6aoVrtNoo+wYJm280ROflh4+5QOo6QJ+jm70fkXSG/qJ5
|
||||||
|
a8/qCPTHkJc/rpkL6/TDQAJURi9RhDAC0gb40HtusbN1LZEA+i0cWTmYXap+DB4Y
|
||||||
|
R4pApilpaG87M+VUokR4xpnx7vTb2MPa7Mdenvi9FEGnKXadmT8038vlfzz5GGUT
|
||||||
|
MlVin9BQPTpdA+PpRiJvKJgVDeAFOg==
|
||||||
|
=asTC
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
@@ -5,6 +5,28 @@ operating_system() {
|
|||||||
sort | cut -d '=' -f 2- | sed 's/"//g' | paste -s -d '-'
|
sort | cut -d '=' -f 2- | sed 's/"//g' | paste -s -d '-'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_operating_system() {
|
||||||
|
if [ "$(operating_system)" != "$1" ]; then
|
||||||
|
echo "Not the right operating system!"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "The right operating system."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
architecture() {
|
||||||
|
uname -m
|
||||||
|
}
|
||||||
|
|
||||||
|
check_architecture() {
|
||||||
|
if [ "$(architecture)" != "$1" ]; then
|
||||||
|
echo "Not the right architecture!"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "The right architecture."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
check_all_yum() {
|
check_all_yum() {
|
||||||
local missing=""
|
local missing=""
|
||||||
for pkg in $1; do
|
for pkg in $1; do
|
||||||
@@ -43,3 +65,8 @@ check_all_dnf() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
install_all_apt() {
|
||||||
|
for pkg in $1; do
|
||||||
|
apt install -y "$pkg"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
1547
include/mgp.py
1547
include/mgp.py
File diff suppressed because it is too large
Load Diff
93
init
93
init
@@ -10,6 +10,8 @@ function print_help () {
|
|||||||
echo -e "Check for missing packages and setup the project.\n"
|
echo -e "Check for missing packages and setup the project.\n"
|
||||||
echo "Optional arguments:"
|
echo "Optional arguments:"
|
||||||
echo -e " -h\tdisplay this help and exit"
|
echo -e " -h\tdisplay this help and exit"
|
||||||
|
echo -e " --without-libs-setup\tskip the step for setting up libs"
|
||||||
|
echo -e " --wsl-quicklisp-proxy \"host:port\"\tquicklist HTTP proxy (this flag + HTTP proxy are required on WSL)"
|
||||||
}
|
}
|
||||||
|
|
||||||
function setup_virtualenv () {
|
function setup_virtualenv () {
|
||||||
@@ -22,7 +24,7 @@ function setup_virtualenv () {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# create new virtualenv
|
# create new virtualenv
|
||||||
virtualenv -p python3 ve3 || exit 1
|
python3 -m virtualenv -p python3 ve3 || exit 1
|
||||||
source ve3/bin/activate
|
source ve3/bin/activate
|
||||||
pip --timeout 1000 install -r requirements.txt || exit 1
|
pip --timeout 1000 install -r requirements.txt || exit 1
|
||||||
deactivate
|
deactivate
|
||||||
@@ -30,26 +32,47 @@ function setup_virtualenv () {
|
|||||||
popd > /dev/null
|
popd > /dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ $# -gt 1 ]]; then
|
wsl_quicklisp_proxy=""
|
||||||
|
setup_libs=true
|
||||||
|
if [[ $# -eq 1 && "$1" == "-h" ]]; then
|
||||||
print_help
|
print_help
|
||||||
exit 1
|
exit 0
|
||||||
elif [[ $# -eq 1 ]]; then
|
else
|
||||||
case "$1" in
|
while(($#)); do
|
||||||
-h)
|
case "$1" in
|
||||||
print_help
|
--wsl-quicklisp-proxy)
|
||||||
exit 0
|
shift
|
||||||
;;
|
if [[ $# -eq 0 ]]; then
|
||||||
*)
|
echo "Missing proxy URL"
|
||||||
# unknown option
|
print_help
|
||||||
print_help
|
exit 1
|
||||||
exit 1
|
fi
|
||||||
;;
|
wsl_quicklisp_proxy=":proxy \"http://$1/\""
|
||||||
esac
|
shift
|
||||||
|
;;
|
||||||
|
--without-libs-setup)
|
||||||
|
shift
|
||||||
|
setup_libs=false
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# unknown option
|
||||||
|
echo "Invalid argument provided: $1"
|
||||||
|
print_help
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
DISTRO=$(operating_system)
|
DISTRO=$(operating_system)
|
||||||
echo "ALL BUILD PACKAGES: $($DIR/environment/os/$DISTRO.sh list MEMGRAPH_BUILD_DEPS)"
|
ARCHITECTURE=$(architecture)
|
||||||
$DIR/environment/os/$DISTRO.sh check MEMGRAPH_BUILD_DEPS
|
if [ "${ARCHITECTURE}" = "arm64" ] || [ "${ARCHITECTURE}" = "aarch64" ]; then
|
||||||
|
OS_SCRIPT=$DIR/environment/os/$DISTRO-arm.sh
|
||||||
|
else
|
||||||
|
OS_SCRIPT=$DIR/environment/os/$DISTRO.sh
|
||||||
|
fi
|
||||||
|
echo "ALL BUILD PACKAGES: $($OS_SCRIPT list MEMGRAPH_BUILD_DEPS)"
|
||||||
|
$OS_SCRIPT check MEMGRAPH_BUILD_DEPS
|
||||||
echo "All packages are in-place..."
|
echo "All packages are in-place..."
|
||||||
|
|
||||||
# create a default build directory
|
# create a default build directory
|
||||||
@@ -66,7 +89,7 @@ if [[ ! -f "${quicklisp_install_dir}/setup.lisp" ]]; then
|
|||||||
echo \
|
echo \
|
||||||
"
|
"
|
||||||
(load \"${DIR}/quicklisp.lisp\")
|
(load \"${DIR}/quicklisp.lisp\")
|
||||||
(quicklisp-quickstart:install :path \"${quicklisp_install_dir}\")
|
(quicklisp-quickstart:install $wsl_quicklisp_proxy :path \"${quicklisp_install_dir}\")
|
||||||
" | sbcl --script || exit 1
|
" | sbcl --script || exit 1
|
||||||
rm -rf quicklisp.lisp || exit 1
|
rm -rf quicklisp.lisp || exit 1
|
||||||
fi
|
fi
|
||||||
@@ -80,11 +103,13 @@ echo \
|
|||||||
(ql:quickload '(:lcp :lcp/test) :silent t)
|
(ql:quickload '(:lcp :lcp/test) :silent t)
|
||||||
" | sbcl --script
|
" | sbcl --script
|
||||||
|
|
||||||
# setup libs (download)
|
if [[ "$setup_libs" == "true" ]]; then
|
||||||
cd libs
|
# Setup libs (download).
|
||||||
./cleanup.sh
|
cd libs
|
||||||
./setup.sh
|
./cleanup.sh
|
||||||
cd ..
|
./setup.sh
|
||||||
|
cd ..
|
||||||
|
fi
|
||||||
|
|
||||||
# setup gql_behave dependencies
|
# setup gql_behave dependencies
|
||||||
setup_virtualenv tests/gql_behave
|
setup_virtualenv tests/gql_behave
|
||||||
@@ -95,6 +120,14 @@ setup_virtualenv tests/stress
|
|||||||
# setup integration/ldap dependencies
|
# setup integration/ldap dependencies
|
||||||
setup_virtualenv tests/integration/ldap
|
setup_virtualenv tests/integration/ldap
|
||||||
|
|
||||||
|
# Setup tests dependencies.
|
||||||
|
# cd tests
|
||||||
|
# ./setup.sh
|
||||||
|
# cd ..
|
||||||
|
# TODO(gitbuda): Remove setup_virtualenv, replace it with tests/ve3. Take care
|
||||||
|
# of the build order because tests/setup.py builds pymgclient which depends on
|
||||||
|
# mgclient which is build after this script by calling make.
|
||||||
|
|
||||||
echo "Done installing dependencies for Memgraph"
|
echo "Done installing dependencies for Memgraph"
|
||||||
|
|
||||||
echo "Linking git hooks"
|
echo "Linking git hooks"
|
||||||
@@ -102,3 +135,17 @@ for hook in $(find $DIR/.githooks -type f -printf "%f\n"); do
|
|||||||
ln -s -f "$DIR/.githooks/$hook" "$DIR/.git/hooks/$hook"
|
ln -s -f "$DIR/.githooks/$hook" "$DIR/.git/hooks/$hook"
|
||||||
echo "Added $hook hook"
|
echo "Added $hook hook"
|
||||||
done;
|
done;
|
||||||
|
|
||||||
|
# Install precommit hook
|
||||||
|
python3 -m pip install pre-commit
|
||||||
|
python3 -m pre_commit install
|
||||||
|
|
||||||
|
# Install py format tools
|
||||||
|
echo "Install black formatter"
|
||||||
|
python3 -m pip install black==22.10.*
|
||||||
|
echo "Install isort"
|
||||||
|
python3 -m pip install isort==5.10.*
|
||||||
|
|
||||||
|
|
||||||
|
# Link `include/mgp.py` with `release/mgp/mgp.py`
|
||||||
|
ln -v -f include/mgp.py release/mgp/mgp.py
|
||||||
|
|||||||
2
libs/.gitignore
vendored
2
libs/.gitignore
vendored
@@ -4,3 +4,5 @@
|
|||||||
!cleanup.sh
|
!cleanup.sh
|
||||||
!CMakeLists.txt
|
!CMakeLists.txt
|
||||||
!__main.cpp
|
!__main.cpp
|
||||||
|
!pulsar.patch
|
||||||
|
!antlr4.10.1.patch
|
||||||
|
|||||||
@@ -1,11 +1,24 @@
|
|||||||
include(ExternalProject)
|
include(ExternalProject)
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
include(ProcessorCount)
|
include(ProcessorCount)
|
||||||
ProcessorCount(NPROC)
|
ProcessorCount(NPROC)
|
||||||
if (NPROC EQUAL 0)
|
if (NPROC EQUAL 0)
|
||||||
set(NPROC 1)
|
set(NPROC 1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
find_package(Boost 1.78 REQUIRED)
|
||||||
|
find_package(BZip2 1.0.6 REQUIRED)
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
set(GFLAGS_NOTHREADS OFF)
|
||||||
|
find_package(gflags REQUIRED)
|
||||||
|
find_package(fmt 8.0.1)
|
||||||
|
find_package(Jemalloc REQUIRED)
|
||||||
|
find_package(ZLIB 1.2.11 REQUIRED)
|
||||||
|
|
||||||
|
set(LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
# convenience functions
|
# convenience functions
|
||||||
function(import_header_library name include_dir)
|
function(import_header_library name include_dir)
|
||||||
add_library(${name} INTERFACE IMPORTED GLOBAL)
|
add_library(${name} INTERFACE IMPORTED GLOBAL)
|
||||||
@@ -44,7 +57,7 @@ endfunction(import_library)
|
|||||||
# INSTALL_COMMAND arguments.
|
# INSTALL_COMMAND arguments.
|
||||||
function(add_external_project name)
|
function(add_external_project name)
|
||||||
set(options NO_C_COMPILER)
|
set(options NO_C_COMPILER)
|
||||||
set(one_value_kwargs SOURCE_DIR)
|
set(one_value_kwargs SOURCE_DIR BUILD_IN_SOURCE)
|
||||||
set(multi_value_kwargs CMAKE_ARGS DEPENDS INSTALL_COMMAND BUILD_COMMAND
|
set(multi_value_kwargs CMAKE_ARGS DEPENDS INSTALL_COMMAND BUILD_COMMAND
|
||||||
CONFIGURE_COMMAND)
|
CONFIGURE_COMMAND)
|
||||||
cmake_parse_arguments(KW "${options}" "${one_value_kwargs}" "${multi_value_kwargs}" ${ARGN})
|
cmake_parse_arguments(KW "${options}" "${one_value_kwargs}" "${multi_value_kwargs}" ${ARGN})
|
||||||
@@ -52,11 +65,16 @@ function(add_external_project name)
|
|||||||
if (KW_SOURCE_DIR)
|
if (KW_SOURCE_DIR)
|
||||||
set(source_dir ${KW_SOURCE_DIR})
|
set(source_dir ${KW_SOURCE_DIR})
|
||||||
endif()
|
endif()
|
||||||
|
set(build_in_source 0)
|
||||||
|
if (KW_BUILD_IN_SOURCE)
|
||||||
|
set(build_in_source ${KW_BUILD_IN_SOURCE})
|
||||||
|
endif()
|
||||||
if (NOT KW_NO_C_COMPILER)
|
if (NOT KW_NO_C_COMPILER)
|
||||||
set(KW_CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} ${KW_CMAKE_ARGS})
|
set(KW_CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} ${KW_CMAKE_ARGS})
|
||||||
endif()
|
endif()
|
||||||
ExternalProject_Add(${name}-proj DEPENDS ${KW_DEPENDS}
|
ExternalProject_Add(${name}-proj DEPENDS ${KW_DEPENDS}
|
||||||
PREFIX ${source_dir} SOURCE_DIR ${source_dir}
|
PREFIX ${source_dir} SOURCE_DIR ${source_dir}
|
||||||
|
BUILD_IN_SOURCE ${build_in_source}
|
||||||
CONFIGURE_COMMAND ${KW_CONFIGURE_COMMAND}
|
CONFIGURE_COMMAND ${KW_CONFIGURE_COMMAND}
|
||||||
CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release
|
CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release
|
||||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||||
@@ -87,25 +105,19 @@ import_external_library(antlr4 STATIC
|
|||||||
CMAKE_ARGS # http://stackoverflow.com/questions/37096062/get-a-basic-c-program-to-compile-using-clang-on-ubuntu-16/38385967#38385967
|
CMAKE_ARGS # http://stackoverflow.com/questions/37096062/get-a-basic-c-program-to-compile-using-clang-on-ubuntu-16/38385967#38385967
|
||||||
-DWITH_LIBCXX=OFF # because of debian bug
|
-DWITH_LIBCXX=OFF # because of debian bug
|
||||||
-DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=true
|
-DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=true
|
||||||
|
-DCMAKE_CXX_STANDARD=20
|
||||||
|
-DANTLR_BUILD_CPP_TESTS=OFF
|
||||||
BUILD_COMMAND $(MAKE) antlr4_static
|
BUILD_COMMAND $(MAKE) antlr4_static
|
||||||
# Make a License.txt out of thin air, so that antlr4.6 knows how to build.
|
INSTALL_COMMAND $(MAKE) install)
|
||||||
# When we upgrade antlr, this will no longer be needed.
|
|
||||||
INSTALL_COMMAND touch ${CMAKE_CURRENT_SOURCE_DIR}/antlr4/runtime/Cpp/License.txt
|
|
||||||
COMMAND $(MAKE) install)
|
|
||||||
|
|
||||||
# Setup google benchmark.
|
# Setup google benchmark.
|
||||||
import_external_library(benchmark STATIC
|
import_external_library(benchmark STATIC
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/benchmark/lib/libbenchmark.a
|
${CMAKE_CURRENT_SOURCE_DIR}/benchmark/${CMAKE_INSTALL_LIBDIR}/libbenchmark.a
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/benchmark/include
|
${CMAKE_CURRENT_SOURCE_DIR}/benchmark/include
|
||||||
# Skip testing. The tests don't compile with Clang 8.
|
# Skip testing. The tests don't compile with Clang 8.
|
||||||
CMAKE_ARGS -DBENCHMARK_ENABLE_TESTING=OFF)
|
CMAKE_ARGS -DBENCHMARK_ENABLE_TESTING=OFF)
|
||||||
|
|
||||||
# setup fmt format
|
include(FetchContent)
|
||||||
import_external_library(fmt STATIC
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/fmt/lib/libfmt.a
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/fmt/include
|
|
||||||
# Skip testing.
|
|
||||||
CMAKE_ARGS -DFMT_TEST=OFF)
|
|
||||||
|
|
||||||
# setup rapidcheck (it cannot be external, since it doesn't have install
|
# setup rapidcheck (it cannot be external, since it doesn't have install
|
||||||
# target)
|
# target)
|
||||||
@@ -132,73 +144,19 @@ import_library(gtest_main STATIC ${GTEST_MAIN_LIBRARY} ${GTEST_INCLUDE_DIR} gtes
|
|||||||
import_library(gmock STATIC ${GMOCK_LIBRARY} ${GTEST_INCLUDE_DIR} gtest-proj)
|
import_library(gmock STATIC ${GMOCK_LIBRARY} ${GTEST_INCLUDE_DIR} gtest-proj)
|
||||||
import_library(gmock_main STATIC ${GMOCK_MAIN_LIBRARY} ${GTEST_INCLUDE_DIR} gtest-proj)
|
import_library(gmock_main STATIC ${GMOCK_MAIN_LIBRARY} ${GTEST_INCLUDE_DIR} gtest-proj)
|
||||||
|
|
||||||
# setup google flags
|
|
||||||
set(GFLAGS_NO_FILENAMES "0")
|
|
||||||
if ("${CMAKE_BUILD_TYPE}" MATCHES "^(R|r)(E|e)(L|l).+")
|
|
||||||
set(GFLAGS_NO_FILENAMES "1")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# setup google flags
|
|
||||||
import_external_library(gflags STATIC
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/gflags/lib/libgflags.a
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/gflags/include
|
|
||||||
# Not needed, since gflags is C++ only.
|
|
||||||
NO_C_COMPILER
|
|
||||||
# Don't register installation in ~/.cmake
|
|
||||||
CMAKE_ARGS -DREGISTER_INSTALL_PREFIX=OFF
|
|
||||||
-DBUILD_gflags_nothreads_LIB=OFF
|
|
||||||
-DGFLAGS_NO_FILENAMES=${GFLAGS_NO_FILENAMES})
|
|
||||||
|
|
||||||
# Setup google logging after gflags (so that glog can use it).
|
|
||||||
set(GLOG_DISABLE_OPTIONS "0")
|
|
||||||
if ("${CMAKE_BUILD_TYPE}" MATCHES "^(R|r)(E|e)(L|l).+")
|
|
||||||
set(GLOG_DISABLE_OPTIONS "1")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Setup google logging after gflags (so that glog can use it).
|
|
||||||
import_external_library(glog STATIC
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/glog/lib/libglog.a
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/glog/include
|
|
||||||
DEPENDS gflags-proj
|
|
||||||
CMAKE_ARGS -Dgflags_DIR=${CMAKE_CURRENT_SOURCE_DIR}/gflags/lib/cmake/gflags
|
|
||||||
-DBUILD_TESTING=OFF
|
|
||||||
-DGLOG_NO_FILENAMES=${GLOG_DISABLE_OPTIONS}
|
|
||||||
-DGLOG_NO_STACKTRACE=${GLOG_DISABLE_OPTIONS}
|
|
||||||
-DGLOG_NO_BUFFER_SETTINGS=${GLOG_DISABLE_OPTIONS}
|
|
||||||
-DGLOG_NO_TIME_PID_FILENAME=${GLOG_DISABLE_OPTIONS})
|
|
||||||
|
|
||||||
# Setup cppitertools
|
# Setup cppitertools
|
||||||
import_header_library(cppitertools ${CMAKE_CURRENT_SOURCE_DIR})
|
import_header_library(cppitertools ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
# Setup json
|
# Setup json
|
||||||
import_header_library(json ${CMAKE_CURRENT_SOURCE_DIR})
|
import_header_library(json ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
# Setup bzip2
|
|
||||||
import_external_library(bzip2 STATIC
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/bzip2/libbz2.a
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/bzip2
|
|
||||||
# bzip2's Makefile has -g CFLAG which is redundant
|
|
||||||
CONFIGURE_COMMAND sed -i "s/-Wall -Winline -O2 -g/-Wall -Winline -O2/g" ${CMAKE_CURRENT_SOURCE_DIR}/bzip2/Makefile
|
|
||||||
BUILD_COMMAND make -C ${CMAKE_CURRENT_SOURCE_DIR}/bzip2
|
|
||||||
CC=${CMAKE_C_COMPILER}
|
|
||||||
CXX=${CMAKE_CXX_COMPILER}
|
|
||||||
INSTALL_COMMAND true)
|
|
||||||
|
|
||||||
# Setup zlib
|
|
||||||
import_external_library(zlib STATIC
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/zlib/lib/libz.a
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/zlib
|
|
||||||
CMAKE_ARGS -DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=true
|
|
||||||
BUILD_COMMAND $(MAKE) zlibstatic)
|
|
||||||
|
|
||||||
# Setup RocksDB
|
# Setup RocksDB
|
||||||
import_external_library(rocksdb STATIC
|
import_external_library(rocksdb STATIC
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/rocksdb/lib/librocksdb.a
|
${CMAKE_CURRENT_SOURCE_DIR}/rocksdb/lib/librocksdb.a
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/rocksdb/include
|
${CMAKE_CURRENT_SOURCE_DIR}/rocksdb/include
|
||||||
DEPENDS gflags-proj
|
CMAKE_ARGS -DUSE_RTTI=ON
|
||||||
CMAKE_ARGS -Dgflags_DIR=${CMAKE_CURRENT_SOURCE_DIR}/gflags/lib/cmake/gflags
|
|
||||||
-DUSE_RTTI=ON
|
|
||||||
-DWITH_TESTS=OFF
|
-DWITH_TESTS=OFF
|
||||||
|
-DGFLAGS_NOTHREADS=OFF
|
||||||
-DCMAKE_INSTALL_LIBDIR=lib
|
-DCMAKE_INSTALL_LIBDIR=lib
|
||||||
-DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=true
|
-DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=true
|
||||||
BUILD_COMMAND $(MAKE) rocksdb)
|
BUILD_COMMAND $(MAKE) rocksdb)
|
||||||
@@ -219,6 +177,82 @@ import_external_library(mgclient STATIC
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/mgclient/include
|
${CMAKE_CURRENT_SOURCE_DIR}/mgclient/include
|
||||||
CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||||
-DBUILD_TESTING=OFF)
|
-DBUILD_TESTING=OFF
|
||||||
|
-DBUILD_CPP_BINDINGS=ON)
|
||||||
find_package(OpenSSL REQUIRED)
|
find_package(OpenSSL REQUIRED)
|
||||||
target_link_libraries(mgclient INTERFACE ${OPENSSL_LIBRARIES})
|
target_link_libraries(mgclient INTERFACE ${OPENSSL_LIBRARIES})
|
||||||
|
|
||||||
|
add_external_project(mgconsole
|
||||||
|
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/mgconsole
|
||||||
|
CMAKE_ARGS
|
||||||
|
-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}
|
||||||
|
BUILD_COMMAND $(MAKE) mgconsole)
|
||||||
|
|
||||||
|
add_custom_target(mgconsole DEPENDS mgconsole-proj)
|
||||||
|
|
||||||
|
# Setup spdlog
|
||||||
|
set(SPDLOG_FMT_EXTERNAL ON)
|
||||||
|
FetchContent_Declare(spdlog
|
||||||
|
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/spdlog)
|
||||||
|
|
||||||
|
FetchContent_MakeAvailable(spdlog)
|
||||||
|
|
||||||
|
# Setup librdkafka.
|
||||||
|
import_external_library(librdkafka STATIC
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/librdkafka/lib/librdkafka.a
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/librdkafka/include
|
||||||
|
CMAKE_ARGS -DRDKAFKA_BUILD_STATIC=ON
|
||||||
|
-DRDKAFKA_BUILD_EXAMPLES=OFF
|
||||||
|
-DRDKAFKA_BUILD_TESTS=OFF
|
||||||
|
-DWITH_ZSTD=OFF
|
||||||
|
-DENABLE_LZ4_EXT=OFF
|
||||||
|
-DCMAKE_INSTALL_LIBDIR=lib
|
||||||
|
-DWITH_SSL=ON
|
||||||
|
# If we want SASL, we need to install it on build machines
|
||||||
|
-DWITH_SASL=OFF)
|
||||||
|
target_link_libraries(librdkafka INTERFACE ${OPENSSL_LIBRARIES} ZLIB::ZLIB)
|
||||||
|
|
||||||
|
import_library(librdkafka++ STATIC
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/librdkafka/lib/librdkafka++.a
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/librdkafka/include
|
||||||
|
)
|
||||||
|
target_link_libraries(librdkafka++ INTERFACE librdkafka)
|
||||||
|
|
||||||
|
set(PROTOBUF_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/protobuf/lib)
|
||||||
|
import_external_library(protobuf STATIC
|
||||||
|
${PROTOBUF_ROOT}/lib/libprotobuf.a
|
||||||
|
${PROTOBUF_ROOT}/include
|
||||||
|
BUILD_IN_SOURCE 1
|
||||||
|
CONFIGURE_COMMAND true)
|
||||||
|
|
||||||
|
import_external_library(pulsar STATIC
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/pulsar/pulsar-client-cpp/lib/libpulsarwithdeps.a
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/pulsar/install/include
|
||||||
|
BUILD_IN_SOURCE 1
|
||||||
|
CONFIGURE_COMMAND cmake pulsar-client-cpp
|
||||||
|
-DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_SOURCE_DIR}/pulsar/install
|
||||||
|
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||||
|
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||||
|
-DBUILD_DYNAMIC_LIB=OFF
|
||||||
|
-DBUILD_STATIC_LIB=ON
|
||||||
|
-DBUILD_TESTS=OFF
|
||||||
|
-DLINK_STATIC=ON
|
||||||
|
-DPROTOC_PATH=${PROTOBUF_ROOT}/bin/protoc
|
||||||
|
-DBOOST_ROOT=${BOOST_ROOT}
|
||||||
|
-DCMAKE_PREFIX_PATH=${PROTOBUF_ROOT}
|
||||||
|
-DProtobuf_INCLUDE_DIRS=${PROTOBUF_ROOT}/include
|
||||||
|
-DBUILD_PYTHON_WRAPPER=OFF
|
||||||
|
-DBUILD_PERF_TOOLS=OFF
|
||||||
|
-DUSE_LOG4CXX=OFF
|
||||||
|
BUILD_COMMAND $(MAKE) pulsarStaticWithDeps)
|
||||||
|
add_dependencies(pulsar-proj protobuf)
|
||||||
|
|
||||||
|
if (${MG_ARCH} STREQUAL "ARM64")
|
||||||
|
set(MG_LIBRDTSC_CMAKE_ARGS -DLIBRDTSC_ARCH_x86=OFF -DLIBRDTSC_ARCH_ARM64=ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
import_external_library(librdtsc STATIC
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/librdtsc/lib/librdtsc.a
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/librdtsc/include
|
||||||
|
CMAKE_ARGS ${MG_LIBRDTSC_CMAKE_ARGS}
|
||||||
|
BUILD_COMMAND $(MAKE) rdtsc)
|
||||||
|
|||||||
13
libs/antlr4.10.1.patch
Normal file
13
libs/antlr4.10.1.patch
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
diff --git a/runtime/Cpp/runtime/CMakeLists.txt b/runtime/Cpp/runtime/CMakeLists.txt
|
||||||
|
index baf46cac9..2e7756de8 100644
|
||||||
|
--- a/runtime/Cpp/runtime/CMakeLists.txt
|
||||||
|
+++ b/runtime/Cpp/runtime/CMakeLists.txt
|
||||||
|
@@ -134,7 +134,7 @@ set_target_properties(antlr4_static
|
||||||
|
ARCHIVE_OUTPUT_DIRECTORY ${LIB_OUTPUT_DIR}
|
||||||
|
COMPILE_FLAGS "${disabled_compile_warnings} ${extra_static_compile_flags}")
|
||||||
|
|
||||||
|
-install(TARGETS antlr4_shared
|
||||||
|
+install(TARGETS antlr4_shared OPTIONAL
|
||||||
|
EXPORT antlr4-targets
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
29
libs/librdtsc.patch
Normal file
29
libs/librdtsc.patch
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||||
|
index ee9b58c..31359a9 100644
|
||||||
|
--- a/CMakeLists.txt
|
||||||
|
+++ b/CMakeLists.txt
|
||||||
|
@@ -48,7 +48,7 @@ option(LIBRDTSC_USE_PMU "Enables PMU usage on ARM platforms" OFF)
|
||||||
|
# | Library Build and Install Properties |
|
||||||
|
# +--------------------------------------------------------+
|
||||||
|
|
||||||
|
-add_library(rdtsc SHARED
|
||||||
|
+add_library(rdtsc
|
||||||
|
src/cycles.c
|
||||||
|
src/common_timer.c
|
||||||
|
src/timer.c
|
||||||
|
@@ -72,15 +72,6 @@ target_include_directories(rdtsc
|
||||||
|
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
|
)
|
||||||
|
|
||||||
|
-# Install directory changes depending on build mode
|
||||||
|
-if (CMAKE_BUILD_TYPE MATCHES "^[Dd]ebug")
|
||||||
|
- # During debug, the library will be installed into a local directory
|
||||||
|
- set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_install CACHE PATH "" FORCE)
|
||||||
|
-else ()
|
||||||
|
- # This will install in /usr/lib and /usr/include
|
||||||
|
- set(CMAKE_INSTALL_PREFIX /usr CACHE PATH "" FORCE)
|
||||||
|
-endif ()
|
||||||
|
-
|
||||||
|
# Specifying what to export when installing (GNUInstallDirs required)
|
||||||
|
install(TARGETS rdtsc
|
||||||
|
EXPORT librstsc-config
|
||||||
1520
libs/pulsar.patch
Normal file
1520
libs/pulsar.patch
Normal file
File diff suppressed because it is too large
Load Diff
21
libs/rocksdb.patch
Normal file
21
libs/rocksdb.patch
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||||
|
index 6761929..6a369af 100644
|
||||||
|
--- a/CMakeLists.txt
|
||||||
|
+++ b/CMakeLists.txt
|
||||||
|
@@ -220,6 +220,7 @@ else()
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -momit-leaf-frame-pointer")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-copy -Wno-unused-but-set-variable")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(CheckCCompilerFlag)
|
||||||
|
@@ -997,7 +998,7 @@ if(NOT WIN32 OR ROCKSDB_INSTALL_ON_WINDOWS)
|
||||||
|
|
||||||
|
if(ROCKSDB_BUILD_SHARED)
|
||||||
|
install(
|
||||||
|
- TARGETS ${ROCKSDB_SHARED_LIB}
|
||||||
|
+ TARGETS ${ROCKSDB_SHARED_LIB} OPTIONAL
|
||||||
|
EXPORT RocksDBTargets
|
||||||
|
COMPONENT runtime
|
||||||
|
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||||
248
libs/setup.sh
248
libs/setup.sh
@@ -1,9 +1,11 @@
|
|||||||
#!/bin/bash -e
|
#!/bin/bash -e
|
||||||
|
|
||||||
# Download external dependencies.
|
# Download external dependencies.
|
||||||
|
# Don't forget to add/update the license in release/third-party-licenses of added/updated libs!
|
||||||
|
|
||||||
|
local_cache_host=${MGDEPS_CACHE_HOST_PORT:-mgdeps-cache:8000}
|
||||||
working_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
working_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
cd ${working_dir}
|
cd "${working_dir}"
|
||||||
|
|
||||||
# Clones a git repository and optionally cherry picks additional commits. The
|
# Clones a git repository and optionally cherry picks additional commits. The
|
||||||
# function will try to preserve any local changes in the repo.
|
# function will try to preserve any local changes in the repo.
|
||||||
@@ -12,30 +14,49 @@ clone () {
|
|||||||
local git_repo=$1
|
local git_repo=$1
|
||||||
local dir_name=$2
|
local dir_name=$2
|
||||||
local checkout_id=$3
|
local checkout_id=$3
|
||||||
shift 3
|
local shallow=$4
|
||||||
|
shift 4
|
||||||
# Clone if there's no repo.
|
# Clone if there's no repo.
|
||||||
if [[ ! -d "$dir_name" ]]; then
|
if [[ ! -d "$dir_name" ]]; then
|
||||||
git clone "$git_repo" "$dir_name"
|
echo "Cloning from $git_repo"
|
||||||
|
# If the clone fails, it doesn't make sense to continue with the function
|
||||||
|
# execution but the whole script should continue executing because we might
|
||||||
|
# clone the same repo from a different source.
|
||||||
|
|
||||||
|
if [ "$shallow" = true ]; then
|
||||||
|
git clone --depth 1 --branch "$checkout_id" "$git_repo" "$dir_name" || return 1
|
||||||
|
else
|
||||||
|
git clone "$git_repo" "$dir_name" || return 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
pushd "$dir_name"
|
pushd "$dir_name"
|
||||||
# Just fetch new commits from remote repository. Don't merge/pull them in, so
|
|
||||||
# that we don't clobber local modifications.
|
|
||||||
git fetch
|
|
||||||
# Check whether we have any local changes which need to be preserved.
|
# Check whether we have any local changes which need to be preserved.
|
||||||
local local_changes=true
|
local local_changes=true
|
||||||
if git diff --no-ext-diff --quiet && git diff --no-ext-diff --cached --quiet; then
|
if git diff --no-ext-diff --quiet && git diff --no-ext-diff --cached --quiet; then
|
||||||
local_changes=false
|
local_changes=false
|
||||||
fi
|
fi
|
||||||
# Stash regardless of local_changes, so that a user gets a message on stdout.
|
|
||||||
git stash
|
if [ "$shallow" = false ]; then
|
||||||
# Checkout the primary commit (there's no need to pull/merge).
|
# Stash regardless of local_changes, so that a user gets a message on stdout.
|
||||||
git checkout $checkout_id
|
git stash
|
||||||
# Apply any optional cherry pick fixes.
|
# Just fetch new commits from remote repository. Don't merge/pull them in, so
|
||||||
while [[ $# -ne 0 ]]; do
|
# that we don't clobber local modifications.
|
||||||
local cherry_pick_id=$1
|
git fetch
|
||||||
shift
|
# Checkout the primary commit (there's no need to pull/merge).
|
||||||
git cherry-pick -n $cherry_pick_id
|
# The checkout fail should exit this script immediately because the target
|
||||||
done
|
# commit is not there and that will most likely create build-time errors.
|
||||||
|
git checkout "$checkout_id" || exit 1
|
||||||
|
# Apply any optional cherry pick fixes.
|
||||||
|
while [[ $# -ne 0 ]]; do
|
||||||
|
local cherry_pick_id=$1
|
||||||
|
shift
|
||||||
|
# The cherry-pick fail should exit this script immediately because the
|
||||||
|
# target commit is not there and that will most likely create build-time
|
||||||
|
# errors.
|
||||||
|
git cherry-pick -n "$cherry_pick_id" || exit 1
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
# Reapply any local changes.
|
# Reapply any local changes.
|
||||||
if [[ $local_changes == true ]]; then
|
if [[ $local_changes == true ]]; then
|
||||||
git stash pop
|
git stash pop
|
||||||
@@ -43,80 +64,177 @@ clone () {
|
|||||||
popd
|
popd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file_get_try_double () {
|
||||||
|
primary_url="$1"
|
||||||
|
secondary_url="$2"
|
||||||
|
echo "Download primary from $primary_url secondary from $secondary_url"
|
||||||
|
if [ -z "$primary_url" ]; then echo "Primary should not be empty." && exit 1; fi
|
||||||
|
if [ -z "$secondary_url" ]; then echo "Secondary should not be empty." && exit 1; fi
|
||||||
|
filename="$(basename "$secondary_url")"
|
||||||
|
wget -nv "$primary_url" -O "$filename" || wget -nv "$secondary_url" -O "$filename" || exit 1
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
repo_clone_try_double () {
|
||||||
|
primary_url="$1"
|
||||||
|
secondary_url="$2"
|
||||||
|
folder_name="$3"
|
||||||
|
ref="$4"
|
||||||
|
shallow="${5:-false}"
|
||||||
|
echo "Cloning primary from $primary_url secondary from $secondary_url"
|
||||||
|
if [ -z "$primary_url" ]; then echo "Primary should not be empty." && exit 1; fi
|
||||||
|
if [ -z "$secondary_url" ]; then echo "Secondary should not be empty." && exit 1; fi
|
||||||
|
if [ -z "$folder_name" ]; then echo "Clone folder should not be empty." && exit 1; fi
|
||||||
|
if [ -z "$ref" ]; then echo "Git clone ref should not be empty." && exit 1; fi
|
||||||
|
clone "$primary_url" "$folder_name" "$ref" "$shallow" || clone "$secondary_url" "$folder_name" "$ref" "$shallow" || exit 1
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# List all dependencies.
|
||||||
|
|
||||||
|
# The reason for introducing primary and secondary urls are:
|
||||||
|
# * HTTPS is hard to cache
|
||||||
|
# * Remote development workflow is more flexible if people don't have to connect to VPN
|
||||||
|
# * Direct download from the "source of truth" is slower and unreliable because of the whole internet in-between
|
||||||
|
# * When a new dependency has to be added, both urls could be the same, later someone could optimize if required
|
||||||
|
|
||||||
|
# The goal of having primary urls is to have links to the "local" cache of
|
||||||
|
# dependencies where these dependencies could be downloaded as fast as
|
||||||
|
# possible. The actual cache server could be on your local machine, on a
|
||||||
|
# dedicated machine inside the build cluster or on the actual build machine.
|
||||||
|
# Download from primary_urls might fail because the cache is not installed.
|
||||||
|
declare -A primary_urls=(
|
||||||
|
["antlr4-code"]="http://$local_cache_host/git/antlr4.git"
|
||||||
|
["antlr4-generator"]="http://$local_cache_host/file/antlr-4.10.1-complete.jar"
|
||||||
|
["cppitertools"]="http://$local_cache_host/git/cppitertools.git"
|
||||||
|
["rapidcheck"]="http://$local_cache_host/git/rapidcheck.git"
|
||||||
|
["gbenchmark"]="http://$local_cache_host/git/benchmark.git"
|
||||||
|
["gtest"]="http://$local_cache_host/git/googletest.git"
|
||||||
|
["libbcrypt"]="http://$local_cache_host/git/libbcrypt.git"
|
||||||
|
["rocksdb"]="http://$local_cache_host/git/rocksdb.git"
|
||||||
|
["mgclient"]="http://$local_cache_host/git/mgclient.git"
|
||||||
|
["pymgclient"]="http://$local_cache_host/git/pymgclient.git"
|
||||||
|
["mgconsole"]="http://$local_cache_host/git/mgconsole.git"
|
||||||
|
["spdlog"]="http://$local_cache_host/git/spdlog"
|
||||||
|
["nlohmann"]="http://$local_cache_host/file/nlohmann/json/9d69186291aca4f0137b69c1dee313b391ff564c/single_include/nlohmann/json.hpp"
|
||||||
|
["neo4j"]="http://$local_cache_host/file/neo4j-community-3.2.3-unix.tar.gz"
|
||||||
|
["librdkafka"]="http://$local_cache_host/git/librdkafka.git"
|
||||||
|
["protobuf"]="http://$local_cache_host/git/protobuf.git"
|
||||||
|
["pulsar"]="http://$local_cache_host/git/pulsar.git"
|
||||||
|
["librdtsc"]="http://$local_cache_host/git/librdtsc.git"
|
||||||
|
)
|
||||||
|
|
||||||
|
# The goal of secondary urls is to have links to the "source of truth" of
|
||||||
|
# dependencies, e.g., Github or S3. Download from secondary urls, if happens
|
||||||
|
# at all, should never fail. In other words, if it fails, the whole build
|
||||||
|
# should fail.
|
||||||
|
declare -A secondary_urls=(
|
||||||
|
["antlr4-code"]="https://github.com/antlr/antlr4.git"
|
||||||
|
["antlr4-generator"]="https://www.antlr.org/download/antlr-4.10.1-complete.jar"
|
||||||
|
["cppitertools"]="https://github.com/ryanhaining/cppitertools.git"
|
||||||
|
["rapidcheck"]="https://github.com/emil-e/rapidcheck.git"
|
||||||
|
["gbenchmark"]="https://github.com/google/benchmark.git"
|
||||||
|
["gtest"]="https://github.com/google/googletest.git"
|
||||||
|
["libbcrypt"]="https://github.com/rg3/libbcrypt"
|
||||||
|
["rocksdb"]="https://github.com/facebook/rocksdb.git"
|
||||||
|
["mgclient"]="https://github.com/memgraph/mgclient.git"
|
||||||
|
["pymgclient"]="https://github.com/memgraph/pymgclient.git"
|
||||||
|
["mgconsole"]="http://github.com/memgraph/mgconsole.git"
|
||||||
|
["spdlog"]="https://github.com/gabime/spdlog"
|
||||||
|
["nlohmann"]="https://raw.githubusercontent.com/nlohmann/json/9d69186291aca4f0137b69c1dee313b391ff564c/single_include/nlohmann/json.hpp"
|
||||||
|
["neo4j"]="https://s3-eu-west-1.amazonaws.com/deps.memgraph.io/neo4j-community-3.2.3-unix.tar.gz"
|
||||||
|
["librdkafka"]="https://github.com/edenhill/librdkafka.git"
|
||||||
|
["protobuf"]="https://github.com/protocolbuffers/protobuf.git"
|
||||||
|
["pulsar"]="https://github.com/apache/pulsar.git"
|
||||||
|
["librdtsc"]="https://github.com/gabrieleara/librdtsc.git"
|
||||||
|
)
|
||||||
|
|
||||||
# antlr
|
# antlr
|
||||||
antlr_generator_filename="antlr-4.6-complete.jar"
|
file_get_try_double "${primary_urls[antlr4-generator]}" "${secondary_urls[antlr4-generator]}"
|
||||||
# wget -O ${antlr_generator_filename} http://www.antlr.org/download/${antlr_generator_filename}
|
|
||||||
wget -nv -O ${antlr_generator_filename} https://s3-eu-west-1.amazonaws.com/deps.memgraph.io/${antlr_generator_filename}
|
antlr4_tag="4.10.1" # v4.10.1
|
||||||
antlr4_tag="aacd2a2c95816d8dc1c05814051d631bfec4cf3e" # v4.6
|
repo_clone_try_double "${primary_urls[antlr4-code]}" "${secondary_urls[antlr4-code]}" "antlr4" "$antlr4_tag" true
|
||||||
clone https://github.com/antlr/antlr4.git antlr4 $antlr4_tag
|
pushd antlr4
|
||||||
# fix missing include
|
git apply ../antlr4.10.1.patch
|
||||||
sed -i 's/^#pragma once/#pragma once\n#include <functional>/' antlr4/runtime/Cpp/runtime/src/support/CPPUtils.h
|
popd
|
||||||
# remove shared library from install dependencies
|
|
||||||
sed -i 's/install(TARGETS antlr4_shared/install(TARGETS antlr4_shared OPTIONAL/' antlr4/runtime/Cpp/runtime/CMakeLists.txt
|
|
||||||
|
|
||||||
# cppitertools v2.0 2019-12-23
|
# cppitertools v2.0 2019-12-23
|
||||||
cppitertools_ref="cb3635456bdb531121b82b4d2e3afc7ae1f56d47"
|
cppitertools_ref="cb3635456bdb531121b82b4d2e3afc7ae1f56d47"
|
||||||
clone https://github.com/ryanhaining/cppitertools.git cppitertools $cppitertools_ref
|
repo_clone_try_double "${primary_urls[cppitertools]}" "${secondary_urls[cppitertools]}" "cppitertools" "$cppitertools_ref"
|
||||||
|
|
||||||
# fmt
|
|
||||||
fmt_tag="7fa8f8fa48b0903deab5bb42e6760477173ac485" # v3.0.1
|
|
||||||
# Commit which fixes an issue when compiling with C++14 and higher.
|
|
||||||
fmt_cxx14_fix="b9aaa507fc49680d037fd84c043f747a395bce04"
|
|
||||||
clone https://github.com/fmtlib/fmt.git fmt $fmt_tag $fmt_cxx14_fix
|
|
||||||
|
|
||||||
# rapidcheck
|
# rapidcheck
|
||||||
rapidcheck_tag="7bc7d302191a4f3d0bf005692677126136e02f60" # (2020-05-04)
|
rapidcheck_tag="7bc7d302191a4f3d0bf005692677126136e02f60" # (2020-05-04)
|
||||||
clone https://github.com/emil-e/rapidcheck.git rapidcheck $rapidcheck_tag
|
repo_clone_try_double "${primary_urls[rapidcheck]}" "${secondary_urls[rapidcheck]}" "rapidcheck" "$rapidcheck_tag"
|
||||||
|
|
||||||
# google benchmark
|
# google benchmark
|
||||||
benchmark_tag="4f8bfeae470950ef005327973f15b0044eceaceb" # v1.1.0
|
benchmark_tag="v1.6.0"
|
||||||
clone https://github.com/google/benchmark.git benchmark $benchmark_tag
|
repo_clone_try_double "${primary_urls[gbenchmark]}" "${secondary_urls[gbenchmark]}" "benchmark" "$benchmark_tag" true
|
||||||
|
|
||||||
# google test
|
# google test
|
||||||
googletest_tag="ec44c6c1675c25b9827aacd08c02433cccde7780" # v1.8.0
|
googletest_tag="release-1.8.0"
|
||||||
clone https://github.com/google/googletest.git googletest $googletest_tag
|
repo_clone_try_double "${primary_urls[gtest]}" "${secondary_urls[gtest]}" "googletest" "$googletest_tag" true
|
||||||
|
|
||||||
# google logging
|
|
||||||
glog_tag="042a21657e79784226babab8b942f7bd0949635f" # custom version (v0.3.5+)
|
|
||||||
clone https://github.com/memgraph/glog.git glog $glog_tag
|
|
||||||
|
|
||||||
# google flags
|
|
||||||
gflags_tag="b37ceb03a0e56c9f15ce80409438a555f8a67b7c" # custom version (May 6, 2017)
|
|
||||||
clone https://github.com/memgraph/gflags.git gflags $gflags_tag
|
|
||||||
|
|
||||||
# libbcrypt
|
# libbcrypt
|
||||||
libbcrypt_tag="8aa32ad94ebe06b76853b0767c910c9fbf7ccef4" # custom version (Dec 16, 2016)
|
libbcrypt_tag="8aa32ad94ebe06b76853b0767c910c9fbf7ccef4" # custom version (Dec 16, 2016)
|
||||||
clone https://github.com/rg3/libbcrypt libbcrypt $libbcrypt_tag
|
repo_clone_try_double "${primary_urls[libbcrypt]}" "${secondary_urls[libbcrypt]}" "libbcrypt" "$libbcrypt_tag"
|
||||||
|
|
||||||
# neo4j
|
# neo4j
|
||||||
wget -nv https://s3-eu-west-1.amazonaws.com/deps.memgraph.io/neo4j-community-3.2.3-unix.tar.gz -O neo4j.tar.gz
|
file_get_try_double "${primary_urls[neo4j]}" "${secondary_urls[neo4j]}"
|
||||||
tar -xzf neo4j.tar.gz
|
tar -xzf neo4j-community-3.2.3-unix.tar.gz
|
||||||
rm -rf neo4j
|
|
||||||
mv neo4j-community-3.2.3 neo4j
|
mv neo4j-community-3.2.3 neo4j
|
||||||
rm neo4j.tar.gz
|
rm neo4j-community-3.2.3-unix.tar.gz
|
||||||
|
|
||||||
# nlohmann json
|
# nlohmann json
|
||||||
# We wget header instead of cloning repo since repo is huge (lots of test data).
|
# We wget header instead of cloning repo since repo is huge (lots of test data).
|
||||||
# We use head on Sep 1, 2017 instead of last release since it was long time ago.
|
# We use head on Sep 1, 2017 instead of last release since it was long time ago.
|
||||||
mkdir -p json
|
mkdir -p json
|
||||||
cd json
|
cd json
|
||||||
wget "https://raw.githubusercontent.com/nlohmann/json/b3e5cb7f20dcc5c806e418df34324eca60d17d4e/single_include/nlohmann/json.hpp"
|
file_get_try_double "${primary_urls[nlohmann]}" "${secondary_urls[nlohmann]}"
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
bzip2_tag="0405487e2b1de738e7f1c8afb50d19cf44e8d580" # v1.0.6 (May 26, 2011)
|
rocksdb_tag="v6.14.6" # (2020-10-14)
|
||||||
clone https://github.com/VFR-maniac/bzip2 bzip2 $bzip2_tag
|
repo_clone_try_double "${primary_urls[rocksdb]}" "${secondary_urls[rocksdb]}" "rocksdb" "$rocksdb_tag" true
|
||||||
|
pushd rocksdb
|
||||||
zlib_tag="cacf7f1d4e3d44d871b605da3b647f07d718623f" # v1.2.11.
|
git apply ../rocksdb.patch
|
||||||
clone https://github.com/madler/zlib.git zlib $zlib_tag
|
popd
|
||||||
# remove shared library from install dependencies
|
|
||||||
sed -i 's/install(TARGETS zlib zlibstatic/install(TARGETS zlibstatic/g' zlib/CMakeLists.txt
|
|
||||||
|
|
||||||
rocksdb_tag="f3e33549c151f30ac4eb7c22356c6d0331f37652" # (2020-10-14)
|
|
||||||
clone https://github.com/facebook/rocksdb.git rocksdb $rocksdb_tag
|
|
||||||
# remove shared library from install dependencies
|
|
||||||
sed -i 's/TARGETS ${ROCKSDB_SHARED_LIB}/TARGETS ${ROCKSDB_SHARED_LIB} OPTIONAL/' rocksdb/CMakeLists.txt
|
|
||||||
|
|
||||||
# mgclient
|
# mgclient
|
||||||
mgclient_tag="fe94b3631385ef5dbe40a3d8458860dbcc33e6ea" # May 27, 2019
|
mgclient_tag="v1.4.0" # (2022-06-14)
|
||||||
clone https://github.com/memgraph/mgclient.git mgclient $mgclient_tag
|
repo_clone_try_double "${primary_urls[mgclient]}" "${secondary_urls[mgclient]}" "mgclient" "$mgclient_tag"
|
||||||
sed -i 's/\${CMAKE_INSTALL_LIBDIR}/lib/' mgclient/src/CMakeLists.txt
|
sed -i 's/\${CMAKE_INSTALL_LIBDIR}/lib/' mgclient/src/CMakeLists.txt
|
||||||
|
|
||||||
|
# pymgclient
|
||||||
|
pymgclient_tag="4f85c179e56302d46a1e3e2cf43509db65f062b3" # (2021-01-15)
|
||||||
|
repo_clone_try_double "${primary_urls[pymgclient]}" "${secondary_urls[pymgclient]}" "pymgclient" "$pymgclient_tag"
|
||||||
|
|
||||||
|
# mgconsole
|
||||||
|
mgconsole_tag="v1.1.0" # (2021-10-07)
|
||||||
|
repo_clone_try_double "${primary_urls[mgconsole]}" "${secondary_urls[mgconsole]}" "mgconsole" "$mgconsole_tag" true
|
||||||
|
|
||||||
|
spdlog_tag="v1.9.2" # (2021-08-12)
|
||||||
|
repo_clone_try_double "${primary_urls[spdlog]}" "${secondary_urls[spdlog]}" "spdlog" "$spdlog_tag" true
|
||||||
|
|
||||||
|
# librdkafka
|
||||||
|
librdkafka_tag="v1.7.0" # (2021-05-06)
|
||||||
|
repo_clone_try_double "${primary_urls[librdkafka]}" "${secondary_urls[librdkafka]}" "librdkafka" "$librdkafka_tag" true
|
||||||
|
|
||||||
|
# protobuf
|
||||||
|
protobuf_tag="v3.12.4"
|
||||||
|
repo_clone_try_double "${primary_urls[protobuf]}" "${secondary_urls[protobuf]}" "protobuf" "$protobuf_tag" true
|
||||||
|
pushd protobuf
|
||||||
|
./autogen.sh && ./configure CC=clang CXX=clang++ --prefix=$(pwd)/lib
|
||||||
|
popd
|
||||||
|
|
||||||
|
#pulsar
|
||||||
|
pulsar_tag="v2.8.1"
|
||||||
|
repo_clone_try_double "${primary_urls[pulsar]}" "${secondary_urls[pulsar]}" "pulsar" "$pulsar_tag" true
|
||||||
|
pushd pulsar
|
||||||
|
git apply ../pulsar.patch
|
||||||
|
popd
|
||||||
|
|
||||||
|
#librdtsc
|
||||||
|
librdtsc_tag="v0.3"
|
||||||
|
repo_clone_try_double "${primary_urls[librdtsc]}" "${secondary_urls[librdtsc]}" "librdtsc" "$librdtsc_tag" true
|
||||||
|
pushd librdtsc
|
||||||
|
git apply ../librdtsc.patch
|
||||||
|
popd
|
||||||
|
|||||||
201
licenses/APL.txt
Normal file
201
licenses/APL.txt
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
84
licenses/BSL.txt
Normal file
84
licenses/BSL.txt
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
MEMGRAPH
|
||||||
|
BUSINESS SOURCE LICENSE (BSL) 1.1
|
||||||
|
|
||||||
|
PARAMETERS
|
||||||
|
|
||||||
|
LICENSOR: MEMGRAPH LTD
|
||||||
|
LICENSED WORK: MEMGRAPH COMMUNITY EDITION (MCE) version 2.0
|
||||||
|
ADDITIONAL USE GRANT: You may use the Licensed Work in accordance with the
|
||||||
|
terms of this License solely for any Authorised Purpose,
|
||||||
|
provided that you may not use the Licensed Work for any
|
||||||
|
Excluded Purpose.
|
||||||
|
|
||||||
|
“Authorised Purpose” means any of the following,
|
||||||
|
provided always that (a) you do not embed or otherwise
|
||||||
|
distribute the Licensed Work to third parties; and (b)
|
||||||
|
you do not provide third parties direct access to
|
||||||
|
operate or control the Licensed Work as a standalone
|
||||||
|
solution or service:
|
||||||
|
1. for your internal business purposes;
|
||||||
|
2. to integrate the Licensed Work with your own
|
||||||
|
proprietary software, provided that your proprietary
|
||||||
|
software adds a primary and significant functionality
|
||||||
|
to the Licensed Work (the “Integrated Solution”);
|
||||||
|
and/or
|
||||||
|
3. to host the Integrated Solution and make it available
|
||||||
|
to third parties on a ‘software-as-a-service’ or an
|
||||||
|
equivalent distributed model.
|
||||||
|
“Excluded Purpose” means any of the following:
|
||||||
|
1. making the Licensed Work accessible to any third
|
||||||
|
party outside of your organization as a standalone
|
||||||
|
solution or service;
|
||||||
|
2. hosting and making the Licensed Work available to
|
||||||
|
third parties on a ‘database-as-a-service’ or any
|
||||||
|
equivalent distributed model as a standalone solution or
|
||||||
|
service; and/or
|
||||||
|
3. using the Licensed Work to create a work or solution
|
||||||
|
which competes (or might reasonably be expected to
|
||||||
|
compete) with the Licensed Work.
|
||||||
|
CHANGE DATE: 2026-27-04
|
||||||
|
CHANGE LICENSE: Apache License, Version 2.0
|
||||||
|
|
||||||
|
For information about alternative licensing arrangements, please visit: https://memgraph.com/legal.
|
||||||
|
The Business Source License (this document, or the “License”) is not an
|
||||||
|
‘open source’ license. However, the Licensed Work will eventually be made
|
||||||
|
available under an ‘open source’ license, as stated in this License.
|
||||||
|
|
||||||
|
TERMS
|
||||||
|
The Licensor hereby grants you the right to copy, modify, create derivative works, redistribute, and make non-production
|
||||||
|
use of the Licensed Work. The Licensor may make an Additional Use Grant, above, permitting limited production use.
|
||||||
|
Effective on the Change Date, or the fourth anniversary of the first publicly available distribution of a specific
|
||||||
|
version of the Licensed Work under this License, whichever comes first, the Licensor hereby grants you rights under the
|
||||||
|
terms of the Change License, and the rights granted in the paragraph above terminate. If your use of the Licensed Work
|
||||||
|
does not comply with the requirements currently in effect as described in thisLicense, you must purchase a commercial
|
||||||
|
license from the Licensor, its affiliated entities, or authorized resellers, or you must refrain from using the Licensed
|
||||||
|
Work. All copies of the original and modified Licensed Work, and derivative works of the Licensed Work, are subject to
|
||||||
|
this License. This License applies separately for each version of the Licensed Work and the Change Date may vary for
|
||||||
|
each version of the Licensed Work released by Licensor. You must conspicuously display this License on each original or
|
||||||
|
modified copy of the Licensed Work. If you receive the Licensed Work in original or modified form from a third party,
|
||||||
|
the terms and conditions set forth in this License apply to your use of that work.Any use of the Licensed Work in
|
||||||
|
violation of this License will automatically terminate your rights under this License for the current and all other
|
||||||
|
versions of the Licensed Work. This License does not grant you any right in any trademark or logo of Licensor or its
|
||||||
|
affiliates (provided that you may use a trademark or logo of Licensor as expressly required by this License).
|
||||||
|
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS
|
||||||
|
ALL WARRANTIES AND CONDITIONS, EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
|
||||||
|
MariaDB hereby grants you permission to use this License’s text to license your works, and to refer to it using the
|
||||||
|
trademark ‘Business Source License’, as long as you comply with the Covenants of Licensor below.
|
||||||
|
Covenants of Licensor
|
||||||
|
In consideration of the right to use this License’s text and the ‘Business Source License’ name and trademark, Licensor
|
||||||
|
covenants to MariaDB, and to all other recipients of the Licensed Work to be provided by Licensor:
|
||||||
|
1. To specify as the Change License the GPL Version 2.0 or any later version, or a license that is compatible with GPL
|
||||||
|
Version 2.0 or a later version, where “compatible” means that software provided under the Change License can be
|
||||||
|
included in a program with software provided under GPL Version 2.0 or a later version. Licensor may specify
|
||||||
|
additional Change Licenses without limitation.
|
||||||
|
|
||||||
|
2. To either: (a) specify an additional grant of rights to use that does not impose any additional restriction on the
|
||||||
|
right granted in this License, as the Additional Use Grant; or (b) insert the text “None”.
|
||||||
|
|
||||||
|
3. To specify a Change Date.
|
||||||
|
|
||||||
|
4. Not to modify this License in any other way.
|
||||||
|
|
||||||
|
NOTICE
|
||||||
|
License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved. ‘Business Source License’ is a trademark of MariaDB Corporation Ab.
|
||||||
464
licenses/MEL.txt
Normal file
464
licenses/MEL.txt
Normal file
@@ -0,0 +1,464 @@
|
|||||||
|
MEMGRAPH
|
||||||
|
ENTERPRISE LICENCE AGREEMENT
|
||||||
|
|
||||||
|
|
||||||
|
Memgraph Limited is registered in England under registration 10195084 and has its registered office at Suite 4,
|
||||||
|
Ironstone House, Ironstone Way, Brixworth, Northampton, NN6 9UD (“Memgraph”).
|
||||||
|
|
||||||
|
|
||||||
|
Memgraph agrees to license and/or grant you (the “Customer”) access to the Software ( as defined below) and provide
|
||||||
|
support and services to you only if you accept and agree to be bound by the terms and conditions in this Memgraph
|
||||||
|
Enterprise Licence Agreement (the “Agreement”). By signing an Order Document (as defined below), which is subject to and
|
||||||
|
part of this Agreement, installing and using the Software or by downloading a trial version of the Software, you agree
|
||||||
|
to be bound by the terms of this Agreement.
|
||||||
|
|
||||||
|
|
||||||
|
Memgraph Enterprise Trial Users: If you receive free of charge trial access to the Software, you are deemed a
|
||||||
|
“Customer” for purposes of this Agreement, except that you are subject to the additional restrictions and limitations
|
||||||
|
set forth in Section 3.2 below in respect of your use of such Software.
|
||||||
|
|
||||||
|
|
||||||
|
1. DEFINITIONS.
|
||||||
|
1.1. “Applicable Laws” means (i) all applicable laws, statutes and regulations, and (ii) regulatory policies,
|
||||||
|
guidelines and industry codes (in each case having the force of law), which apply to the provisions of the
|
||||||
|
Software and Services and this Agreement.
|
||||||
|
1.2. “Confidential Information” means all information disclosed by a party (“Disclosing Party”) to the other party
|
||||||
|
(“Receiving Party”), whether orally or in writing, that is designated as confidential or that reasonably should
|
||||||
|
be understood to be confidential given the nature of the information and the circumstances of disclosure.
|
||||||
|
Customer’s Confidential Information includes Customer Data; Memgraph Confidential Information includes the
|
||||||
|
Software and Services; and Confidential Information of each party includes the terms and conditions of this
|
||||||
|
Agreement and all Orders (including pricing), as well as business and marketing plans, technology and technical
|
||||||
|
information, product plans and designs, and business processes disclosed by such party. However, Confidential
|
||||||
|
Information does not include any information that (i) is or becomes generally known to the public without
|
||||||
|
breach of any obligation owed to the Disclosing Party, (ii) was known to the Receiving Party prior to its
|
||||||
|
disclosure by the Disclosing Party without breach of any obligation owed to the Disclosing Party, (iii) is
|
||||||
|
received from a third party without breach of any obligation owed to the Disclosing Party, or (iv) was
|
||||||
|
independently developed by the Receiving Party.
|
||||||
|
1.3. “Customer Data” means business information or other data loaded by or for Customer and/or processed by the
|
||||||
|
Software.
|
||||||
|
1.4. “Data Protection Legislation” means all applicable data protection and privacy legislation in force from time
|
||||||
|
to time in the UK including the General Data Protection Regulation ((EU) 2016/679) as it forms part of UK law
|
||||||
|
by virtue of section 3 of the European Union (Withdrawal) Act 2018; the Data
|
||||||
|
Protection Act 2018; the Privacy and Electronic Communications Directive 2002/58/EC (as updated by Directive
|
||||||
|
2009/136/EC); and the Privacy and Electronic Communications Regulations 2003 (SI 2003/2426), in each case as
|
||||||
|
amended.
|
||||||
|
1.5. “Derivate Work” means any modification or enhancement made by Customer to the Software, whether in source code,
|
||||||
|
binary executable, intermediate or other form.
|
||||||
|
1.6. “Effective Date” means the date on which you execute this Agreement.
|
||||||
|
1.7. “Order Document” or “Order” means, as applicable: (i) in the case of a Trial Licence, the Memgraph trial
|
||||||
|
registration form available on Memgraph’s website; or (ii) in any other case, an order form that is submitted
|
||||||
|
by or on behalf of Customer and executed by or on behalf of the parties referencing
|
||||||
|
this Agreement and that specifies the Software and/or Services ordered by Customer, as well as the specific
|
||||||
|
terms and conditions, for that particular transaction.
|
||||||
|
1.8. “Services” means those services, including Support Services, which may be provided to Customer by Memgraph
|
||||||
|
pursuant to the terms of this Agreement and are expressly limited to those services directly related to
|
||||||
|
Customer’s use of the Software, and expressly exclude any other services.
|
||||||
|
1.9. “Software” means Memgraph’s proprietary downloadable graph database enterprise software known as Memgraph
|
||||||
|
Enterprise Edition (MEE) (“Enterprise Software”) and the associated technical documentation located at
|
||||||
|
https://docs.memgraph.com/ (“Documentation”), as well as software updates, upgrades, bug fixes, or modified
|
||||||
|
versions thereof that Memgraph licenses or provides to Customer directly or indirectly throughout the Subscription
|
||||||
|
Term. For the avoidance of doubt, for the purpose of this Agreement, the term Software excludes Memgraph’s
|
||||||
|
free-to-use software known as Memgraph Community Edition (MCE) which is licensed pursuant to separate terms
|
||||||
|
(including the Business Source Licence (BSL) or Apache 2.0) as indicated here: https://memgraph.com/legal.
|
||||||
|
1.10. “Subscription Term” means the fixed term, of not less than one (1) year, designated in an Order Document
|
||||||
|
beginning on the Effective Date and ending at the end of the period stated therein. If no expiration date is
|
||||||
|
specified in an Order Document, the Subscription Term shall be a one (1) year period (“Minimum Subscription
|
||||||
|
Term”). A “Subscription” is the binding, non-cancellable contract for the use of the Software for the
|
||||||
|
Subscription Term as set forth in an Order Document.
|
||||||
|
1.11. “Support” means the support and maintenance services, including any updates, upgrades, patches, enhancements
|
||||||
|
and bug fixes for the Software that may be provided to Customer by Memgraph pursuant to the terms of this
|
||||||
|
Agreement.
|
||||||
|
1.12. “Users” means employees and Contractors of Customer that Customer has permitted or authorized to access and use
|
||||||
|
of the Software on Customer’s behalf pursuant to the terms of this Agreement.
|
||||||
|
|
||||||
|
2. ORDERS, DELIVERY; SUPPORT.
|
||||||
|
2.1. Delivery. Customer shall access the Software from Memgraph’s website or online repository (as instructed by
|
||||||
|
Memgraph) after the Effective Date. Memgraph shall deliver to Customer the licence key necessary to unlock the
|
||||||
|
Software after Customer accepts an Order. Unless otherwise stated in an Order, Customer is solely responsible
|
||||||
|
for installing Software on Customer’s own computer equipment. In some instances, Customer’s purchasing
|
||||||
|
relationship exists solely between Customer and an authorised reseller of Memgraph’s Software and Services
|
||||||
|
(a “Reseller”), in which case Sections 5.1-5.3 (Fees and Payment) will be inapplicable to such Order(s), and
|
||||||
|
the Reseller shall be responsible for submitting Orders and the appropriate payment method therewith to
|
||||||
|
Memgraph. An Order is not binding until Memgraph accepts and countersigns the Order.
|
||||||
|
2.2. Support. Memgraph will use commercially reasonable efforts to provide Support to Customer in accordance with
|
||||||
|
Memgraph’s then-current terms and conditions set forth at
|
||||||
|
https://download.memgraph.com/legal/memgraph-support-terms-and-conditions.pdf at the support tier stated in the
|
||||||
|
applicable Order. The Support terms and conditions are subject to change at Memgraph’s discretion; however,
|
||||||
|
Memgraph will not materially reduce the level of Support during a Subscription Term for which Fees have been
|
||||||
|
paid.
|
||||||
|
|
||||||
|
3. LICENCE GRANTS; RESTRICTIONS AND PROPRIETARY RIGHTS.
|
||||||
|
Customer’s licence and access rights and benefits, and Memgraph’s obligations to Customer, will vary depending on the
|
||||||
|
product and the type of licence Memgraph is granting. If you purchased a licence to Memgraph Software, your licence will
|
||||||
|
be subject to certain use and/or capacity restrictions, as identified on the applicable Order Document.
|
||||||
|
3.1. Enterprise Software Licence. In consideration of the Fees paid hereunder and subject to the terms of this
|
||||||
|
Agreement and the applicable Order, Memgraph grants Customer a world-wide, non-exclusive, non-transferable,
|
||||||
|
non-sublicensable, and limited licence during the applicable Subscription Term, to download, access, install
|
||||||
|
and use the Enterprise Software up to the maximum capacity (“Licensed Capacity”), and subject to the usage
|
||||||
|
rules, specified in the applicable Order Document, and to use Documentation solely for Customer’s internal
|
||||||
|
business purposes in connection with the operation of the Enterprise Software.
|
||||||
|
3.2. Enterprise Trial Licence. If the Customer downloads, accesses, installs or uses the Software under a trial
|
||||||
|
licence (“Trial Licence”), then Customer may use one (1) copy of the Software in accordance with the terms and
|
||||||
|
conditions of this Agreement for a thirty (30) day period, or such longer trial period represented by the
|
||||||
|
applicable licence key issued by or expressly authorised by Memgraph (the “Trial Period”). Trial Licences are
|
||||||
|
permitted solely for Customer’s evaluation use to determine whether to purchase a Subscription to the Software.
|
||||||
|
Customer may not use a Trial Licence for any other purpose. At the end of the Trial Period, the Trial Licence
|
||||||
|
will expire and this Agreement will terminate as to such Trial Licence and continue to apply to any subsequent
|
||||||
|
Subscription or use of the Software. If Customer decides not to obtain a Subscription upon expiration of the
|
||||||
|
Trial Period, it will promptly cease using and will delete the Software from its computer systems. Memgraph has
|
||||||
|
the right to terminate a Trial Licence at any time for any reason.
|
||||||
|
3.3. Limited right to modify the Software. In consideration of the Fees paid hereunder and subject to the terms of
|
||||||
|
this Agreement and the applicable Order, Memgraph grants Customer a licence to: (i) create, compile and test
|
||||||
|
Derivative Works; (ii) use Derivative Works solely for Customer’s internal business purposes; and (iii)
|
||||||
|
distribute Derivative Works back to Memgraph for potential incorporation into Memgraph’s maintained code base
|
||||||
|
at its sole discretion.
|
||||||
|
3.4. NO OBLIGATIONS. NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THIS AGREEMENT OR IN ANY ORDER DOCUMENT, MEMGRAPH
|
||||||
|
WILL HAVE NO WARRANTY, INDEMNITY, SUPPORT, OR SERVICE LEVEL, OBLIGATIONS WITH RESPECT TO ANY ENTERPRISE TRIAL,
|
||||||
|
OR OTHER NO-CHARGE SOFTWARE (INCLUDING TOOLS AND UTILITIES) LICENCES.
|
||||||
|
3.5. General Restrictions. Customer acknowledges that the Software, and its structure, organization, and source code,
|
||||||
|
constitute Memgraph’s and its suppliers’ valuable trade secrets, and that usage of the Software is subject to
|
||||||
|
the following restrictions:
|
||||||
|
3.5.1. Restrictions. Customer agrees not to, and not to authorize any third party to: (i) allow access or use
|
||||||
|
of the Software by anyone other than its Users; (ii) distribute, embed, sell, rent, transfer, lease,
|
||||||
|
lend, sublicense, loan, assign, pledge, grant a security interest in, or otherwise make the Software
|
||||||
|
accessible or available to any third party; except to the limited extent expressly provided in Section
|
||||||
|
3.5.2, use the Software in any service-bureau, timesharing, outsourcing or similar arrangement; (iii)
|
||||||
|
subject only to the limited rights set out in Section 3.3, modify, adapt, transform, derive, disassemble,
|
||||||
|
decompile, reverse engineer or otherwise attempt to derive the structure, sequence or organization of,
|
||||||
|
the Software or any portion thereof; (iv) remove or alter product identification, copyright, trademark or
|
||||||
|
other proprietary markings contained in or on the Software; (v) conduct any competitive analysis, publish
|
||||||
|
or share with any third party any results of any technical evaluation or tests performed on the Software,
|
||||||
|
or disclose Software features, errors or bugs to a third party without Memgraph’s prior written consent;
|
||||||
|
or (vi) engage in any act designed to circumvent any restriction set forth in this Agreement, in the
|
||||||
|
Software, or in an Order, including but not limited to restrictions related to Licensed Capacity.
|
||||||
|
3.5.2. Internal Use Licences; Users. The Software is licensed for Customer’s internal business use and not for
|
||||||
|
distribution or use by third parties. For clarity, however, Customer may make available to third parties
|
||||||
|
any Customer-hosted services or other Customer applications or services that make use of or incorporate
|
||||||
|
the Software, provided and solely to the extent that (i) Customer’s application or hosted service adds
|
||||||
|
primary and significant functionality to the Software, (ii) Customer does not embed or otherwise
|
||||||
|
distribute the Software to third parties (iii) Customer does not provide third parties direct access to
|
||||||
|
operate or control the Software itself; and (iv) Customer at all times remains in compliance with the
|
||||||
|
terms of the applicable licence grants under this Agreement. Subject to the terms and conditions of this
|
||||||
|
Agreement, in addition to Customer’s employees, Customer may permit its independent contractors and
|
||||||
|
consultants (“Contractors”) to serve as Users. Customer will remain responsible for compliance by each of
|
||||||
|
its Users (including but not limited to any Contractor Users) with all of the terms and conditions of
|
||||||
|
this Agreement, and any use of the Software by any Contractors must be for the sole benefit of Customer.
|
||||||
|
3.6. Ownership; Reservation of Rights. This is an agreement for use of Memgraph Software and not an agreement for
|
||||||
|
sale. Customer acknowledges that it is obtaining only a limited right to use the Software on a licensed basis,
|
||||||
|
and that irrespective of any use of the words “purchase”, “sale” or like terms hereunder no ownership rights
|
||||||
|
are being conveyed to Customer. Customer agrees that Memgraph or its suppliers retain all right, title and
|
||||||
|
interest (including all patent, copyright, trade secret and other intellectual property rights) in and to the
|
||||||
|
Memgraph Software. Nothing in this Section shall be deemed as granting Memgraph ownership of Customer Data or
|
||||||
|
in any way impacting Customer’s ownership of Customer Data.
|
||||||
|
3.7. Third Party Code. The Software may contain or be provided with components which are licensed from third
|
||||||
|
parties, including components subject to the terms and conditions of “open source” software licences
|
||||||
|
(“Open Source Software”). Open Source Software may be identified in the Software, Documentation, or in a list
|
||||||
|
of the Open Source Software provided to you upon your written request. To the extent required by the licence
|
||||||
|
that accompanies the Open Source Software, the terms of such licence will apply in lieu of the terms of this
|
||||||
|
Agreement with respect to such Open Source Software, including, without limitation, any provisions governing
|
||||||
|
access to source code, modification, or reverse engineering.
|
||||||
|
3.8. IP Ownership. The Parties agree that, save as otherwise provided in this Agreement, neither party shall gain, by
|
||||||
|
virtue of this Agreement, any rights of ownership or any other interest, right or title of copyrights, patents,
|
||||||
|
trade secrets, trademarks, or any other intellectual property rights owned by the other Party. Any and all new
|
||||||
|
works developed in the course of performing obligations pursuant to this Agreement and all new inventions,
|
||||||
|
innovations or ideas developed by a Party in the course of performance of its activities under this Agreement,
|
||||||
|
will belong to that Party who develops the same. Notwithstanding anything to the contrary in this Section, the
|
||||||
|
Parties understand and agree that any and all proprietary materials developed by a Party prior to this
|
||||||
|
Agreement and any modifications, enhancements, improvements or inventions made to such proprietary materials
|
||||||
|
shall be owned by that Party, regardless of which Party prepared or developed such modifications, enhancements,
|
||||||
|
improvements or inventions.
|
||||||
|
3.9. License-back of Derivate Works. If Customer elects, at its sole discretion, to distribute Derivative Works
|
||||||
|
back to Memgraph for potential incorporation into Memgraph’s maintained code base, Customer grants Memgraph
|
||||||
|
(without any restrictions, limitations or requirement of remuneration) a worldwide, non-exclusive, fully
|
||||||
|
paid-up, royalty-free, perpetual, irrevocable, transferable and sublicensable licence to use, exploit, modify,
|
||||||
|
make derivative works of, commercialise, distribute and otherwise exploit such Derivative Works.
|
||||||
|
|
||||||
|
|
||||||
|
4. CUSTOMER DATA; OBLIGATIONS OF CUSTOMER AND MEMGRAPH.
|
||||||
|
4.1. Customer shall retain all of its rights, title, and interest in and to its intellectual property rights in
|
||||||
|
Customer Data. Customer grants to Memgraph a non-exclusive, worldwide, limited-term licence solely to host,
|
||||||
|
copy, transmit and display Customer Data as reasonably necessary for Memgraph to support Customer’s use of the
|
||||||
|
Software, to ensure the security of and to administrate the Software, and to deliver Services in accordance
|
||||||
|
with this Agreement or as otherwise outlined in https://memgraph.com/legal/privacy-policy/.
|
||||||
|
4.2. Protection of Customer Data. Memgraph will maintain appropriate administrative, physical, and technical
|
||||||
|
safeguards, consistent with generally prevailing industry standards, for protection of the security,
|
||||||
|
confidentiality, and integrity of Customer Data, as described in the Documentation. Those safeguards will
|
||||||
|
include, but will not be limited to, measures for preventing access, use, modification, or disclosure of
|
||||||
|
Customer Data by Memgraph personnel, except as permitted by this Agreement.
|
||||||
|
4.3. Personal data. Both parties will comply with all applicable requirements of the Data Protection Legislation.
|
||||||
|
This section 4.3 is in addition to, and does not relieve, remove or replace, a party’s obligations under the
|
||||||
|
Data Protection Legislation. Notwithstanding the foregoing, the parties acknowledge that, in the ordinary
|
||||||
|
course of providing the Services, Memgraph shall not process personal data (as defined in the Data Protection
|
||||||
|
Legislation) on behalf of the Customer. In the event that the Customer requires Memgraph to process personal
|
||||||
|
data on its behalf, it shall notify Memgraph and the parties shall execute such additional terms as necessary
|
||||||
|
to comply with applicable Data Protection Legislation.
|
||||||
|
|
||||||
|
5. FEES AND PAYMENT.
|
||||||
|
5.1. Fees. Customer will pay Memgraph the fees for the Licences and Services as set forth in the applicable Order (
|
||||||
|
“Fees”). Customer acknowledges and agrees that if Customer’s use of the Software exceeds the Licensed Capacity
|
||||||
|
set forth on the applicable Orders or otherwise requires the payment of additional fees (per the terms of this
|
||||||
|
Agreement), Customer shall be invoiced for such usage and Customer agrees to pay the additional fees in
|
||||||
|
accordance with this Section. Notwithstanding the terms of Section 5.4 below (Reconciliation), Customer
|
||||||
|
acknowledges and agrees that it is obligated to ensure that its Software usage does not exceed the Licensed Capacity
|
||||||
|
and to promptly notify Memgraph of any such excess usage no more than thirty (30) days from the last day of the
|
||||||
|
calendar month during which such excess usage occurred.
|
||||||
|
5.2. Payment Terms. Except as otherwise specifically set forth on an Order Document, all fees are due and payable
|
||||||
|
within thirty days after the date of invoice. Renewal Fees for any renewal Subscription Term (if purchased by
|
||||||
|
Customer) will be due and payable within thirty (30) days of expiration of the then-current term. If Fees are
|
||||||
|
not paid when due, or in the event of other breach of this Agreement, Customer shall discontinue use of the
|
||||||
|
Software and Memgraph may suspend its performance, including its delivery of technical support of the Software
|
||||||
|
or other Services without further notice and without penalty. All Orders (including multi-year Subscriptions
|
||||||
|
with annual payment schedules) are non-cancellable and all amounts paid are non-refundable, unless otherwise
|
||||||
|
expressly set forth herein. Any invoiced amount not received by the due date will accrue late interest at the
|
||||||
|
rate of 1.5% of the outstanding balance per month, or the maximum rate permitted by applicable law, whichever
|
||||||
|
is lower.
|
||||||
|
5.3. Taxes. Fees are exclusive of taxes. Customer will pay any sales, use, value added, duties, fees and other
|
||||||
|
governmental assessments or charges arising out of this Agreement and the transactions contemplated herein.
|
||||||
|
Customer will make all payments free and clear of, and without reduction for, any withholding taxes.
|
||||||
|
5.4. Reconciliation. At Memgraph’s request from time to time, not exceeding once per quarter, Customer will provide
|
||||||
|
Memgraph with a report detailing its use of the Software, including its non-production and/or production use
|
||||||
|
and using the self-monitoring capabilities of the Software or other means, and Memgraph may inspect Customer’s
|
||||||
|
records related to such report not more frequently than annually to ensure payment of Fees. Any on-site review
|
||||||
|
will be conducted during regular business hours at Customer’s offices. The parties will use reasonable efforts
|
||||||
|
to promptly resolve any discrepancies between licensed usage and actual usage.
|
||||||
|
|
||||||
|
6. APPLICABLE LAWS.
|
||||||
|
6.1. Each Party shall perform this Agreement in accordance with all Applicable Laws. Without prejudice to the
|
||||||
|
foregoing, each Party shall:
|
||||||
|
6.1.1. comply with all Applicable Laws relating to anti-bribery, anti-corruption, anti-slavery and human
|
||||||
|
trafficking, including the Bribery Act 2010 and the Modern Slavery Act 2015
|
||||||
|
(the “Relevant Requirements”);
|
||||||
|
6.1.2. have and maintain in place throughout the Term its own policies and procedures, including adequate
|
||||||
|
procedures under the Bribery Act 2010, to ensure compliance with the Relevant Requirements, and will
|
||||||
|
enforce them where appropriate;
|
||||||
|
6.1.3. (if not prohibited by law or regulation from doing so) promptly report to the other Party any request or
|
||||||
|
demand for any undue financial or other advantage of any kind received by the reporting Party in
|
||||||
|
connection with the performance of this Agreement; and
|
||||||
|
6.1.4. (if not prohibited by law or regulation from doing so) notify the other Party (and email shall be
|
||||||
|
sufficient for this purpose) as soon as it becomes aware of any actual or suspected slavery or human
|
||||||
|
trafficking in a supply chain which has a connection with this Agreement.
|
||||||
|
|
||||||
|
7. REPRESENTATIONS AND WARRANTIES.
|
||||||
|
7.1. Mutual Representations and Warranties. Each Party represents and warrants to the other that: (i) it is a
|
||||||
|
corporation lawfully incorporated and validly existing pursuant to the laws of its place of incorporation;
|
||||||
|
(ii) it has all requisite power and authority, corporate or otherwise, to execute, deliver and perform its
|
||||||
|
obligations under this Agreement; and (iii) this Agreement constitutes its legal, valid and binding obligations
|
||||||
|
and may be enforced against it.
|
||||||
|
7.2. Limited Memgraph Warranty. Memgraph warrants that the Software, when used as permitted hereunder and in
|
||||||
|
accordance with the applicable Documentation, will operate in all material respects as described in the
|
||||||
|
applicable Documentation, and that the Services will be provided in a professional manner consistent with
|
||||||
|
industry standards.
|
||||||
|
7.3. Limitations; Remedy. Memgraph does not warrant that the Software or the Services will be error-free,
|
||||||
|
uninterrupted or meet Customer’s specific requirements or that performance of the Services will be
|
||||||
|
uninterrupted. Memgraph will have no warranty obligation under Section 7.2 for Customer’s misuse or failure to
|
||||||
|
use the Software in accordance with its Documentation or this Agreement. Customer’s sole and exclusive remedy,
|
||||||
|
and Memgraph’s sole and exclusive obligation, for breach of warranty will be (i) during the thirty (30) day
|
||||||
|
period following initial Delivery of the Software under an Order, Memgraph’s correction of the program errors
|
||||||
|
that cause the breach of warranty, or if Memgraph cannot substantially correct such breach in a commercially
|
||||||
|
reasonable manner, a refund of the fees paid for the nonconforming Software (ii) during the remainder of the
|
||||||
|
relevant Subscription Term, Memgraph’s delivery of Support with respect to any such program errors. In the
|
||||||
|
event of a refund remedy, Customer’s licences and right to use the Software or receive Services will end. In
|
||||||
|
the event of any noticed breach of warranty with respect to Services, Memgraph’s sole and exclusive obligation
|
||||||
|
shall be the re-performance of the deficient Services.
|
||||||
|
7.4. Disclaimer. THIS SECTION 7 IS A LIMITED WARRANTY AND, EXCEPT EXPRESSLY AS SET FORTH IN SECTION 7.2,
|
||||||
|
THE SOFTWARE, INCLUDING WITHOUT LIMITATION THE THIRD-PARTY CODE, AND ALL SERVICES ARE PROVIDED “AS IS”.
|
||||||
|
MEMGRAPH MAKES NO OTHER WARRANTIES OR REPRESENTATIONS, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, AND DISCLAIMS
|
||||||
|
ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT.
|
||||||
|
|
||||||
|
8. INDEMNIFICATION.
|
||||||
|
8.1. By Memgraph. Memgraph will defend against any action against Customer brought by a third party to the extent the
|
||||||
|
action is based on a claim that the Software infringes a third party’s patent, copyright or trademark
|
||||||
|
(a “Claim”) and indemnify Customer from the damages, liabilities, costs and expenses (including reasonable
|
||||||
|
attorneys’ fees) awarded against Customer or agreed in settlement by Customer resulting from such Claim. If
|
||||||
|
your use of the Software is (or in Memgraph’s opinion likely to be) enjoined, then Memgraph may, at its own
|
||||||
|
expense and at its option: (i) substitute substantially similar functionality for the Software which renders
|
||||||
|
it non-infringing; (ii) procure for Customer the right to continue to use the Software; or if (i) and (ii) are
|
||||||
|
not commercially reasonable, terminate this Agreement and refund Customer any prepaid, unused (pro-rated) Fees
|
||||||
|
for the duration of the then-current Subscription Term. The foregoing obligations of Memgraph will not apply:
|
||||||
|
(i) if the Software is modified by any party other than Memgraph, but solely to the extent the alleged
|
||||||
|
infringement is caused by such modification; (ii) if the Software is used in combination with other products or
|
||||||
|
processes not provided or authorized by Memgraph, but solely to the extent the alleged infringement is caused
|
||||||
|
by such combination; (iii) use of any version or release of Software other than the most current version or
|
||||||
|
release made available to Customer by Memgraph, if its use would have avoided the infringement; (iv) any
|
||||||
|
unauthorized use of the Software. THIS SECTION 8.1 SETS FORTH MEMGRAPH’S SOLE LIABILITY AND CUSTOMER’S SOLE
|
||||||
|
AND EXCLUSIVE REMEDY WITH RESPECT TO ANY CLAIM OF INTELLECTUAL PROPERTY INFRINGEMENT.
|
||||||
|
8.2. By Customer. Customer will indemnify and hold Memgraph and its suppliers harmless against any claims,
|
||||||
|
liabilities, costs, and expenses (including reasonable attorneys’ fees) that Memgraph or its suppliers may
|
||||||
|
incur as a result of a third-party claim arising from or related to Customer Data, or misuse or unauthorised
|
||||||
|
use of the Software by Customer or any User.
|
||||||
|
8.3. Conditions. All defence and indemnity obligations under Sections 8.1 and 8.2 are conditioned on the indemnitee
|
||||||
|
(i) giving the indemnitor written notice of the relevant claim within thirty (30) days after the indemnitee
|
||||||
|
receives notice of the Claim (or sooner if required by applicable law); (ii) reasonably cooperating with the
|
||||||
|
indemnitor, at the indemnitor’s expense, in the defence of the claim; and (iii) giving the indemnitor sole
|
||||||
|
control of the defence and any settlement negotiations. The indemnitee may participate in the defence at its
|
||||||
|
expense.
|
||||||
|
|
||||||
|
9. LIMITATION OF LIABILITY.
|
||||||
|
9.1. TO THE EXTENT PERMITTED BY LAW, NEITHER MEMGRAPH NOR CUSTOMER SHALL BE LIABLE TO THE OTHER OR ANY THIRD PARTY
|
||||||
|
FOR LOST PROFITS (WHETHER DIRECT OR INDIRECT) OR LOSS OF USE OR DATA, SUBSTITUTE GOODS OR SERVICES, OR FOR
|
||||||
|
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, SPECIAL OR EXEMPLARY DAMAGES (INCLUDING DAMAGE TO BUSINESS, REPUTATION OR
|
||||||
|
GOODWILL), OR INDIRECT DAMAGES OF ANY TYPE HOWEVER CAUSED, WHETHER BY BREACH OF WARRANTY, BREACH OF CONTRACT,
|
||||||
|
IN TORT (INCLUDING NEGLIGENCE) OR ANY OTHER LEGAL OR EQUITABLE CAUSE OF ACTION EVEN IF SUCH PARTY HAS BEEN
|
||||||
|
ADVISED OF SUCH DAMAGES IN ADVANCE OR IF SUCH DAMAGES WERE FORESEEABLE.
|
||||||
|
9.2. LIMITATIONS ON DIRECT DAMAGES. EXCEPT FOR ANY EXCLUDED CLAIMS AND ANY DAMAGES THAT CANNOT BE LIMITED UNDER
|
||||||
|
APPLICABLE LAW, IN NO EVENT WILL MEMGRAPH’S TOTAL AGGREGATE LIABILITY ARISING FROM OR RELATED TO THIS
|
||||||
|
AGREEMENT, EXCEED AN AMOUNT EQUAL TO THE TOTAL AMOUNT OF FEES PAID OR PAYABLE BY CUSTOMER TO MEMGRAPH UNDER
|
||||||
|
THIS AGREEMENT DURING THE TWELVE MONTHS PRECEDING THE CLAIM. THE FOREGOING LIMITATIONS SHALL NOT APPLY TO: (i)
|
||||||
|
PAYMENTS TO A THIRD PARTY ARISING FROM A PARTY’S OBLIGATIONS UNDER SECTION 8 (INDEMNIFICATION); (ii) BREACH BY
|
||||||
|
A PARTY OF SECTION 10 (CONFIDENTIAL INFORMATION), AND (iii) INFRINGEMENT BY A PARTY OF THE OTHER PARTY’S
|
||||||
|
INTELLECTUAL PROPERTY RIGHTS (COLLECTIVELY EXCLUSIONS (i)-(iii) ARE REFERRED TO AS THE “EXCLUDED CLAIMS”). WITH
|
||||||
|
RESPECT TO ANY EXCLUDED CLAIMS, MEMGRAPH’S TOTAL AGGREGATE LIABILITY SHALL IN NO EVENT EXCEED £1,000,000.
|
||||||
|
9.3. Nothing in this Agreement excludes the liability of Memgraph for death or personal injury caused by the
|
||||||
|
Supplier’s negligence; or for fraud or fraudulent misrepresentation.
|
||||||
|
|
||||||
|
10. CONFIDENTIALITY.
|
||||||
|
10.1. The Receiving Party will use the same degree of care that it uses to protect the confidentiality of its own
|
||||||
|
confidential information of like kind (but not less than reasonable care) to (i) not use any confidential
|
||||||
|
information of the Disclosing Party for any purpose outside the scope of this agreement and (ii) except as
|
||||||
|
otherwise authorized by the Disclosing Party in writing, limit access to confidential information of the
|
||||||
|
Disclosing Party to those of its and its affiliates’ employees and contractors who need that access for
|
||||||
|
purposes consistent with this agreement and who have signed confidentiality agreements with the receiving party
|
||||||
|
containing protections not materially less protective of the confidential information than those herein.
|
||||||
|
Neither party will disclose the terms of this agreement or any Orders to any third-party other than its
|
||||||
|
affiliates, legal counsel, and accountants without the other party’s prior written consent, provided that a
|
||||||
|
party that makes any such disclosure to its affiliate, legal counsel or accountants will remain responsible for
|
||||||
|
such affiliate’s, legal counsel’s, or accountant’s compliance with this “Confidentiality” section.
|
||||||
|
10.2. Compelled Disclosure. The Receiving Party may disclose confidential information of the Disclosing Party to the
|
||||||
|
extent compelled by law to do so, provided the Receiving Party gives the Disclosing Party prior notice of the
|
||||||
|
compelled disclosure (to the extent legally permitted) and reasonable assistance, at the Disclosing Party’s
|
||||||
|
cost, if the Disclosing Party wishes to contest the disclosure. If the receiving party is compelled by law to
|
||||||
|
disclose the Disclosing Party’s confidential information as part of a civil proceeding to which the Disclosing
|
||||||
|
Party is a party, and the Disclosing Party is not contesting the disclosure, the Disclosing Party will
|
||||||
|
reimburse the Receiving Party for its reasonable cost of complying and providing secure access to that
|
||||||
|
confidential information.
|
||||||
|
|
||||||
|
|
||||||
|
11. TERMINATION.
|
||||||
|
11.1. Term. The term (“Term”) of this Agreement will commence on the Effective Date and continue until all
|
||||||
|
Subscriptions, licence terms and Orders expire, unless earlier terminated in accordance with this Section 11.
|
||||||
|
11.2. Termination for Cause. In the event of a material breach of this Agreement (excluding any breaches for which an
|
||||||
|
exclusive remedy is expressly provided), the non-breaching party may terminate this Agreement if such breach
|
||||||
|
is not cured within thirty (30) days after written notice thereof (except that for a breach of Section 3.5
|
||||||
|
(“General Restrictions”), there will be no cure period). For clarity, material breach of this Agreement
|
||||||
|
includes, but is not limited to, failure to timely pay amounts due hereunder, exceeding the scope of any
|
||||||
|
Licence granted hereunder (including the Licensed Capacity), violating the Licence restrictions, breach of
|
||||||
|
Section 6.1 and failing to protect the other party’s Confidential Information.
|
||||||
|
11.3. Without affecting any other right or remedy available to it, and to the fullest extent permitted by applicable
|
||||||
|
law, either party may terminate this Agreement with immediate effect by giving written notice to the other
|
||||||
|
party if the other party:
|
||||||
|
11.3.1. suspends, or threatens to suspend, payment of its debts or is unable to pay its debts as they fall due or
|
||||||
|
admits inability to pay its debts or is deemed unable to pay its debts within the meaning of section 123
|
||||||
|
of the Insolvency Act 1986, as if the words “it is proved to the satisfaction of the court” did not
|
||||||
|
appear in sections 123(1)(e) or 123(2) of the Insolvency Act 1986; or
|
||||||
|
11.3.2. the other party commences negotiations with all or any class of its creditors with a view to rescheduling
|
||||||
|
any of its debts, or makes a proposal for or enters into any compromise or arrangement with its creditors
|
||||||
|
other than for the sole purpose of a scheme for a solvent amalgamation of that other party with one or
|
||||||
|
more other companies or the solvent reconstruction of that other party; or
|
||||||
|
11.3.3. a petition is filed, a notice is given, a resolution is passed, or an order is made, for or in connection
|
||||||
|
with the winding up of that other party other than for the sole purpose of a scheme for a solvent
|
||||||
|
amalgamation of that other party with one or more other companies or the solvent reconstruction of that
|
||||||
|
other party; or
|
||||||
|
11.3.4. an application is made to court, or an order is made, for the appointment of an administrator, or if a
|
||||||
|
notice of intention to appoint an administrator is given or if an administrator is appointed, over the
|
||||||
|
other party; or
|
||||||
|
11.3.5. the holder of a qualifying floating charge over the assets of that other party has become entitled to
|
||||||
|
appoint or has appointed an administrative receiver; or
|
||||||
|
11.3.6. a person becomes entitled to appoint a receiver over the assets of the other party or a receiver is
|
||||||
|
appointed over the assets of the other party; or
|
||||||
|
11.3.7. a creditor or encumbrancer of the other party attaches or takes possession of, or a distress, execution,
|
||||||
|
sequestration or other such process is levied or enforced on or sued against, the whole or any part of
|
||||||
|
the other party’s assets and such attachment or process is not discharged within 30 days; or
|
||||||
|
11.3.8. any event occurs, or proceeding is taken, with respect to the other party in any jurisdiction to which
|
||||||
|
it is subject that has an effect equivalent or similar to any of the events mentioned in clause 11.3.1 to
|
||||||
|
clause 11.3.7 (inclusive); or
|
||||||
|
11.3.9. the other party suspends or ceases, or threatens to suspend or cease, carrying on all or a substantial
|
||||||
|
part of its business.
|
||||||
|
11.4. Effect of Termination. Upon the termination of this Agreement: (i) all licences will terminate; (ii) Customer
|
||||||
|
will immediately discontinue all use of the affected Software and erase all other tangible embodiments of
|
||||||
|
Memgraph Confidential Information in Customer’s possession or control, and promptly certify the same to
|
||||||
|
Memgraph; (iii) Memgraph may immediately cease providing the Services; (iv) (subject to this Section),
|
||||||
|
Memgraph will return or delete all tangible embodiments of Customer Confidential Information in Memgraph’s
|
||||||
|
possession or control; and (v) Sections 1 (“Definitions”), 3.5 (“General Restrictions”), 3.6 (“Ownership;
|
||||||
|
Reservation of Rights”), 5 (“Fees and Payment”), 7.3 (“Limitations”), 7.4 (“Disclaimer”), 8
|
||||||
|
(“Indemnification”), 9 (“Limitation of Liability”), 10 (“Confidentiality”), 11.4 (“Effect of Termination”),
|
||||||
|
and 12 (“Miscellaneous”) will survive. If a party’s file retention policies or a valid legal order provides
|
||||||
|
for backup or archival copies of files to be retained, such party will notify the other party of such policy
|
||||||
|
or order, protect the other party’s Confidential Information as required hereunder, and permanently erase,
|
||||||
|
delete, or destroy such Confidential Information as soon as permissible under such policy or order.
|
||||||
|
|
||||||
|
12. MISCELLANEOUS.
|
||||||
|
12.1. Assignment. This Agreement will bind and inure to the benefit of each party’s permitted successors and assigns.
|
||||||
|
Memgraph may assign this Agreement to any affiliate or in connection with a merger, reorganization,
|
||||||
|
acquisition, or other transfer of all or substantially all of Memgraph’s assets or voting securities. Customer
|
||||||
|
may not assign or transfer this Agreement, in whole or in part, without Memgraph’s written consent except that
|
||||||
|
Customer may assign its rights and obligations under this Agreement, in whole but not in part, without
|
||||||
|
Memgraph’s written consent in connection with any merger, consolidation, sale of all or substantially all of
|
||||||
|
Customer’s assets or voting stock, or any other similar transaction provided that: (i) the assignee is not a
|
||||||
|
direct competitor of Memgraph; (ii) Customer provides prompt written notice of such assignment to Memgraph;
|
||||||
|
(iii) the assignee is capable of fully performing Customer’s obligations under this Agreement; and (iv) the
|
||||||
|
assignee agrees to be bound by the terms and conditions of this Agreement. Any attempt to transfer or assign
|
||||||
|
this Agreement without such written consent will be null and void.Force Majeure. Memgraph shall have no
|
||||||
|
liability to the Customer under this Agreement if it is prevented from or delayed in performing its obligations
|
||||||
|
under this Agreement, or from carrying on its business, by acts, events, omissions or accidents beyond its
|
||||||
|
reasonable control, including strikes, lock-outs or other industrial disputes (whether involving the workforce
|
||||||
|
of Memgraph or any other party), failure of a utility service or transport or telecommunications network, act
|
||||||
|
of God, war, pandemic, riot, civil commotion, malicious damage, compliance with any law or governmental order,
|
||||||
|
rule, regulation or direction, accident, breakdown of plant or machinery, fire, flood, storm or default of
|
||||||
|
suppliers or subcontractors, provided that the Customer is notified of such an event and its expected duration.
|
||||||
|
12.2. Governing Law. This Agreement and any dispute or claim arising out of or in connection with it or its subject
|
||||||
|
matter or formation (including non-contractual disputes or claims) shall be governed by and construed in
|
||||||
|
accordance with the law of England and Wales.
|
||||||
|
12.3. Jurisdiction. Each party irrevocably agrees that the courts of England and Wales shall have exclusive
|
||||||
|
jurisdiction to settle any dispute or claim arising out of or in connection with this Agreement or its subject
|
||||||
|
matter or formation (including non-contractual disputes or claims).
|
||||||
|
12.4. Severability; Waiver; Construction. If a court of competent jurisdiction adjudges any provision of this
|
||||||
|
Agreement to be invalid or unenforceable, the remaining provisions of this Agreement, if capable of substantial
|
||||||
|
performance, will continue in full force and effect without being impaired or invalidated in any way. The
|
||||||
|
parties agree to replace any invalid provision with a valid provision that most closely approximates the intent
|
||||||
|
and economic effect of the invalid provision. All waivers must be in writing. A party’s consent to, or waiver
|
||||||
|
of, enforcement of this Agreement on one occasion will not be deemed a waiver of any other provision or such
|
||||||
|
provision on any other occasion. In this Agreement, the word “including” means “including but not limited to.”
|
||||||
|
No presumption will operate in favour of or against any party as a result of its role in drafting this
|
||||||
|
Agreement.
|
||||||
|
12.5. Subcontractors. Memgraph may use the services of subcontractors in connection with its performance of this
|
||||||
|
Agreement, provided that Memgraph remains solely responsible for (i) compliance of any such subcontractor with
|
||||||
|
the terms of this Agreement and (ii) the overall performance of Memgraph as required under this Agreement.
|
||||||
|
12.6. Use of Aggregate Data. Customer agrees that Memgraph may collect, use and disclose quantitative data and
|
||||||
|
metadata derived from the use of the Software (i) for its own internal, statistical analysis, (ii) to develop
|
||||||
|
and improve the Software and (iii) to create and distribute reports and other materials regarding use of the
|
||||||
|
Software. For clarity, any such data collected, used, and disclosed will be in anonymized aggregate form only
|
||||||
|
and shall not identify Customer or its Users, or disclose any Customer Data.Independent Contractors. The
|
||||||
|
parties are independent contractors. No agency, partnership, franchise, joint venture, or employment
|
||||||
|
relationship is intended or created by this Agreement. Neither party has the power or authority to create or
|
||||||
|
assume any obligation, or make any representations or warranties, on behalf of the other party.
|
||||||
|
12.7. Publicity. Memgraph may, in conformity with Customer’s trademark usage guidelines, use Customer’s name and logo
|
||||||
|
in Memgraph’s sales and marketing materials, including in business presentations, Customer lists, and on
|
||||||
|
websites. Neither party will issue a press release regarding this Agreement without the other party’s prior
|
||||||
|
written consent. Neither party will disclose the terms of this Agreement to any third party, except as required
|
||||||
|
by law.
|
||||||
|
12.8. Notice. Any notice, consent, or waiver hereunder must be in writing, addressed to the attention of “Legal
|
||||||
|
Department” at the address set forth above, and delivered by personal delivery, reputable rapid courier, or
|
||||||
|
certified/registered mail, return receipt requested, and will be deemed given upon personal delivery, one (1)
|
||||||
|
day after deposit with an overnight domestic courier, two (2) days after deposit with an international courier,
|
||||||
|
or five (5) days after deposit in the certified or registered mail. A party may specify a new address by
|
||||||
|
providing notice to the other party in accordance with this Section.
|
||||||
|
12.9. Compliance with Law. Each party will comply with all applicable laws, regulations, and orders of any
|
||||||
|
governmental authority of competent jurisdiction in its performance under this Agreement, including but not
|
||||||
|
limited to those applicable to data collection and the privacy and security of personal information, including
|
||||||
|
trans-border data transfers and data breach notification requirements as required of each party by law.
|
||||||
|
12.10.Supremacy; Modification. This Agreement will prevail over any written instrument submitted by Customer; the
|
||||||
|
terms of any purchase order, acknowledgement, or similar document submitted by Customer to Memgraph will have
|
||||||
|
no effect. If the express terms of an Order Document conflict with this Agreement, the terms on the Order
|
||||||
|
Document will prevail, but only with respect to that Order Document. This Agreement cannot be varied or
|
||||||
|
supplemented by course of dealing or by usage of trade. All modifications or amendments to this Agreement must
|
||||||
|
be in writing and signed by both parties, except that subsequent renewals and purchases of additional Licensed
|
||||||
|
Capacity can be procured by payment against an issued invoice as set forth in Section 5 (“Fees and Payment”)
|
||||||
|
above.
|
||||||
|
12.11.No Third Party Beneficiaries. This Agreement is not intended and shall not be construed to give any third party
|
||||||
|
any interest or rights with respect to or in connection with any agreement or provision herein, except as
|
||||||
|
expressly provided for in this Agreement.
|
||||||
|
12.12.Entire Agreement. This Agreement in its original English text, sets forth the complete, exclusive, and final
|
||||||
|
agreement of the parties concerning the subject matter hereof, supersedes, replaces, and merges all prior and
|
||||||
|
contemporaneous agreements, communications, and understandings, both
|
||||||
|
written and oral, between them concerning the subject matter hereof. This Agreement may be executed in
|
||||||
|
counterparts.
|
||||||
52
licenses/third-party/antlr/LICENSE.txt
vendored
Normal file
52
licenses/third-party/antlr/LICENSE.txt
vendored
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
[The "BSD 3-clause license"]
|
||||||
|
Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
3. Neither the name of the copyright holder nor the names of its contributors
|
||||||
|
may be used to endorse or promote products derived from this software
|
||||||
|
without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
=====
|
||||||
|
|
||||||
|
MIT License for codepointat.js from https://git.io/codepointat
|
||||||
|
MIT License for fromcodepoint.js from https://git.io/vDW1m
|
||||||
|
|
||||||
|
Copyright Mathias Bynens <https://mathiasbynens.be/>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
42
licenses/third-party/bzip2/LICENSE
vendored
Normal file
42
licenses/third-party/bzip2/LICENSE
vendored
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
This program, "bzip2", the associated library "libbzip2", and all
|
||||||
|
documentation, are copyright (C) 1996-2010 Julian R Seward. All
|
||||||
|
rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. The origin of this software must not be misrepresented; you must
|
||||||
|
not claim that you wrote the original software. If you use this
|
||||||
|
software in a product, an acknowledgment in the product
|
||||||
|
documentation would be appreciated but is not required.
|
||||||
|
|
||||||
|
3. Altered source versions must be plainly marked as such, and must
|
||||||
|
not be misrepresented as being the original software.
|
||||||
|
|
||||||
|
4. The name of the author may not be used to endorse or promote
|
||||||
|
products derived from this software without specific prior written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||||
|
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||||
|
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
Julian Seward, jseward@bzip.org
|
||||||
|
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
23
licenses/third-party/cppitertools/LICENSE.md
vendored
Normal file
23
licenses/third-party/cppitertools/LICENSE.md
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
Copyright (c) 2013, Ryan Haining, Aaron Josephs, Google
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
27
licenses/third-party/fmt/LICENSE.rst
vendored
Normal file
27
licenses/third-party/fmt/LICENSE.rst
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2012 - present, Victor Zverovich
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
--- Optional exception to the license ---
|
||||||
|
|
||||||
|
As an exception, if, as a result of your compiling your source code, portions
|
||||||
|
of this Software are embedded into a machine-executable object form of such
|
||||||
|
source code, you may redistribute such embedded portions in such object form
|
||||||
|
without including the above copyright and permission notices.
|
||||||
28
licenses/third-party/gflags/COPYING.txt
vendored
Normal file
28
licenses/third-party/gflags/COPYING.txt
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
Copyright (c) 2006, Google Inc.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
27
licenses/third-party/jemalloc/COPYING
vendored
Normal file
27
licenses/third-party/jemalloc/COPYING
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
Unless otherwise specified, files in the jemalloc source distribution are
|
||||||
|
subject to the following license:
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2002-present Jason Evans <jasone@canonware.com>.
|
||||||
|
All rights reserved.
|
||||||
|
Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved.
|
||||||
|
Copyright (C) 2009-present Facebook, Inc. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright notice(s),
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice(s),
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS
|
||||||
|
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user