Compare commits
2 Commits
MG-pmr-pro
...
T0785-MG-b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ebe54d759e | ||
|
|
492a13d5e7 |
@@ -2,7 +2,6 @@
|
||||
Checks: '*,
|
||||
-abseil-string-find-str-contains,
|
||||
-altera-struct-pack-align,
|
||||
-altera-unroll-loops,
|
||||
-android-*,
|
||||
-cert-err58-cpp,
|
||||
-cppcoreguidelines-avoid-c-arrays,
|
||||
|
||||
@@ -32,7 +32,7 @@ for file in $modified_files; do
|
||||
fi
|
||||
|
||||
echo "Running header checker..."
|
||||
$project_folder/tools/header-checker.py $tmpdir/$file $file --amend-year
|
||||
$project_folder/tools/header-checker.py $tmpdir/$file
|
||||
code=$?
|
||||
|
||||
if [ $code -ne 0 ]; then
|
||||
|
||||
2
.github/workflows/daily_benchmark.yaml
vendored
2
.github/workflows/daily_benchmark.yaml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
- name: Build release binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
|
||||
28
.github/workflows/diff.yaml
vendored
28
.github/workflows/diff.yaml
vendored
@@ -32,7 +32,7 @@ jobs:
|
||||
- name: Build community binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -45,7 +45,7 @@ jobs:
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
- name: Build combined ASAN, UBSAN and coverage binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -82,7 +82,7 @@ jobs:
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run unit tests. It is restricted to 2 threads intentionally, because higher concurrency makes the timing related tests unstable.
|
||||
cd build
|
||||
@@ -91,7 +91,7 @@ jobs:
|
||||
- name: Compute code coverage
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Compute code coverage.
|
||||
cd tools/github
|
||||
@@ -109,7 +109,7 @@ jobs:
|
||||
|
||||
- name: Run clang-tidy
|
||||
run: |
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Restrict clang-tidy results only to the modified parts
|
||||
git diff -U0 master... -- src ':!*.hpp' | ./tools/github/clang-tidy/clang-tidy-diff.py -p 1 -j $THREADS -path build | tee ./build/clang_tidy_output.txt
|
||||
@@ -136,7 +136,7 @@ jobs:
|
||||
- name: Build debug binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -149,7 +149,7 @@ jobs:
|
||||
- name: Run leftover CTest tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run leftover CTest tests (all except unit and benchmark tests).
|
||||
cd build
|
||||
@@ -181,7 +181,7 @@ jobs:
|
||||
- name: Run cppcheck and clang-format
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run cppcheck and clang-format.
|
||||
cd tools/github
|
||||
@@ -212,7 +212,7 @@ jobs:
|
||||
- name: Build release binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -238,7 +238,7 @@ jobs:
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
@@ -272,7 +272,7 @@ jobs:
|
||||
- name: Create enterprise DEB package
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
cd build
|
||||
|
||||
@@ -319,7 +319,7 @@ jobs:
|
||||
- name: Build release binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -360,7 +360,7 @@ jobs:
|
||||
- name: Build release binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
|
||||
6
.github/workflows/full_clang_tidy.yaml
vendored
6
.github/workflows/full_clang_tidy.yaml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
- name: Build debug binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -36,10 +36,10 @@ jobs:
|
||||
|
||||
- name: Run clang-tidy
|
||||
run: |
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/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 -clang-tidy-binary=/opt/toolchain-v4/bin/clang-tidy "$PWD/src/*" |
|
||||
./tools/github/clang-tidy/run-clang-tidy.py -p build -j $THREADS -clang-tidy-binary=/opt/toolchain-v3/bin/clang-tidy "$PWD/src/*" |
|
||||
tee ./build/full_clang_tidy_output.txt
|
||||
|
||||
- name: Summarize clang-tidy results
|
||||
|
||||
17
.github/workflows/package_all.yaml
vendored
17
.github/workflows/package_all.yaml
vendored
@@ -39,6 +39,23 @@ jobs:
|
||||
name: centos-8
|
||||
path: build/output/centos-8/memgraph*.rpm
|
||||
|
||||
debian-9:
|
||||
runs-on: [self-hosted, DockerMgBuild]
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: "Set up repository"
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0 # Required because of release/get_version.py
|
||||
- name: "Build package"
|
||||
run: |
|
||||
./release/package/run.sh package debian-9
|
||||
- name: "Upload package"
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: debian-9
|
||||
path: build/output/debian-9/memgraph*.deb
|
||||
|
||||
debian-10:
|
||||
runs-on: [self-hosted, DockerMgBuild]
|
||||
timeout-minutes: 60
|
||||
|
||||
24
.github/workflows/release_centos8.yaml
vendored
24
.github/workflows/release_centos8.yaml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
- name: Build community binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
- name: Build coverage binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -77,7 +77,7 @@ jobs:
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
@@ -86,7 +86,7 @@ jobs:
|
||||
- name: Compute code coverage
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Compute code coverage.
|
||||
cd tools/github
|
||||
@@ -121,7 +121,7 @@ jobs:
|
||||
- name: Build debug binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -134,7 +134,7 @@ jobs:
|
||||
- name: Run leftover CTest tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run leftover CTest tests (all except unit and benchmark tests).
|
||||
cd build
|
||||
@@ -166,7 +166,7 @@ jobs:
|
||||
- name: Run cppcheck and clang-format
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run cppcheck and clang-format.
|
||||
cd tools/github
|
||||
@@ -198,7 +198,7 @@ jobs:
|
||||
- name: Build release binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -211,7 +211,7 @@ jobs:
|
||||
- name: Create enterprise RPM package
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
cd build
|
||||
|
||||
@@ -233,7 +233,7 @@ jobs:
|
||||
- name: Run micro benchmark tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run micro benchmark tests.
|
||||
cd build
|
||||
@@ -272,7 +272,7 @@ jobs:
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
|
||||
26
.github/workflows/release_debian10.yaml
vendored
26
.github/workflows/release_debian10.yaml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
- name: Build community binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
- name: Build coverage binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -77,7 +77,7 @@ jobs:
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
@@ -86,7 +86,7 @@ jobs:
|
||||
- name: Compute code coverage
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Compute code coverage.
|
||||
cd tools/github
|
||||
@@ -121,7 +121,7 @@ jobs:
|
||||
- name: Build debug binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -134,7 +134,7 @@ jobs:
|
||||
- name: Run leftover CTest tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run leftover CTest tests (all except unit and benchmark tests).
|
||||
cd build
|
||||
@@ -166,7 +166,7 @@ jobs:
|
||||
- name: Run cppcheck and clang-format
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run cppcheck and clang-format.
|
||||
cd tools/github
|
||||
@@ -198,7 +198,7 @@ jobs:
|
||||
- name: Build release binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -211,7 +211,7 @@ jobs:
|
||||
- name: Create enterprise DEB package
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
cd build
|
||||
|
||||
@@ -232,7 +232,7 @@ jobs:
|
||||
- name: Run micro benchmark tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run micro benchmark tests.
|
||||
cd build
|
||||
@@ -271,7 +271,7 @@ jobs:
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
@@ -333,7 +333,7 @@ jobs:
|
||||
- name: Build release binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
|
||||
24
.github/workflows/release_ubuntu2004.yaml
vendored
24
.github/workflows/release_ubuntu2004.yaml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
- name: Build community binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
- name: Build coverage binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -77,7 +77,7 @@ jobs:
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
@@ -86,7 +86,7 @@ jobs:
|
||||
- name: Compute code coverage
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Compute code coverage.
|
||||
cd tools/github
|
||||
@@ -121,7 +121,7 @@ jobs:
|
||||
- name: Build debug binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -134,7 +134,7 @@ jobs:
|
||||
- name: Run leftover CTest tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run leftover CTest tests (all except unit and benchmark tests).
|
||||
cd build
|
||||
@@ -166,7 +166,7 @@ jobs:
|
||||
- name: Run cppcheck and clang-format
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run cppcheck and clang-format.
|
||||
cd tools/github
|
||||
@@ -198,7 +198,7 @@ jobs:
|
||||
- name: Build release binaries
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Initialize dependencies.
|
||||
./init
|
||||
@@ -211,7 +211,7 @@ jobs:
|
||||
- name: Create enterprise DEB package
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
cd build
|
||||
|
||||
@@ -232,7 +232,7 @@ jobs:
|
||||
- name: Run micro benchmark tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run micro benchmark tests.
|
||||
cd build
|
||||
@@ -271,7 +271,7 @@ jobs:
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
# Activate toolchain.
|
||||
source /opt/toolchain-v4/activate
|
||||
source /opt/toolchain-v3/activate
|
||||
|
||||
# Run unit tests.
|
||||
cd build
|
||||
|
||||
@@ -228,8 +228,6 @@ endif()
|
||||
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 -------------------------------------------------
|
||||
|
||||
# threading
|
||||
@@ -324,8 +322,7 @@ if (UBSAN)
|
||||
# To make the program abort on undefined behavior, use UBSAN_OPTIONS=halt_on_error=1.
|
||||
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")
|
||||
set(MG_PYTHON_VERSION "" CACHE STRING "Specify the exact python version used by the query modules")
|
||||
|
||||
# Add subprojects
|
||||
include_directories(src)
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
# 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
|
||||
)
|
||||
@@ -14,14 +14,9 @@ TOOLCHAIN_BUILD_DEPS=(
|
||||
expat-devel libipt-devel libbabeltrace-devel xz-devel python3-devel # gdb
|
||||
texinfo # gdb
|
||||
libcurl-devel # cmake
|
||||
curl # snappy
|
||||
readline-devel # cmake and llvm
|
||||
libffi-devel libxml2-devel perl-Digest-MD5 # llvm
|
||||
libedit-devel pcre-devel automake bison # swig
|
||||
file
|
||||
openssl-devel
|
||||
gmp-devel
|
||||
gperf
|
||||
)
|
||||
|
||||
TOOLCHAIN_RUN_DEPS=(
|
||||
@@ -31,10 +26,10 @@ TOOLCHAIN_RUN_DEPS=(
|
||||
expat libipt libbabeltrace xz-libs python3 # for gdb
|
||||
readline # for cmake and llvm
|
||||
libffi libxml2 # for llvm
|
||||
openssl-devel
|
||||
)
|
||||
|
||||
MEMGRAPH_BUILD_DEPS=(
|
||||
git # source code control
|
||||
make pkgconfig # build system
|
||||
curl wget # for downloading libs
|
||||
libuuid-devel java-11-openjdk # required by antlr
|
||||
@@ -100,12 +95,8 @@ install() {
|
||||
echo "NOTE: export LANG=en_US.utf8"
|
||||
fi
|
||||
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 install -y wget python3 python3-pip
|
||||
yum install -y git224
|
||||
yum install -y wget git python3 python3-pip
|
||||
for pkg in $1; do
|
||||
if [ "$pkg" == libipt ]; then
|
||||
if ! yum list installed libipt >/dev/null 2>/dev/null; then
|
||||
|
||||
@@ -13,14 +13,9 @@ TOOLCHAIN_BUILD_DEPS=(
|
||||
zlib-devel # zlib library used for all builds
|
||||
expat-devel libipt-devel libbabeltrace-devel xz-devel python36-devel texinfo # for gdb
|
||||
libcurl-devel # for cmake
|
||||
curl # snappy
|
||||
readline-devel # for cmake and llvm
|
||||
libffi-devel libxml2-devel # for llvm
|
||||
libedit-devel pcre-devel automake bison # for swig
|
||||
file
|
||||
openssl-devel
|
||||
gmp-devel
|
||||
gperf
|
||||
)
|
||||
|
||||
TOOLCHAIN_RUN_DEPS=(
|
||||
@@ -30,7 +25,6 @@ TOOLCHAIN_RUN_DEPS=(
|
||||
expat libipt libbabeltrace xz-libs python36 # for gdb
|
||||
readline # for cmake and llvm
|
||||
libffi libxml2 # for llvm
|
||||
openssl-devel
|
||||
)
|
||||
|
||||
MEMGRAPH_BUILD_DEPS=(
|
||||
|
||||
@@ -1,139 +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 gcc-c++ make # generic build tools
|
||||
wget # used for archive download
|
||||
gnupg2 # used for archive signature verification
|
||||
tar gzip bzip2 xz unzip # used for archive unpacking
|
||||
zlib-devel # zlib library used for all builds
|
||||
expat-devel xz-devel python3-devel texinfo # for gdb
|
||||
libcurl-devel # for cmake
|
||||
curl # snappy
|
||||
readline-devel # for cmake and llvm
|
||||
libffi-devel libxml2-devel # for llvm
|
||||
libedit-devel pcre-devel automake bison # for swig
|
||||
file
|
||||
openssl-devel
|
||||
gmp-devel
|
||||
gperf
|
||||
)
|
||||
|
||||
TOOLCHAIN_RUN_DEPS=(
|
||||
make # generic build tools
|
||||
tar gzip bzip2 xz # used for archive unpacking
|
||||
zlib # zlib library used for all builds
|
||||
expat xz-libs python3 # for gdb
|
||||
readline # for cmake and llvm
|
||||
libffi libxml2 # for llvm
|
||||
openssl-devel
|
||||
)
|
||||
|
||||
MEMGRAPH_BUILD_DEPS=(
|
||||
git # source code control
|
||||
make pkgconf-pkg-config # build system
|
||||
curl wget # for downloading libs
|
||||
libuuid-devel java-11-openjdk # required by antlr
|
||||
readline-devel # for memgraph console
|
||||
python3-devel # for query modules
|
||||
openssl-devel
|
||||
libseccomp-devel
|
||||
python3 python3-virtualenv python3-pip nmap-ncat # for qa, macro_benchmark and stress tests
|
||||
#
|
||||
# IMPORTANT: python3-yaml does NOT exist on CentOS
|
||||
# Install it manually using `pip3 install PyYAML`
|
||||
#
|
||||
PyYAML # Package name here does not correspond to the yum package!
|
||||
libcurl-devel # mg-requests
|
||||
rpm-build rpmlint # for RPM package building
|
||||
doxygen graphviz # source documentation generators
|
||||
which nodejs golang zip unzip java-11-openjdk-devel # for driver tests
|
||||
sbcl # for custom Lisp C++ preprocessing
|
||||
autoconf # for jemalloc code generation
|
||||
libtool # for protobuf code generation
|
||||
)
|
||||
|
||||
list() {
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
check() {
|
||||
local missing=""
|
||||
for pkg in $1; do
|
||||
if [ "$pkg" == "PyYAML" ]; then
|
||||
if ! python3 -c "import yaml" >/dev/null 2>/dev/null; then
|
||||
missing="$pkg $missing"
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
if [ "$pkg" == "python3-virtualenv" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ "$pkg" == sbcl ]; then
|
||||
if ! sbcl --version &> /dev/null; then
|
||||
missing="$pkg $missing"
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
if ! yum list installed "$pkg" >/dev/null 2>/dev/null; then
|
||||
missing="$pkg $missing"
|
||||
fi
|
||||
done
|
||||
if [ "$missing" != "" ]; then
|
||||
echo "MISSING PACKAGES: $missing"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
install() {
|
||||
cd "$DIR"
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "Please run as root."
|
||||
exit 1
|
||||
fi
|
||||
# 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
|
||||
yum update -y
|
||||
yum install -y wget git python3 python3-pip
|
||||
for pkg in $1; do
|
||||
if [ "$pkg" == sbcl ]; then
|
||||
if ! sbcl --version &> /dev/null; then
|
||||
curl -s https://altushost-swe.dl.sourceforge.net/project/sbcl/sbcl/1.4.2/sbcl-1.4.2-arm64-linux-binary.tar.bz2 -o /tmp/sbcl-arm64.tar.bz2
|
||||
tar xvjf /tmp/sbcl-arm64.tar.bz2 -C /tmp
|
||||
pushd /tmp/sbcl-1.4.2-arm64-linux
|
||||
INSTALL_ROOT=/usr/local sh install.sh
|
||||
popd
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
if [ "$pkg" == PyYAML ]; then
|
||||
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
|
||||
fi
|
||||
if [ "$pkg" == python3-virtualenv ]; then
|
||||
if [ -z ${SUDO_USER+x} ]; then # Running as root (e.g. Docker).
|
||||
pip3 install --user virtualenv
|
||||
else # Running using sudo.
|
||||
sudo -H -u "$SUDO_USER" bash -c "pip3 install --user virtualenv"
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
yum install -y "$pkg"
|
||||
done
|
||||
}
|
||||
|
||||
deps=$2"[*]"
|
||||
"$1" "${!deps}"
|
||||
@@ -15,12 +15,6 @@ TOOLCHAIN_BUILD_DEPS=(
|
||||
libcurl4-openssl-dev # for cmake
|
||||
libreadline-dev # for cmake and 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
|
||||
)
|
||||
|
||||
@@ -32,7 +26,6 @@ TOOLCHAIN_RUN_DEPS=(
|
||||
libcurl4 # for cmake
|
||||
libreadline7 # for cmake and llvm
|
||||
libffi6 libxml2 # for llvm
|
||||
libssl-dev # for libevent
|
||||
)
|
||||
|
||||
MEMGRAPH_BUILD_DEPS=(
|
||||
|
||||
@@ -16,12 +16,6 @@ TOOLCHAIN_BUILD_DEPS=(
|
||||
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=(
|
||||
@@ -33,7 +27,6 @@ TOOLCHAIN_RUN_DEPS=(
|
||||
file # for CPack
|
||||
libreadline8 # for cmake and llvm
|
||||
libffi7 libxml2 # for llvm
|
||||
libssl-dev # for libevent
|
||||
)
|
||||
|
||||
MEMGRAPH_BUILD_DEPS=(
|
||||
|
||||
63
environment/os/debian-9.sh
Executable file
63
environment/os/debian-9.sh
Executable file
@@ -0,0 +1,63 @@
|
||||
#!/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
|
||||
autoconf # for jemalloc code generation
|
||||
libtool # for protobuf code generation
|
||||
)
|
||||
|
||||
list() {
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
check() {
|
||||
check_all_dpkg "$1"
|
||||
}
|
||||
|
||||
install() {
|
||||
install_all_apt "$1"
|
||||
}
|
||||
|
||||
deps=$2"[*]"
|
||||
"$1" "${!deps}"
|
||||
@@ -16,12 +16,6 @@ TOOLCHAIN_BUILD_DEPS=(
|
||||
libcurl4-openssl-dev # cmake
|
||||
libreadline-dev # cmake and 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
|
||||
)
|
||||
|
||||
@@ -33,7 +27,6 @@ TOOLCHAIN_RUN_DEPS=(
|
||||
libcurl4 # for cmake
|
||||
libreadline7 # for cmake and llvm
|
||||
libffi6 libxml2 # for llvm
|
||||
libssl-dev # for libevent
|
||||
)
|
||||
|
||||
MEMGRAPH_BUILD_DEPS=(
|
||||
|
||||
@@ -15,12 +15,6 @@ TOOLCHAIN_BUILD_DEPS=(
|
||||
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
|
||||
)
|
||||
|
||||
@@ -32,7 +26,6 @@ TOOLCHAIN_RUN_DEPS=(
|
||||
libcurl4 # for cmake
|
||||
libreadline8 # for cmake and llvm
|
||||
libffi7 libxml2 # for llvm
|
||||
libssl-dev # for libevent
|
||||
)
|
||||
|
||||
MEMGRAPH_BUILD_DEPS=(
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
31d30
|
||||
< add_subdirectory(logging/example)
|
||||
@@ -1,2 +0,0 @@
|
||||
24d23
|
||||
< find_dependency(mvfst)
|
||||
@@ -1,16 +0,0 @@
|
||||
55,57c55,57
|
||||
< # 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-")
|
||||
80,82c80,82
|
||||
< # 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")
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,75 +0,0 @@
|
||||
-----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-----
|
||||
59
init
59
init
@@ -10,8 +10,6 @@ function print_help () {
|
||||
echo -e "Check for missing packages and setup the project.\n"
|
||||
echo "Optional arguments:"
|
||||
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 () {
|
||||
@@ -32,36 +30,21 @@ function setup_virtualenv () {
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
wsl_quicklisp_proxy=""
|
||||
setup_libs=true
|
||||
if [[ $# -eq 1 && "$1" == "-h" ]]; then
|
||||
if [[ $# -gt 1 ]]; then
|
||||
print_help
|
||||
exit 0
|
||||
else
|
||||
while(($#)); do
|
||||
case "$1" in
|
||||
--wsl-quicklisp-proxy)
|
||||
shift
|
||||
if [[ $# -eq 0 ]]; then
|
||||
echo "Missing proxy URL"
|
||||
print_help
|
||||
exit 1
|
||||
fi
|
||||
wsl_quicklisp_proxy=":proxy \"http://$1/\""
|
||||
shift
|
||||
;;
|
||||
--without-libs-setup)
|
||||
shift
|
||||
setup_libs=false
|
||||
;;
|
||||
*)
|
||||
# unknown option
|
||||
echo "Invalid argument provided: $1"
|
||||
print_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
exit 1
|
||||
elif [[ $# -eq 1 ]]; then
|
||||
case "$1" in
|
||||
-h)
|
||||
print_help
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
# unknown option
|
||||
print_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
DISTRO=$(operating_system)
|
||||
@@ -83,7 +66,7 @@ if [[ ! -f "${quicklisp_install_dir}/setup.lisp" ]]; then
|
||||
echo \
|
||||
"
|
||||
(load \"${DIR}/quicklisp.lisp\")
|
||||
(quicklisp-quickstart:install $wsl_quicklisp_proxy :path \"${quicklisp_install_dir}\")
|
||||
(quicklisp-quickstart:install :path \"${quicklisp_install_dir}\")
|
||||
" | sbcl --script || exit 1
|
||||
rm -rf quicklisp.lisp || exit 1
|
||||
fi
|
||||
@@ -97,13 +80,11 @@ echo \
|
||||
(ql:quickload '(:lcp :lcp/test) :silent t)
|
||||
" | sbcl --script
|
||||
|
||||
if [[ "$setup_libs" == "true" ]]; then
|
||||
# Setup libs (download).
|
||||
cd libs
|
||||
./cleanup.sh
|
||||
./setup.sh
|
||||
cd ..
|
||||
fi
|
||||
# Setup libs (download).
|
||||
cd libs
|
||||
./cleanup.sh
|
||||
./setup.sh
|
||||
cd ..
|
||||
|
||||
# setup gql_behave dependencies
|
||||
setup_virtualenv tests/gql_behave
|
||||
|
||||
@@ -8,15 +8,6 @@ if (NPROC EQUAL 0)
|
||||
set(NPROC 1)
|
||||
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
|
||||
@@ -111,13 +102,19 @@ import_external_library(antlr4 STATIC
|
||||
|
||||
# Setup google benchmark.
|
||||
import_external_library(benchmark STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/benchmark/${CMAKE_INSTALL_LIBDIR}/libbenchmark.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/benchmark/lib/libbenchmark.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/benchmark/include
|
||||
# Skip testing. The tests don't compile with Clang 8.
|
||||
CMAKE_ARGS -DBENCHMARK_ENABLE_TESTING=OFF)
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
# setup fmt format
|
||||
FetchContent_Declare(fmt
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/fmt)
|
||||
|
||||
FetchContent_MakeAvailable(fmt)
|
||||
|
||||
# setup rapidcheck (it cannot be external, since it doesn't have install
|
||||
# target)
|
||||
set(RC_ENABLE_GTEST ON CACHE BOOL "Build Google Test integration" FORCE)
|
||||
@@ -143,19 +140,58 @@ 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_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 cppitertools
|
||||
import_header_library(cppitertools ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
# Setup json
|
||||
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
|
||||
set(ZLIB_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/zlib)
|
||||
set(ZLIB_LIBRARIES ${ZLIB_ROOT}/lib/libz.a)
|
||||
set(ZLIB_INCLUDE_DIRS ${ZLIB_ROOT}/include)
|
||||
import_external_library(zlib STATIC
|
||||
${ZLIB_LIBRARIES}
|
||||
${ZLIB_INCLUDE_DIRS}
|
||||
CMAKE_ARGS -DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=true
|
||||
BUILD_COMMAND $(MAKE) zlibstatic)
|
||||
|
||||
# Setup RocksDB
|
||||
import_external_library(rocksdb STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rocksdb/lib/librocksdb.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rocksdb/include
|
||||
CMAKE_ARGS -DUSE_RTTI=ON
|
||||
DEPENDS gflags-proj
|
||||
CMAKE_ARGS -Dgflags_DIR=${CMAKE_CURRENT_SOURCE_DIR}/gflags/lib/cmake/gflags
|
||||
-DUSE_RTTI=ON
|
||||
-DWITH_TESTS=OFF
|
||||
-DGFLAGS_NOTHREADS=OFF
|
||||
-DCMAKE_INSTALL_LIBDIR=lib
|
||||
-DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=true
|
||||
BUILD_COMMAND $(MAKE) rocksdb)
|
||||
@@ -196,6 +232,8 @@ FetchContent_Declare(spdlog
|
||||
|
||||
FetchContent_MakeAvailable(spdlog)
|
||||
|
||||
include(jemalloc.cmake)
|
||||
|
||||
# Setup librdkafka.
|
||||
import_external_library(librdkafka STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/librdkafka/lib/librdkafka.a
|
||||
@@ -203,13 +241,12 @@ import_external_library(librdkafka STATIC
|
||||
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)
|
||||
target_link_libraries(librdkafka INTERFACE ${OPENSSL_LIBRARIES} zlib)
|
||||
|
||||
import_library(librdkafka++ STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/librdkafka/lib/librdkafka++.a
|
||||
@@ -224,6 +261,9 @@ import_external_library(protobuf STATIC
|
||||
BUILD_IN_SOURCE 1
|
||||
CONFIGURE_COMMAND true)
|
||||
|
||||
set(BOOST_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/boost/lib)
|
||||
set(BOOST_ROOT ${BOOST_ROOT} PARENT_SCOPE)
|
||||
|
||||
import_external_library(pulsar STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/pulsar/pulsar-client-cpp/lib/libpulsarwithdeps.a
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/pulsar/install/include
|
||||
@@ -240,18 +280,10 @@ import_external_library(pulsar STATIC
|
||||
-DBOOST_ROOT=${BOOST_ROOT}
|
||||
-DCMAKE_PREFIX_PATH=${PROTOBUF_ROOT}
|
||||
-DProtobuf_INCLUDE_DIRS=${PROTOBUF_ROOT}/include
|
||||
-DZLIB_LIBRARIES=${ZLIB_LIBRARIES}
|
||||
-DZLIB_INCLUDE_DIRS=${ZLIB_INCLUDE_DIRS}
|
||||
-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)
|
||||
add_dependencies(pulsar-proj protobuf zlib)
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
diff --git a/runtime/Cpp/runtime/CMakeLists.txt b/runtime/Cpp/runtime/CMakeLists.txt
|
||||
index a8503bb..11362cf 100644
|
||||
--- a/runtime/Cpp/runtime/CMakeLists.txt
|
||||
+++ b/runtime/Cpp/runtime/CMakeLists.txt
|
||||
@@ -5,8 +5,8 @@ set(THIRDPARTY_DIR ${CMAKE_BINARY_DIR}/runtime/thirdparty)
|
||||
set(UTFCPP_DIR ${THIRDPARTY_DIR}/utfcpp)
|
||||
ExternalProject_Add(
|
||||
utfcpp
|
||||
- GIT_REPOSITORY "git://github.com/nemtrif/utfcpp"
|
||||
- GIT_TAG "v3.1.1"
|
||||
+ GIT_REPOSITORY "https://github.com/nemtrif/utfcpp"
|
||||
+ GIT_TAG "v3.2.1"
|
||||
SOURCE_DIR ${UTFCPP_DIR}
|
||||
UPDATE_DISCONNECTED 1
|
||||
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${UTFCPP_DIR}/install -Dgtest_force_shared_crt=ON
|
||||
@@ -118,7 +118,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
|
||||
DESTINATION lib
|
||||
EXPORT antlr4-targets)
|
||||
install(TARGETS antlr4_static
|
||||
diff --git a/runtime/Cpp/runtime/src/support/Any.h b/runtime/Cpp/runtime/src/support/Any.h
|
||||
index 468db98..65a473b 100644
|
||||
--- a/runtime/Cpp/runtime/src/support/Any.h
|
||||
+++ b/runtime/Cpp/runtime/src/support/Any.h
|
||||
@@ -122,12 +122,12 @@ private:
|
||||
}
|
||||
|
||||
private:
|
||||
- template<int N = 0, typename std::enable_if<N == N && std::is_nothrow_copy_constructible<T>::value, int>::type = 0>
|
||||
+ template<int N = 0, typename std::enable_if<N == N && std::is_copy_constructible<T>::value, int>::type = 0>
|
||||
Base* clone() const {
|
||||
return new Derived<T>(value);
|
||||
}
|
||||
|
||||
- template<int N = 0, typename std::enable_if<N == N && !std::is_nothrow_copy_constructible<T>::value, int>::type = 0>
|
||||
+ template<int N = 0, typename std::enable_if<N == N && !std::is_copy_constructible<T>::value, int>::type = 0>
|
||||
Base* clone() const {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
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
|
||||
@@ -1,21 +0,0 @@
|
||||
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}"
|
||||
@@ -121,13 +121,12 @@ declare -A primary_urls=(
|
||||
["mgconsole"]="http://$local_cache_host/git/mgconsole.git"
|
||||
["spdlog"]="http://$local_cache_host/git/spdlog"
|
||||
["jemalloc"]="http://$local_cache_host/git/jemalloc.git"
|
||||
["nlohmann"]="http://$local_cache_host/file/nlohmann/json/4f8fba14066156b73f1189a2b8bd568bde5284c5/single_include/nlohmann/json.hpp"
|
||||
["nlohmann"]="http://$local_cache_host/file/nlohmann/json/b3e5cb7f20dcc5c806e418df34324eca60d17d4e/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"
|
||||
["boost"]="http://$local_cache_host/file/boost_1_77_0.tar.gz"
|
||||
["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
|
||||
@@ -152,13 +151,12 @@ declare -A secondary_urls=(
|
||||
["mgconsole"]="http://github.com/memgraph/mgconsole.git"
|
||||
["spdlog"]="https://github.com/gabime/spdlog"
|
||||
["jemalloc"]="https://github.com/jemalloc/jemalloc.git"
|
||||
["nlohmann"]="https://raw.githubusercontent.com/nlohmann/json/4f8fba14066156b73f1189a2b8bd568bde5284c5/single_include/nlohmann/json.hpp"
|
||||
["nlohmann"]="https://raw.githubusercontent.com/nlohmann/json/b3e5cb7f20dcc5c806e418df34324eca60d17d4e/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"
|
||||
["boost"]="https://boostorg.jfrog.io/artifactory/main/release/1.77.0/source/boost_1_77_0.tar.gz"
|
||||
["pulsar"]="https://github.com/apache/pulsar.git"
|
||||
["librdtsc"]="https://github.com/gabrieleara/librdtsc.git"
|
||||
)
|
||||
|
||||
# antlr
|
||||
@@ -166,26 +164,39 @@ file_get_try_double "${primary_urls[antlr4-generator]}" "${secondary_urls[antlr4
|
||||
|
||||
antlr4_tag="4.9.2" # v4.9.2
|
||||
repo_clone_try_double "${primary_urls[antlr4-code]}" "${secondary_urls[antlr4-code]}" "antlr4" "$antlr4_tag" true
|
||||
pushd antlr4
|
||||
git apply ../antlr4.patch
|
||||
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
|
||||
# fix issue https://github.com/antlr/antlr4/issues/3194 - should update Antlr commit once the PR related to the issue gets merged
|
||||
sed -i 's/std::is_nothrow_copy_constructible/std::is_copy_constructible/' antlr4/runtime/Cpp/runtime/src/support/Any.h
|
||||
# replace the utf8cpp version which is used because the older one uses gtest that doesn't
|
||||
# compile with the newer compilers because of uninitialized variable
|
||||
# the newer utf8cpp switched to ftest
|
||||
sed -i 's/v3.1.1/v3.2.1/' antlr4/runtime/Cpp/runtime/CMakeLists.txt
|
||||
|
||||
# cppitertools v2.0 2019-12-23
|
||||
cppitertools_ref="cb3635456bdb531121b82b4d2e3afc7ae1f56d47"
|
||||
repo_clone_try_double "${primary_urls[cppitertools]}" "${secondary_urls[cppitertools]}" "cppitertools" "$cppitertools_ref"
|
||||
|
||||
# fmt
|
||||
fmt_tag="8.0.1" # (2021-07-03)
|
||||
repo_clone_try_double "${primary_urls[fmt]}" "${secondary_urls[fmt]}" "fmt" "$fmt_tag" true
|
||||
|
||||
# rapidcheck
|
||||
rapidcheck_tag="7bc7d302191a4f3d0bf005692677126136e02f60" # (2020-05-04)
|
||||
repo_clone_try_double "${primary_urls[rapidcheck]}" "${secondary_urls[rapidcheck]}" "rapidcheck" "$rapidcheck_tag"
|
||||
|
||||
# google benchmark
|
||||
benchmark_tag="v1.6.0"
|
||||
benchmark_tag="v1.1.0"
|
||||
repo_clone_try_double "${primary_urls[gbenchmark]}" "${secondary_urls[gbenchmark]}" "benchmark" "$benchmark_tag" true
|
||||
|
||||
# google test
|
||||
googletest_tag="release-1.8.0"
|
||||
repo_clone_try_double "${primary_urls[gtest]}" "${secondary_urls[gtest]}" "googletest" "$googletest_tag" true
|
||||
|
||||
# google flags
|
||||
gflags_tag="b37ceb03a0e56c9f15ce80409438a555f8a67b7c" # custom version (May 6, 2017)
|
||||
repo_clone_try_double "${primary_urls[gflags]}" "${secondary_urls[gflags]}" "gflags" "$gflags_tag"
|
||||
|
||||
# libbcrypt
|
||||
libbcrypt_tag="8aa32ad94ebe06b76853b0767c910c9fbf7ccef4" # custom version (Dec 16, 2016)
|
||||
repo_clone_try_double "${primary_urls[libbcrypt]}" "${secondary_urls[libbcrypt]}" "libbcrypt" "$libbcrypt_tag"
|
||||
@@ -204,11 +215,18 @@ cd json
|
||||
file_get_try_double "${primary_urls[nlohmann]}" "${secondary_urls[nlohmann]}"
|
||||
cd ..
|
||||
|
||||
bzip2_tag="0405487e2b1de738e7f1c8afb50d19cf44e8d580" # v1.0.6 (May 26, 2011)
|
||||
repo_clone_try_double "${primary_urls[bzip2]}" "${secondary_urls[bzip2]}" "bzip2" "$bzip2_tag"
|
||||
|
||||
zlib_tag="v1.2.11" # v1.2.11.
|
||||
repo_clone_try_double "${primary_urls[zlib]}" "${secondary_urls[zlib]}" "zlib" "$zlib_tag" true
|
||||
# remove shared library from install dependencies
|
||||
sed -i 's/install(TARGETS zlib zlibstatic/install(TARGETS zlibstatic/g' zlib/CMakeLists.txt
|
||||
|
||||
rocksdb_tag="v6.14.6" # (2020-10-14)
|
||||
repo_clone_try_double "${primary_urls[rocksdb]}" "${secondary_urls[rocksdb]}" "rocksdb" "$rocksdb_tag" true
|
||||
pushd rocksdb
|
||||
git apply ../rocksdb.patch
|
||||
popd
|
||||
# remove shared library from install dependencies
|
||||
sed -i 's/TARGETS ${ROCKSDB_SHARED_LIB}/TARGETS ${ROCKSDB_SHARED_LIB} OPTIONAL/' rocksdb/CMakeLists.txt
|
||||
|
||||
# mgclient
|
||||
mgclient_tag="v1.3.0" # (2021-09-23)
|
||||
@@ -226,6 +244,25 @@ repo_clone_try_double "${primary_urls[mgconsole]}" "${secondary_urls[mgconsole]}
|
||||
spdlog_tag="v1.9.2" # (2021-08-12)
|
||||
repo_clone_try_double "${primary_urls[spdlog]}" "${secondary_urls[spdlog]}" "spdlog" "$spdlog_tag" true
|
||||
|
||||
jemalloc_tag="ea6b3e973b477b8061e0076bb257dbd7f3faa756" # (2021-02-11)
|
||||
repo_clone_try_double "${primary_urls[jemalloc]}" "${secondary_urls[jemalloc]}" "jemalloc" "$jemalloc_tag"
|
||||
pushd jemalloc
|
||||
# ThreadPool select job randomly, and there can be some threads that had been
|
||||
# performed some memory heavy task before and will be inactive for some time,
|
||||
# but until it will became active again, the memory will not be freed since by
|
||||
# default each thread has it's own arena, but there should be not more then
|
||||
# 4*CPU arenas (see opt.nareans description).
|
||||
#
|
||||
# By enabling percpu_arena number of arenas limited to number of CPUs and hence
|
||||
# this problem should go away.
|
||||
#
|
||||
# muzzy_decay_ms -- use MADV_FREE when available on newer Linuxes, to
|
||||
# avoid spurious latencies and additional work associated with
|
||||
# MADV_DONTNEED. See
|
||||
# https://github.com/ClickHouse/ClickHouse/issues/11121 for motivation.
|
||||
./autogen.sh --with-malloc-conf="percpu_arena:percpu,oversize_threshold:0,muzzy_decay_ms:5000,dirty_decay_ms:5000"
|
||||
popd
|
||||
|
||||
# librdkafka
|
||||
librdkafka_tag="v1.7.0" # (2021-05-06)
|
||||
repo_clone_try_double "${primary_urls[librdkafka]}" "${secondary_urls[librdkafka]}" "librdkafka" "$librdkafka_tag" true
|
||||
@@ -237,16 +274,18 @@ pushd protobuf
|
||||
./autogen.sh && ./configure CC=clang CXX=clang++ --prefix=$(pwd)/lib
|
||||
popd
|
||||
|
||||
# boost
|
||||
file_get_try_double "${primary_urls[boost]}" "${secondary_urls[boost]}"
|
||||
tar -xzf boost_1_77_0.tar.gz
|
||||
mv boost_1_77_0 boost
|
||||
pushd boost
|
||||
./bootstrap.sh --prefix=$(pwd)/lib --with-libraries="system,regex" --with-toolset=clang
|
||||
./b2 toolset=clang -j$(nproc) install variant=release
|
||||
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
|
||||
|
||||
@@ -36,18 +36,9 @@ set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "openssl (>= 1.1.0), python3 (>= 3.5.0)")
|
||||
|
||||
# RPM specific
|
||||
|
||||
set(MG_ARCH_EXTENSION "noarch")
|
||||
|
||||
if (${MG_ARCH} STREQUAL "x86_64")
|
||||
set(MG_ARCH_EXTENSION "x86_64")
|
||||
elseif (${MG_ARCH} STREQUAL "ARM64")
|
||||
set(MG_ARCH_EXTENSION "aarch64")
|
||||
endif()
|
||||
|
||||
set(CPACK_RPM_PACKAGE_URL https://memgraph.com)
|
||||
set(CPACK_RPM_PACKAGE_VERSION "${MEMGRAPH_VERSION_RPM}")
|
||||
set(CPACK_RPM_FILE_NAME "memgraph-${MEMGRAPH_VERSION_RPM}-1.${MG_ARCH_EXTENSION}.rpm")
|
||||
set(CPACK_RPM_FILE_NAME "memgraph-${MEMGRAPH_VERSION_RPM}-1.x86_64.rpm")
|
||||
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION
|
||||
/var /var/lib /var/log /etc/logrotate.d
|
||||
/lib /lib/systemd /lib/systemd/system /lib/systemd/system/memgraph.service)
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
FROM dokken/centos-stream-9
|
||||
|
||||
ARG env_folder
|
||||
ARG toolchain_version
|
||||
|
||||
COPY ${env_folder} /env_folder
|
||||
|
||||
RUN yum update && yum install -y curl git
|
||||
|
||||
RUN /${env_folder}/os/centos-9.sh install MEMGRAPH_BUILD_DEPS
|
||||
RUN /${env_folder}/os/centos-9.sh install TOOLCHAIN_RUN_DEPS
|
||||
|
||||
RUN rm -rf /env_folder
|
||||
|
||||
RUN yum clean all
|
||||
|
||||
RUN curl https://s3.eu-west-1.amazonaws.com/deps.memgraph.io/${toolchain_version}/${toolchain_version}-binaries-centos-9-arm64.tar.gz -o /tmp/toolchain.tar.gz \
|
||||
&& tar xvzf /tmp/toolchain.tar.gz -C /opt \
|
||||
&& rm /tmp/toolchain.tar.gz
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
cp -r ../../environment env_folder
|
||||
docker build -f build_env.dockerfile --build-arg env_folder=env_folder --build-arg toolchain_version=toolchain-v4 -t mg_build_env .
|
||||
rm -rf env_folder
|
||||
@@ -1,7 +1,7 @@
|
||||
FROM debian:bullseye
|
||||
# NOTE: If you change the base distro update release/package as well.
|
||||
|
||||
ARG release
|
||||
ARG deb_release
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
openssl libcurl4 libssl1.1 libseccomp2 python3 libpython3.9 python3-pip \
|
||||
@@ -10,10 +10,10 @@ RUN apt-get update && apt-get install -y \
|
||||
|
||||
RUN pip3 install networkx==2.4 numpy==1.21.4 scipy==1.7.3
|
||||
|
||||
COPY ${release} /
|
||||
COPY ${deb_release} /
|
||||
|
||||
# Install memgraph package
|
||||
RUN dpkg -i ${release}
|
||||
RUN dpkg -i ${deb_release}
|
||||
|
||||
# Memgraph listens for Bolt Protocol on this port by default.
|
||||
EXPOSE 7687
|
||||
@@ -1,31 +0,0 @@
|
||||
FROM dokken/centos-stream-9
|
||||
# NOTE: If you change the base distro update release/package as well.
|
||||
|
||||
ARG release
|
||||
|
||||
RUN yum update && yum install -y \
|
||||
openssl libcurl libseccomp python3 python3-pip \
|
||||
--nobest --allowerasing \
|
||||
&& rm -rf /tmp/* \
|
||||
&& yum clean all
|
||||
|
||||
RUN pip3 install networkx==2.4 numpy==1.21.4 scipy==1.7.3
|
||||
|
||||
COPY ${release} /
|
||||
|
||||
# Install memgraph package
|
||||
RUN rpm -i ${release}
|
||||
|
||||
# Memgraph listens for Bolt Protocol on this port by default.
|
||||
EXPOSE 7687
|
||||
# Snapshots and logging volumes
|
||||
VOLUME /var/log/memgraph
|
||||
VOLUME /var/lib/memgraph
|
||||
# Configuration volume
|
||||
VOLUME /etc/memgraph
|
||||
|
||||
USER memgraph
|
||||
WORKDIR /usr/lib/memgraph
|
||||
|
||||
ENTRYPOINT ["/usr/lib/memgraph/memgraph"]
|
||||
CMD [""]
|
||||
46
release/docker/package_deb_docker
Executable file
46
release/docker/package_deb_docker
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
# Build and package Docker image of Memgraph.
|
||||
|
||||
function print_help () {
|
||||
echo "Usage: $0 [--latest] MEMGRAPH_PACKAGE.deb"
|
||||
echo "Optional arguments:"
|
||||
echo -e "\t-h|--help\t\tPrint help."
|
||||
echo -e "\t--latest\t\tTag image as latest version."
|
||||
}
|
||||
|
||||
working_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
latest_image=""
|
||||
tag_latest=""
|
||||
if [[ $# -eq 2 && "$1" == "--latest" ]]; then
|
||||
latest_image="memgraph:latest"
|
||||
tag_latest="-t memgraph:latest"
|
||||
shift
|
||||
elif [[ $# -ne 1 || "$1" == "-h" || "$1" == "--help" ]]; then
|
||||
print_help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
deb_path="$1"
|
||||
if [[ ! -f "$deb_path" ]]; then
|
||||
echo "File '$deb_path' does not exist!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Copy the .deb to working directory.
|
||||
cp "$deb_path" "${working_dir}/"
|
||||
cd ${working_dir}
|
||||
|
||||
# Extract version and offering from deb name.
|
||||
deb_name=`echo $(basename "$deb_path") | sed 's/.deb$//'`
|
||||
version=`echo ${deb_name} | cut -d '_' -f 2 | rev | cut -d '-' -f 2- | rev | tr '+~' '__'`
|
||||
dockerfile_path="${working_dir}/memgraph.dockerfile"
|
||||
image_name="memgraph:${version}"
|
||||
package_name="memgraph-${version}-docker.tar.gz"
|
||||
|
||||
# Build docker image.
|
||||
docker build -t ${image_name} ${tag_latest} -f ${dockerfile_path} --build-arg deb_release=${deb_name}.deb .
|
||||
docker save ${image_name} ${latest_image} > ${package_name}
|
||||
rm "${deb_name}.deb"
|
||||
echo "Built Docker image at '${working_dir}/${package_name}'"
|
||||
@@ -1,61 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
# Build and package Docker image of Memgraph.
|
||||
|
||||
function print_help () {
|
||||
echo "Usage: $0 [--latest] MEMGRAPH_PACKAGE.(deb|rpm)"
|
||||
echo "Optional arguments:"
|
||||
echo -e "\t-h|--help\t\tPrint help."
|
||||
echo -e "\t--latest\t\tTag image as latest version."
|
||||
}
|
||||
|
||||
working_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
latest_image=""
|
||||
tag_latest=""
|
||||
if [[ $# -eq 2 && "$1" == "--latest" ]]; then
|
||||
latest_image="memgraph:latest"
|
||||
tag_latest="-t memgraph:latest"
|
||||
shift
|
||||
elif [[ $# -ne 1 || "$1" == "-h" || "$1" == "--help" ]]; then
|
||||
print_help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
package_path="$1"
|
||||
if [[ ! -f "$package_path" ]]; then
|
||||
echo "File '$package_path' does not exist!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Copy the .deb to working directory.
|
||||
cp "$package_path" "${working_dir}/"
|
||||
cd ${working_dir}
|
||||
|
||||
extension="${package_path##*.}"
|
||||
|
||||
if [[ "$extension" == "deb" ]]; then
|
||||
# Extract version and offering from deb name.
|
||||
package_name=`echo $(basename "$package_path") | sed 's/.deb$//'`
|
||||
version=`echo ${package_name} | cut -d '_' -f 2 | rev | cut -d '-' -f 2- | rev | tr '+~' '__'`
|
||||
dockerfile_path="${working_dir}/memgraph_deb.dockerfile"
|
||||
elif [[ "$extension" == "rpm" ]]; then
|
||||
# Extract version and offering from deb name.
|
||||
package_name=`echo $(basename "$package_path") | sed 's/.rpm$//'`
|
||||
version=`echo ${package_name} | cut -d '-' -f 2 | rev | cut -d '-' -f 2- | rev`
|
||||
version=${version%_1}
|
||||
dockerfile_path="${working_dir}/memgraph_rpm.dockerfile"
|
||||
else
|
||||
echo "Invalid file sent as the package"
|
||||
print_help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
image_name="memgraph:${version}"
|
||||
image_package_name="memgraph-${version}-docker.tar.gz"
|
||||
|
||||
# Build docker image.
|
||||
docker build -t ${image_name} ${tag_latest} -f ${dockerfile_path} --build-arg release=${package_name}.${extension} .
|
||||
docker save ${image_name} ${latest_image} | gzip > ${image_package_name}
|
||||
rm "${package_name}.${extension}"
|
||||
echo "Built Docker image at '${working_dir}/${image_package_name}'"
|
||||
17
release/package/debian-9/Dockerfile
Normal file
17
release/package/debian-9/Dockerfile
Normal file
@@ -0,0 +1,17 @@
|
||||
FROM debian:9
|
||||
|
||||
ARG TOOLCHAIN_VERSION
|
||||
|
||||
# Stops tzdata interactive configuration.
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt update && apt install -y \
|
||||
ca-certificates wget git
|
||||
# Do NOT be smart here and clean the cache because the container is used in the
|
||||
# stateful context.
|
||||
|
||||
RUN wget -q https://s3-eu-west-1.amazonaws.com/deps.memgraph.io/${TOOLCHAIN_VERSION}/${TOOLCHAIN_VERSION}-binaries-debian-9.tar.gz \
|
||||
-O ${TOOLCHAIN_VERSION}-binaries-debian-9.tar.gz \
|
||||
&& tar xzvf ${TOOLCHAIN_VERSION}-binaries-debian-9.tar.gz -C /opt
|
||||
|
||||
ENTRYPOINT ["sleep", "infinity"]
|
||||
@@ -8,6 +8,10 @@ services:
|
||||
build:
|
||||
context: centos-8
|
||||
container_name: "mgbuild_centos-8"
|
||||
mgbuild_debian-9:
|
||||
build:
|
||||
context: debian-9
|
||||
container_name: "mgbuild_debian-9"
|
||||
mgbuild_debian-10:
|
||||
build:
|
||||
context: debian-10
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
set -Eeuo pipefail
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
SUPPORTED_OS=(centos-7 centos-8 debian-10 debian-11 ubuntu-18.04 ubuntu-20.04)
|
||||
SUPPORTED_OS=(centos-7 centos-8 debian-9 debian-10 debian-11 ubuntu-18.04 ubuntu-20.04)
|
||||
PROJECT_ROOT="$SCRIPT_DIR/../.."
|
||||
TOOLCHAIN_VERSION="toolchain-v4"
|
||||
TOOLCHAIN_VERSION="toolchain-v3"
|
||||
ACTIVATE_TOOLCHAIN="source /opt/${TOOLCHAIN_VERSION}/activate"
|
||||
HOST_OUTPUT_DIR="$PROJECT_ROOT/build/output"
|
||||
|
||||
@@ -106,7 +106,7 @@ case "$1" in
|
||||
last_package_name=$(cd "$HOST_OUTPUT_DIR/$based_on_os" && ls -t memgraph* | head -1)
|
||||
docker_build_folder="$PROJECT_ROOT/release/docker"
|
||||
cd "$docker_build_folder"
|
||||
./package_docker --latest "$HOST_OUTPUT_DIR/$based_on_os/$last_package_name"
|
||||
./package_deb_docker --latest "$HOST_OUTPUT_DIR/$based_on_os/$last_package_name"
|
||||
# shellcheck disable=SC2012
|
||||
docker_image_name=$(cd "$docker_build_folder" && ls -t memgraph* | head -1)
|
||||
docker_host_folder="$HOST_OUTPUT_DIR/docker"
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
set(audit_src_files log.cpp)
|
||||
|
||||
find_package(fmt REQUIRED)
|
||||
find_package(gflags REQUIRED)
|
||||
|
||||
add_library(mg-audit STATIC ${audit_src_files})
|
||||
target_link_libraries(mg-audit json gflags fmt::fmt)
|
||||
target_link_libraries(mg-audit mg-utils mg-storage-v2)
|
||||
|
||||
@@ -5,9 +5,6 @@ set(auth_src_files
|
||||
module.cpp)
|
||||
|
||||
find_package(Seccomp REQUIRED)
|
||||
find_package(fmt REQUIRED)
|
||||
find_package(gflags REQUIRED)
|
||||
|
||||
|
||||
add_library(mg-auth STATIC ${auth_src_files})
|
||||
target_link_libraries(mg-auth json libbcrypt gflags fmt::fmt)
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
find_package(fmt REQUIRED)
|
||||
find_package(gflags REQUIRED)
|
||||
|
||||
set(communication_src_files
|
||||
bolt/v1/value.cpp
|
||||
buffer.cpp
|
||||
@@ -9,8 +6,10 @@ set(communication_src_files
|
||||
helpers.cpp
|
||||
init.cpp)
|
||||
|
||||
find_package(Boost REQUIRED)
|
||||
|
||||
add_library(mg-communication STATIC ${communication_src_files})
|
||||
target_link_libraries(mg-communication Threads::Threads mg-utils mg-io fmt::fmt gflags)
|
||||
target_link_libraries(mg-communication Boost::headers Threads::Threads mg-utils mg-io fmt::fmt gflags)
|
||||
|
||||
find_package(OpenSSL REQUIRED)
|
||||
target_link_libraries(mg-communication ${OPENSSL_LIBRARIES})
|
||||
|
||||
@@ -89,8 +89,7 @@ class Server final {
|
||||
alive_.store(true);
|
||||
|
||||
if (!socket_.Bind(endpoint_)) {
|
||||
spdlog::error(
|
||||
utils::MessageWithLink("Cannot bind to socket on endpoint {}.", endpoint_, "https://memgr.ph/socket"));
|
||||
spdlog::error(utils::MessageWithLink("Cannot bind to socket on endpoint {}.", endpoint_, "https://memgr.ph/socket"));
|
||||
alive_.store(false);
|
||||
return false;
|
||||
}
|
||||
@@ -103,8 +102,9 @@ class Server final {
|
||||
|
||||
listener_.Start();
|
||||
|
||||
thread_ = std::thread([this]() {
|
||||
utils::ThreadSetName(fmt::format("{} server", service_name_));
|
||||
std::string service_name(service_name_);
|
||||
thread_ = std::thread([this, service_name]() {
|
||||
utils::ThreadSetName(fmt::format("{} server", service_name));
|
||||
|
||||
spdlog::info("{} server is fully armed and operational", service_name_);
|
||||
spdlog::info("{} listening on {}", service_name_, socket_.endpoint());
|
||||
|
||||
94
src/communication/websocket/listener.hpp
Normal file
94
src/communication/websocket/listener.hpp
Normal file
@@ -0,0 +1,94 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
// License, and you may not use this file except in compliance with the Business Source License.
|
||||
//
|
||||
// As of the Change Date specified in that file, in accordance with
|
||||
// the Business Source License, use of this software will be governed
|
||||
// by the Apache License, Version 2.0, included in the file
|
||||
// licenses/APL.txt.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/strand.hpp>
|
||||
#include <boost/beast/core.hpp>
|
||||
|
||||
#include "communication/websocket/session.hpp"
|
||||
#include "utils/spin_lock.hpp"
|
||||
#include "utils/synchronized.hpp"
|
||||
|
||||
namespace communication::websocket {
|
||||
template <typename TSession, typename TSessionData>
|
||||
class Listener : public std::enable_shared_from_this<Listener<TSession, TSessionData>> {
|
||||
using tcp = boost::asio::ip::tcp;
|
||||
|
||||
public:
|
||||
template <typename... Args>
|
||||
static std::shared_ptr<Listener> Create(Args &&...args) {
|
||||
return std::shared_ptr<Listener>{new Listener(std::forward<Args>(args)...)};
|
||||
}
|
||||
|
||||
// Start accepting incoming connections
|
||||
void Run() {
|
||||
// The new connection gets its own strand
|
||||
acceptor_.async_accept(ioc_, [shared_this = this->shared_from_this()](auto ec, auto socket) {
|
||||
shared_this->OnAccept(ec, std::move(socket));
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
Listener(boost::asio::io_context &ioc, tcp::endpoint endpoint, TSessionData *data)
|
||||
: data_{data}, ioc_(ioc), acceptor_(ioc) {
|
||||
boost::beast::error_code ec;
|
||||
|
||||
// Open the acceptor
|
||||
acceptor_.open(endpoint.protocol(), ec);
|
||||
if (ec) {
|
||||
LogError(ec, "open");
|
||||
return;
|
||||
}
|
||||
|
||||
// Allow address reuse
|
||||
acceptor_.set_option(boost::asio::socket_base::reuse_address(true), ec);
|
||||
if (ec) {
|
||||
LogError(ec, "set_option");
|
||||
return;
|
||||
}
|
||||
|
||||
// Bind to the server address
|
||||
acceptor_.bind(endpoint, ec);
|
||||
if (ec) {
|
||||
LogError(ec, "bind");
|
||||
return;
|
||||
}
|
||||
|
||||
acceptor_.listen(boost::asio::socket_base::max_listen_connections, ec);
|
||||
if (ec) {
|
||||
LogError(ec, "listen");
|
||||
return;
|
||||
}
|
||||
|
||||
spdlog::info("WebSocket server is listening on {}:{}", endpoint.address(), endpoint.port());
|
||||
}
|
||||
|
||||
void OnAccept(boost::beast::error_code ec, tcp::socket socket) {
|
||||
if (ec) {
|
||||
return LogError(ec, "accept");
|
||||
}
|
||||
|
||||
Session<TSession, TSessionData>::Create(std::move(socket), data_)->Run();
|
||||
Run();
|
||||
}
|
||||
|
||||
TSessionData *data_;
|
||||
boost::asio::io_context &ioc_;
|
||||
tcp::acceptor acceptor_;
|
||||
};
|
||||
} // namespace communication::websocket
|
||||
69
src/communication/websocket/server.hpp
Normal file
69
src/communication/websocket/server.hpp
Normal file
@@ -0,0 +1,69 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
// License, and you may not use this file except in compliance with the Business Source License.
|
||||
//
|
||||
// As of the Change Date specified in that file, in accordance with
|
||||
// the Business Source License, use of this software will be governed
|
||||
// by the Apache License, Version 2.0, included in the file
|
||||
// licenses/APL.txt.
|
||||
|
||||
#pragma once
|
||||
|
||||
#define BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include <spdlog/sinks/base_sink.h>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
|
||||
#include "communication/websocket/listener.hpp"
|
||||
#include "io/network/endpoint.hpp"
|
||||
|
||||
namespace communication::websocket {
|
||||
|
||||
template <typename TSession, typename TSessionData>
|
||||
class Server final {
|
||||
using tcp = boost::asio::ip::tcp;
|
||||
|
||||
public:
|
||||
explicit Server(io::network::Endpoint endpoint, TSessionData *data)
|
||||
: ioc_{},
|
||||
listener_{Listener<TSession, TSessionData>::Create(
|
||||
ioc_, tcp::endpoint{boost::asio::ip::make_address(endpoint.address), endpoint.port}, data)} {}
|
||||
|
||||
Server(const Server &) = delete;
|
||||
Server(Server &&) = delete;
|
||||
Server &operator=(const Server &) = delete;
|
||||
Server &operator=(Server &&) = delete;
|
||||
|
||||
~Server() {
|
||||
MG_ASSERT(!background_thread_ || (ioc_.stopped() && !background_thread_->joinable()),
|
||||
"Server wasn't shutdown properly");
|
||||
}
|
||||
|
||||
void Start() {
|
||||
MG_ASSERT(!background_thread_, "The server was already started!");
|
||||
listener_->Run();
|
||||
background_thread_.emplace([this] { ioc_.run(); });
|
||||
}
|
||||
|
||||
void Shutdown() { ioc_.stop(); }
|
||||
|
||||
void AwaitShutdown() {
|
||||
if (background_thread_ && background_thread_->joinable()) {
|
||||
background_thread_->join();
|
||||
}
|
||||
}
|
||||
|
||||
bool IsRunning() const { return background_thread_ && !ioc_.stopped(); }
|
||||
|
||||
private:
|
||||
boost::asio::io_context ioc_;
|
||||
|
||||
std::shared_ptr<Listener<TSession, TSessionData>> listener_;
|
||||
std::optional<std::thread> background_thread_;
|
||||
};
|
||||
} // namespace communication::websocket
|
||||
157
src/communication/websocket/session.hpp
Normal file
157
src/communication/websocket/session.hpp
Normal file
@@ -0,0 +1,157 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
// License, and you may not use this file except in compliance with the Business Source License.
|
||||
//
|
||||
// As of the Change Date specified in that file, in accordance with
|
||||
// the Business Source License, use of this software will be governed
|
||||
// by the Apache License, Version 2.0, included in the file
|
||||
// licenses/APL.txt.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
#include <span>
|
||||
|
||||
#include <boost/asio/dispatch.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/strand.hpp>
|
||||
#include <boost/beast/core/tcp_stream.hpp>
|
||||
#include <boost/beast/http.hpp>
|
||||
#include <boost/beast/websocket.hpp>
|
||||
|
||||
#include "communication/buffer.hpp"
|
||||
#include "communication/session.hpp"
|
||||
|
||||
namespace communication::websocket {
|
||||
void LogError(boost::beast::error_code ec, const std::string_view what) {
|
||||
spdlog::warn("Websocket session failed on {}: {}", what, ec.message());
|
||||
}
|
||||
|
||||
template <typename TSession, typename TSessionData>
|
||||
class Session : public std::enable_shared_from_this<Session<TSession, TSessionData>> {
|
||||
using tcp = boost::asio::ip::tcp;
|
||||
|
||||
public:
|
||||
template <typename... Args>
|
||||
static std::shared_ptr<Session> Create(Args &&...args) {
|
||||
return std::shared_ptr<Session>{new Session{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
void Run() {
|
||||
boost::asio::dispatch(strand_, [shared_this = this->shared_from_this()] { shared_this->OnRun(); });
|
||||
}
|
||||
|
||||
private:
|
||||
explicit Session(tcp::socket &&socket, TSessionData *data)
|
||||
: endpoint_(socket.local_endpoint()),
|
||||
ws_(std::move(socket)),
|
||||
strand_{boost::asio::make_strand(ws_.get_executor())},
|
||||
data_{data} {}
|
||||
|
||||
void OnRun() {
|
||||
ws_.set_option(boost::beast::websocket::stream_base::timeout::suggested(boost::beast::role_type::server));
|
||||
boost::asio::socket_base::keep_alive option(true);
|
||||
ws_.set_option(boost::beast::websocket::stream_base::decorator([](boost::beast::websocket::response_type &res) {
|
||||
res.set(boost::beast::http::field::server, "Memgraph WS");
|
||||
res.set(boost::beast::http::field::sec_websocket_protocol, "binary");
|
||||
}));
|
||||
|
||||
ws_.binary(true);
|
||||
// This buffer will hold the HTTP request as raw characters
|
||||
|
||||
// This buffer is required for reading HTTP messages
|
||||
// flat_buffer buffer;
|
||||
|
||||
// Read the HTTP request ourselves
|
||||
// boost::beast::http::request<http::string_body> req;
|
||||
// http::read(sock, buffer, req);
|
||||
// std::cout << "bu
|
||||
// Read into our buffer until we reach the end of the HTTP request.
|
||||
// No parsing takes place here, we are just accumulating data.
|
||||
|
||||
// boost::beast::net::read_until(sock, net::dynamic_buffer(s), "\r\n\r\n");
|
||||
|
||||
// Now accept the connection, using the buffered data.
|
||||
// ws_.accept(net::buffer(s));
|
||||
ws_.async_accept(boost::asio::bind_executor(
|
||||
strand_, [shared_this = this->shared_from_this()](auto ec) { shared_this->OnAccept(ec); }));
|
||||
}
|
||||
|
||||
void OnAccept(boost::beast::error_code ec) {
|
||||
if (ec) {
|
||||
return LogError(ec, "accept");
|
||||
}
|
||||
|
||||
session_data_.emplace(this->shared_from_this());
|
||||
|
||||
// run on the strand
|
||||
boost::asio::dispatch(strand_, [shared_this = this->shared_from_this()] { shared_this->DoRead(); });
|
||||
}
|
||||
|
||||
void DoWrite(const uint8_t *data, size_t len, bool have_more = false) {
|
||||
boost::beast::error_code ec;
|
||||
ws_.write(boost::asio::const_buffer{data, len}, ec);
|
||||
if (ec) {
|
||||
return LogError(ec, "write");
|
||||
}
|
||||
}
|
||||
|
||||
void DoRead() {
|
||||
auto buf = session_data_->input_buffer_.write_end()->Allocate();
|
||||
|
||||
auto mutable_buffer = std::make_unique<boost::asio::mutable_buffer>(buf.data, buf.len);
|
||||
|
||||
ws_.async_read_some(
|
||||
*mutable_buffer,
|
||||
boost::asio::bind_executor(
|
||||
strand_, [mutable_buffer = std::move(mutable_buffer), shared_this = this->shared_from_this()](
|
||||
auto ec, auto bytes_transferred) { shared_this->OnRead(ec, bytes_transferred); }));
|
||||
}
|
||||
|
||||
void OnRead(boost::beast::error_code ec, size_t bytes_transferred) {
|
||||
if (ec == boost::beast::websocket::error::closed) {
|
||||
return;
|
||||
}
|
||||
if (ec) {
|
||||
return LogError(ec, "read");
|
||||
}
|
||||
|
||||
session_data_->input_buffer_.write_end()->Written(bytes_transferred);
|
||||
|
||||
try {
|
||||
session_data_->session_.Execute();
|
||||
} catch (const SessionClosedException &e) {
|
||||
spdlog::info("Closed connection");
|
||||
return;
|
||||
}
|
||||
DoRead();
|
||||
}
|
||||
|
||||
boost::asio::ip::tcp::endpoint endpoint_;
|
||||
boost::beast::websocket::stream<boost::beast::tcp_stream> ws_;
|
||||
boost::beast::flat_buffer buffer_;
|
||||
boost::asio::strand<decltype(ws_)::executor_type> strand_;
|
||||
|
||||
TSessionData *data_;
|
||||
|
||||
struct SessionData {
|
||||
explicit SessionData(std::shared_ptr<Session<TSession, TSessionData>> session)
|
||||
: output_stream_([session](const uint8_t *data, size_t len, bool have_more) {
|
||||
session->DoWrite(data, len, have_more);
|
||||
return true;
|
||||
}),
|
||||
session_(session->data_,
|
||||
io::network::Endpoint{session->endpoint_.address().to_string(), session->endpoint_.port()},
|
||||
input_buffer_.read_end(), &output_stream_) {}
|
||||
|
||||
Buffer input_buffer_;
|
||||
communication::OutputStream output_stream_;
|
||||
TSession session_;
|
||||
};
|
||||
|
||||
std::optional<SessionData> session_data_;
|
||||
};
|
||||
} // namespace communication::websocket
|
||||
@@ -238,7 +238,7 @@ Value ToBoltValue(const storage::PropertyValue &value) {
|
||||
case storage::PropertyValue::Type::Double:
|
||||
return Value(value.ValueDouble());
|
||||
case storage::PropertyValue::Type::String:
|
||||
return Value(std::string{value.ValueString()});
|
||||
return Value(value.ValueString());
|
||||
case storage::PropertyValue::Type::List: {
|
||||
const auto &values = value.ValueList();
|
||||
std::vector<Value> vec;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -10,14 +10,11 @@
|
||||
// licenses/APL.txt.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
||||
namespace integrations {
|
||||
constexpr int64_t kDefaultCheckBatchLimit{1};
|
||||
constexpr std::chrono::milliseconds kDefaultCheckTimeout{30000};
|
||||
constexpr std::chrono::milliseconds kMinimumInterval{1};
|
||||
constexpr int64_t kMinimumSize{1};
|
||||
const std::string kReducted{"<REDUCTED>"};
|
||||
} // namespace integrations
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -126,18 +126,6 @@ Consumer::Consumer(ConsumerInfo info, ConsumerFunction consumer_function)
|
||||
|
||||
std::string error;
|
||||
|
||||
for (const auto &[key, value] : info_.public_configs) {
|
||||
if (conf->set(key, value, error) != RdKafka::Conf::CONF_OK) {
|
||||
throw SettingCustomConfigFailed(info_.consumer_name, error, key, value);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &[key, value] : info_.private_configs) {
|
||||
if (conf->set(key, value, error) != RdKafka::Conf::CONF_OK) {
|
||||
throw SettingCustomConfigFailed(info_.consumer_name, error, key, kReducted);
|
||||
}
|
||||
}
|
||||
|
||||
if (conf->set("event_cb", this, error) != RdKafka::Conf::CONF_OK) {
|
||||
throw ConsumerFailedToInitializeException(info_.consumer_name, error);
|
||||
}
|
||||
@@ -440,11 +428,11 @@ void Consumer::ConsumerRebalanceCb::rebalance_cb(RdKafka::KafkaConsumer *consume
|
||||
}
|
||||
auto maybe_error = consumer->assign(partitions);
|
||||
if (maybe_error != RdKafka::ErrorCode::ERR_NO_ERROR) {
|
||||
spdlog::warn("Assigning offset of consumer {} failed: {}", consumer_name_, RdKafka::err2str(maybe_error));
|
||||
spdlog::warn("Assigning offset of consumer {} failed: {}", consumer_name_, RdKafka::err2str(err));
|
||||
}
|
||||
maybe_error = consumer->commitSync(partitions);
|
||||
if (maybe_error != RdKafka::ErrorCode::ERR_NO_ERROR) {
|
||||
spdlog::warn("Commiting offsets of consumer {} failed: {}", consumer_name_, RdKafka::err2str(maybe_error));
|
||||
spdlog::warn("Commiting offsets of consumer {} failed: {}", consumer_name_, RdKafka::err2str(err));
|
||||
}
|
||||
}
|
||||
void Consumer::ConsumerRebalanceCb::set_offset(int64_t offset) { offset_ = offset; }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -86,8 +86,6 @@ struct ConsumerInfo {
|
||||
std::string bootstrap_servers;
|
||||
std::chrono::milliseconds batch_interval;
|
||||
int64_t batch_size;
|
||||
std::unordered_map<std::string, std::string> public_configs;
|
||||
std::unordered_map<std::string, std::string> private_configs;
|
||||
};
|
||||
|
||||
/// Memgraphs Kafka consumer wrapper.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
#include <string>
|
||||
|
||||
#include "utils/exceptions.hpp"
|
||||
|
||||
@@ -22,46 +22,37 @@ class KafkaStreamException : public utils::BasicException {
|
||||
|
||||
class ConsumerFailedToInitializeException : public KafkaStreamException {
|
||||
public:
|
||||
ConsumerFailedToInitializeException(const std::string_view consumer_name, const std::string_view error)
|
||||
ConsumerFailedToInitializeException(const std::string &consumer_name, const std::string &error)
|
||||
: KafkaStreamException("Failed to initialize Kafka consumer {} : {}", consumer_name, error) {}
|
||||
};
|
||||
|
||||
class SettingCustomConfigFailed : public ConsumerFailedToInitializeException {
|
||||
public:
|
||||
SettingCustomConfigFailed(const std::string_view consumer_name, const std::string_view error,
|
||||
const std::string_view key, const std::string_view value)
|
||||
: ConsumerFailedToInitializeException(
|
||||
consumer_name,
|
||||
fmt::format(R"(failed to set custom config ("{}": "{}"), because of error {})", key, value, error)) {}
|
||||
};
|
||||
|
||||
class ConsumerRunningException : public KafkaStreamException {
|
||||
public:
|
||||
explicit ConsumerRunningException(const std::string_view consumer_name)
|
||||
explicit ConsumerRunningException(const std::string &consumer_name)
|
||||
: KafkaStreamException("Kafka consumer {} is already running", consumer_name) {}
|
||||
};
|
||||
|
||||
class ConsumerStoppedException : public KafkaStreamException {
|
||||
public:
|
||||
explicit ConsumerStoppedException(const std::string_view consumer_name)
|
||||
explicit ConsumerStoppedException(const std::string &consumer_name)
|
||||
: KafkaStreamException("Kafka consumer {} is already stopped", consumer_name) {}
|
||||
};
|
||||
|
||||
class ConsumerCheckFailedException : public KafkaStreamException {
|
||||
public:
|
||||
explicit ConsumerCheckFailedException(const std::string_view consumer_name, const std::string_view error)
|
||||
explicit ConsumerCheckFailedException(const std::string &consumer_name, const std::string &error)
|
||||
: KafkaStreamException("Kafka consumer {} check failed: {}", consumer_name, error) {}
|
||||
};
|
||||
|
||||
class ConsumerStartFailedException : public KafkaStreamException {
|
||||
public:
|
||||
explicit ConsumerStartFailedException(const std::string_view consumer_name, const std::string_view error)
|
||||
explicit ConsumerStartFailedException(const std::string &consumer_name, const std::string &error)
|
||||
: KafkaStreamException("Starting Kafka consumer {} failed: {}", consumer_name, error) {}
|
||||
};
|
||||
|
||||
class TopicNotFoundException : public KafkaStreamException {
|
||||
public:
|
||||
TopicNotFoundException(const std::string_view consumer_name, const std::string_view topic_name)
|
||||
TopicNotFoundException(const std::string &consumer_name, const std::string &topic_name)
|
||||
: KafkaStreamException("Kafka consumer {} cannot find topic {}", consumer_name, topic_name) {}
|
||||
};
|
||||
} // namespace integrations::kafka
|
||||
|
||||
@@ -4,8 +4,5 @@ set(io_src_files
|
||||
network/socket.cpp
|
||||
network/utils.cpp)
|
||||
|
||||
find_package(fmt REQUIRED)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
add_library(mg-io STATIC ${io_src_files})
|
||||
target_link_libraries(mg-io stdc++fs Threads::Threads fmt::fmt mg-utils)
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
find_package(gflags REQUIRED)
|
||||
find_package(BZip2 REQUIRED)
|
||||
find_package(ZLIB REQUIRED)
|
||||
|
||||
# STATIC library used to store key-value pairs
|
||||
add_library(mg-kvstore STATIC kvstore.cpp)
|
||||
target_link_libraries(mg-kvstore stdc++fs mg-utils rocksdb BZip2::BZip2 ZLIB::ZLIB gflags)
|
||||
target_link_libraries(mg-kvstore stdc++fs mg-utils rocksdb bzip2 zlib gflags)
|
||||
|
||||
# STATIC library for dummy key-value storage
|
||||
# add_library(mg-kvstore-dummy STATIC kvstore_dummy.cpp)
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
#include <string_view>
|
||||
#include <thread>
|
||||
|
||||
#include <jemalloc/jemalloc.h>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <gflags/gflags.h>
|
||||
#include <spdlog/common.h>
|
||||
@@ -34,6 +32,7 @@
|
||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||
|
||||
#include "communication/bolt/v1/constants.hpp"
|
||||
#include "communication/websocket/server.hpp"
|
||||
#include "helpers.hpp"
|
||||
#include "py/py.hpp"
|
||||
#include "query/auth_checker.hpp"
|
||||
@@ -46,7 +45,6 @@
|
||||
#include "query/procedure/py_module.hpp"
|
||||
#include "requests/requests.hpp"
|
||||
#include "storage/v2/isolation_level.hpp"
|
||||
#include "storage/v2/property_value.hpp"
|
||||
#include "storage/v2/storage.hpp"
|
||||
#include "storage/v2/view.hpp"
|
||||
#include "telemetry/telemetry.hpp"
|
||||
@@ -820,7 +818,7 @@ class BoltSession final : public communication::bolt::Session<communication::Inp
|
||||
|
||||
std::pair<std::vector<std::string>, std::optional<int>> Interpret(
|
||||
const std::string &query, const std::map<std::string, communication::bolt::Value> ¶ms) override {
|
||||
storage::PropertyValue::TMap params_pv{utils::NewDeleteResource()};
|
||||
std::map<std::string, storage::PropertyValue> params_pv;
|
||||
for (const auto &kv : params) params_pv.emplace(kv.first, glue::ToPropertyValue(kv.second));
|
||||
const std::string *username{nullptr};
|
||||
if (user_) {
|
||||
@@ -1180,8 +1178,8 @@ int main(int argc, char **argv) {
|
||||
spdlog::warn(utils::MessageWithLink("Using non-secure Bolt connection (without SSL).", "https://memgr.ph/ssl"));
|
||||
}
|
||||
|
||||
ServerT server({FLAGS_bolt_address, static_cast<uint16_t>(FLAGS_bolt_port)}, &session_data, &context,
|
||||
FLAGS_bolt_session_inactivity_timeout, service_name, FLAGS_bolt_num_workers);
|
||||
auto server = communication::websocket::Server<BoltSession, SessionData>{
|
||||
{FLAGS_bolt_address, static_cast<uint16_t>(FLAGS_bolt_port)}, &session_data};
|
||||
|
||||
// Setup telemetry
|
||||
std::optional<telemetry::Telemetry> telemetry;
|
||||
@@ -1215,7 +1213,7 @@ int main(int argc, char **argv) {
|
||||
};
|
||||
InitSignalHandlers(shutdown);
|
||||
|
||||
MG_ASSERT(server.Start(), "Couldn't start the Bolt server!");
|
||||
server.Start();
|
||||
server.AwaitShutdown();
|
||||
query::procedure::gModuleRegistry.UnloadAllModules();
|
||||
|
||||
|
||||
@@ -2,11 +2,9 @@ set(memory_src_files
|
||||
new_delete.cpp
|
||||
memory_control.cpp)
|
||||
|
||||
find_package(Jemalloc REQUIRED)
|
||||
|
||||
add_library(mg-memory STATIC ${memory_src_files})
|
||||
target_link_libraries(mg-memory mg-utils fmt)
|
||||
|
||||
if (ENABLE_JEMALLOC)
|
||||
target_link_libraries(mg-memory Jemalloc::Jemalloc)
|
||||
target_link_libraries(mg-memory jemalloc)
|
||||
endif()
|
||||
|
||||
@@ -30,7 +30,6 @@ set(mg_query_sources
|
||||
plan/rule_based_planner.cpp
|
||||
plan/variable_start_planner.cpp
|
||||
procedure/mg_procedure_impl.cpp
|
||||
procedure/mg_procedure_helpers.cpp
|
||||
procedure/module.cpp
|
||||
procedure/py_module.cpp
|
||||
serialization/property_value.cpp
|
||||
@@ -48,9 +47,6 @@ add_dependencies(mg-query generate_lcp_query)
|
||||
target_include_directories(mg-query PUBLIC ${CMAKE_SOURCE_DIR}/include)
|
||||
target_link_libraries(mg-query dl cppitertools Boost::headers)
|
||||
target_link_libraries(mg-query mg-integrations-pulsar mg-integrations-kafka mg-storage-v2 mg-license mg-utils mg-kvstore mg-memory)
|
||||
if(NOT "${MG_PYTHON_PATH}" STREQUAL "")
|
||||
set(Python3_ROOT_DIR "${MG_PYTHON_PATH}")
|
||||
endif()
|
||||
if("${MG_PYTHON_VERSION}" STREQUAL "")
|
||||
find_package(Python3 3.5 REQUIRED COMPONENTS Development)
|
||||
else()
|
||||
|
||||
@@ -11,9 +11,6 @@
|
||||
|
||||
#include "query/cypher_query_interpreter.hpp"
|
||||
|
||||
#include "utils/memory.hpp"
|
||||
#include "utils/pmr/string.hpp"
|
||||
|
||||
// NOLINTNEXTLINE (cppcoreguidelines-avoid-non-const-global-variables)
|
||||
DEFINE_HIDDEN_bool(query_cost_planner, true, "Use the cost-estimating query planner.");
|
||||
// NOLINTNEXTLINE (cppcoreguidelines-avoid-non-const-global-variables)
|
||||
@@ -23,7 +20,7 @@ DEFINE_VALIDATED_int32(query_plan_cache_ttl, 60, "Time to live for cached query
|
||||
namespace query {
|
||||
CachedPlan::CachedPlan(std::unique_ptr<LogicalPlan> plan) : plan_(std::move(plan)) {}
|
||||
|
||||
ParsedQuery ParseQuery(const std::string &query_string, const storage::PropertyValue::TMap ¶ms,
|
||||
ParsedQuery ParseQuery(const std::string &query_string, const std::map<std::string, storage::PropertyValue> ¶ms,
|
||||
utils::SkipList<QueryCacheEntry> *cache, utils::SpinLock *antlr_lock,
|
||||
const InterpreterConfig::Query &query_config) {
|
||||
// Strip the query for caching purposes. The process of stripping a query
|
||||
@@ -37,7 +34,7 @@ ParsedQuery ParseQuery(const std::string &query_string, const storage::PropertyV
|
||||
|
||||
// Check that all user-specified parameters are provided.
|
||||
for (const auto ¶m_pair : stripped_query.parameters()) {
|
||||
auto it = params.find(utils::pmr::string{param_pair.second, utils::NewDeleteResource()});
|
||||
auto it = params.find(param_pair.second);
|
||||
|
||||
if (it == params.end()) {
|
||||
throw query::UnprovidedParameterError("Parameter ${} not provided.", param_pair.second);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -11,14 +11,23 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// THIS INCLUDE SHOULD ALWAYS COME BEFORE THE
|
||||
// "cypher_main_visitor.hpp"
|
||||
// "planner.hpp" includes json.hpp which uses libc's
|
||||
// EOF macro while "cypher_main_visitor.hpp" includes
|
||||
// "antlr4-runtime.h" which contains a static variable
|
||||
// of the same name, EOF.
|
||||
// This hides the definition of the macro which causes
|
||||
// the compilation to fail.
|
||||
#include "query/plan/planner.hpp"
|
||||
//////////////////////////////////////////////////////
|
||||
#include "query/config.hpp"
|
||||
#include "query/frontend/ast/cypher_main_visitor.hpp"
|
||||
#include "query/frontend/opencypher/parser.hpp"
|
||||
#include "query/frontend/semantic/required_privileges.hpp"
|
||||
#include "query/frontend/semantic/symbol_generator.hpp"
|
||||
#include "query/frontend/stripped.hpp"
|
||||
#include "query/plan/planner.hpp"
|
||||
#include "storage/v2/property_value.hpp"
|
||||
#include "utils/flag_validation.hpp"
|
||||
#include "utils/timer.hpp"
|
||||
|
||||
@@ -102,7 +111,7 @@ struct PlanCacheEntry {
|
||||
*/
|
||||
struct ParsedQuery {
|
||||
std::string query_string;
|
||||
storage::PropertyValue::TMap user_parameters;
|
||||
std::map<std::string, storage::PropertyValue> user_parameters;
|
||||
Parameters parameters;
|
||||
frontend::StrippedQuery stripped_query;
|
||||
AstStorage ast_storage;
|
||||
@@ -111,7 +120,7 @@ struct ParsedQuery {
|
||||
bool is_cacheable{true};
|
||||
};
|
||||
|
||||
ParsedQuery ParseQuery(const std::string &query_string, const storage::PropertyValue::TMap ¶ms,
|
||||
ParsedQuery ParseQuery(const std::string &query_string, const std::map<std::string, storage::PropertyValue> ¶ms,
|
||||
utils::SkipList<QueryCacheEntry> *cache, utils::SpinLock *antlr_lock,
|
||||
const InterpreterConfig::Query &query_config);
|
||||
|
||||
|
||||
@@ -217,11 +217,4 @@ class SettingConfigInMulticommandTxException final : public QueryException {
|
||||
SettingConfigInMulticommandTxException()
|
||||
: QueryException("Settings cannot be changed or fetched in multicommand transactions.") {}
|
||||
};
|
||||
|
||||
class VersionInfoInMulticommandTxException : public QueryException {
|
||||
public:
|
||||
VersionInfoInMulticommandTxException()
|
||||
: QueryException("Version info query not allowed in multicommand transactions.") {}
|
||||
};
|
||||
|
||||
} // namespace query
|
||||
|
||||
@@ -54,7 +54,9 @@ cpp<#
|
||||
size_t size = 0;
|
||||
slk::Load(&size, reader);
|
||||
self->${member}.resize(size);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
for (size_t i = 0;
|
||||
i < size;
|
||||
++i) {
|
||||
self->${member}[i] = query::LoadAstPointer<query::${type}>(storage, reader);
|
||||
}
|
||||
cpp<#))
|
||||
@@ -73,7 +75,9 @@ cpp<#
|
||||
#>cpp
|
||||
size_t size = 0;
|
||||
slk::Load(&size, reader);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
for (size_t i = 0;
|
||||
i < size;
|
||||
++i) {
|
||||
query::PropertyIx key;
|
||||
slk::Load(&key, reader, storage);
|
||||
auto *value = query::LoadAstPointer<query::Expression>(storage, reader);
|
||||
@@ -89,34 +93,6 @@ cpp<#
|
||||
}
|
||||
cpp<#)
|
||||
|
||||
(defun slk-save-expression-map (member)
|
||||
#>cpp
|
||||
size_t size = self.${member}.size();
|
||||
slk::Save(size, builder);
|
||||
for (const auto &entry : self.${member}) {
|
||||
query::SaveAstPointer(entry.first, builder);
|
||||
query::SaveAstPointer(entry.second, builder);
|
||||
}
|
||||
cpp<#)
|
||||
|
||||
(defun slk-load-expression-map (member)
|
||||
#>cpp
|
||||
size_t size = 0;
|
||||
slk::Load(&size, reader);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
auto *key = query::LoadAstPointer<query::Expression>(storage, reader);
|
||||
auto *value = query::LoadAstPointer<query::Expression>(storage, reader);
|
||||
self->${member}.emplace(key, value);
|
||||
}
|
||||
cpp<#)
|
||||
|
||||
(defun clone-expression-map (source dest)
|
||||
#>cpp
|
||||
for (const auto &[key, value] : ${source}) {
|
||||
${dest}[key->Clone(storage)] = value->Clone(storage);
|
||||
}
|
||||
cpp<#)
|
||||
|
||||
(defun slk-load-name-ix (name-type)
|
||||
(lambda (member)
|
||||
#>cpp
|
||||
@@ -1843,7 +1819,9 @@ cpp<#
|
||||
size_t size = 0;
|
||||
slk::Load(&size, reader);
|
||||
self->${member}.resize(size);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
for (size_t i = 0;
|
||||
i < size;
|
||||
++i) {
|
||||
slk::Load(&self->${member}[i], reader, storage);
|
||||
}
|
||||
cpp<#)
|
||||
@@ -2553,7 +2531,7 @@ cpp<#
|
||||
:slk-save #'slk-save-ast-pointer
|
||||
:slk-load (slk-load-ast-pointer "Expression"))
|
||||
|
||||
(topic_names "std::variant<Expression*, std::vector<std::string>>" :initval "nullptr"
|
||||
(topic_names "std::variant<Expression*, std::vector<std::string>>" :initval "nullptr"
|
||||
:clone #'clone-variant-topic-names
|
||||
:scope :public)
|
||||
(consumer_group "std::string" :scope :public)
|
||||
@@ -2563,17 +2541,7 @@ cpp<#
|
||||
|
||||
(service_url "Expression *" :initval "nullptr" :scope :public
|
||||
:slk-save #'slk-save-ast-pointer
|
||||
:slk-load (slk-load-ast-pointer "Expression"))
|
||||
|
||||
(configs "std::unordered_map<Expression *, Expression *>" :scope :public
|
||||
:slk-save #'slk-save-expression-map
|
||||
:slk-load #'slk-load-expression-map
|
||||
:clone #'clone-expression-map)
|
||||
|
||||
(credentials "std::unordered_map<Expression *, Expression *>" :scope :public
|
||||
:slk-save #'slk-save-expression-map
|
||||
:slk-load #'slk-load-expression-map
|
||||
:clone #'clone-expression-map))
|
||||
:slk-load (slk-load-ast-pointer "Expression")))
|
||||
|
||||
(:public
|
||||
(lcp:define-enum action
|
||||
@@ -2615,12 +2583,4 @@ cpp<#
|
||||
(:serialize (:slk))
|
||||
(:clone))
|
||||
|
||||
(lcp:define-class version-query (query) ()
|
||||
(:public
|
||||
#>cpp
|
||||
DEFVISITABLE(QueryVisitor<void>);
|
||||
cpp<#)
|
||||
(:serialize (:slk))
|
||||
(:clone))
|
||||
|
||||
(lcp:pop-namespace) ;; namespace query
|
||||
|
||||
@@ -92,7 +92,6 @@ class IsolationLevelQuery;
|
||||
class CreateSnapshotQuery;
|
||||
class StreamQuery;
|
||||
class SettingQuery;
|
||||
class VersionQuery;
|
||||
|
||||
using TreeCompositeVisitor = ::utils::CompositeVisitor<
|
||||
SingleQuery, CypherUnion, NamedExpression, OrOperator, XorOperator, AndOperator, NotOperator, AdditionOperator,
|
||||
@@ -124,9 +123,9 @@ class ExpressionVisitor
|
||||
None, ParameterLookup, Identifier, PrimitiveLiteral, RegexMatch> {};
|
||||
|
||||
template <class TResult>
|
||||
class QueryVisitor : public ::utils::Visitor<TResult, CypherQuery, ExplainQuery, ProfileQuery, IndexQuery, AuthQuery,
|
||||
InfoQuery, ConstraintQuery, DumpQuery, ReplicationQuery, LockPathQuery,
|
||||
FreeMemoryQuery, TriggerQuery, IsolationLevelQuery, CreateSnapshotQuery,
|
||||
StreamQuery, SettingQuery, VersionQuery> {};
|
||||
class QueryVisitor
|
||||
: public ::utils::Visitor<TResult, CypherQuery, ExplainQuery, ProfileQuery, IndexQuery, AuthQuery, InfoQuery,
|
||||
ConstraintQuery, DumpQuery, ReplicationQuery, LockPathQuery, FreeMemoryQuery,
|
||||
TriggerQuery, IsolationLevelQuery, CreateSnapshotQuery, StreamQuery, SettingQuery> {};
|
||||
|
||||
} // namespace query
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -9,6 +9,19 @@
|
||||
// by the Apache License, Version 2.0, included in the file
|
||||
// licenses/APL.txt.
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// THIS INCLUDE SHOULD ALWAYS COME BEFORE THE
|
||||
// "cypher_main_visitor.hpp"
|
||||
// "module.hpp" includes json.hpp which uses libc's
|
||||
// EOF macro while "cypher_main_visitor.hpp" includes
|
||||
// "antlr4-runtime.h" which contains a static variable
|
||||
// of the same name, EOF.
|
||||
// This hides the definition of the macro which causes
|
||||
// the compilation to fail.
|
||||
#include "query/frontend/ast/ast.hpp"
|
||||
#include "query/frontend/ast/ast_visitor.hpp"
|
||||
#include "query/procedure/module.hpp"
|
||||
//////////////////////////////////////////////////////
|
||||
#include "query/frontend/ast/cypher_main_visitor.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -28,11 +41,8 @@
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
|
||||
#include "query/exceptions.hpp"
|
||||
#include "query/frontend/ast/ast.hpp"
|
||||
#include "query/frontend/ast/ast_visitor.hpp"
|
||||
#include "query/frontend/parsing.hpp"
|
||||
#include "query/interpret/awesome_memgraph_functions.hpp"
|
||||
#include "query/procedure/module.hpp"
|
||||
#include "query/stream/common.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
@@ -554,7 +564,7 @@ std::string_view ToString(const CommonStreamConfigKey key) {
|
||||
__VA_ARGS__ \
|
||||
};
|
||||
|
||||
GENERATE_STREAM_CONFIG_KEY_ENUM(Kafka, TOPICS, CONSUMER_GROUP, BOOTSTRAP_SERVERS, CONFIGS, CREDENTIALS);
|
||||
GENERATE_STREAM_CONFIG_KEY_ENUM(Kafka, TOPICS, CONSUMER_GROUP, BOOTSTRAP_SERVERS);
|
||||
|
||||
std::string_view ToString(const KafkaConfigKey key) {
|
||||
switch (key) {
|
||||
@@ -564,10 +574,6 @@ std::string_view ToString(const KafkaConfigKey key) {
|
||||
return "CONSUMER_GROUP";
|
||||
case KafkaConfigKey::BOOTSTRAP_SERVERS:
|
||||
return "BOOTSTRAP_SERVERS";
|
||||
case KafkaConfigKey::CONFIGS:
|
||||
return "CONFIGS";
|
||||
case KafkaConfigKey::CREDENTIALS:
|
||||
return "CREDENTIALS";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -578,21 +584,6 @@ void MapCommonStreamConfigs(auto &memory, StreamQuery &stream_query) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
antlrcpp::Any CypherMainVisitor::visitConfigKeyValuePair(MemgraphCypher::ConfigKeyValuePairContext *ctx) {
|
||||
MG_ASSERT(ctx->literal().size() == 2);
|
||||
return std::pair{ctx->literal(0)->accept(this).as<Expression *>(), ctx->literal(1)->accept(this).as<Expression *>()};
|
||||
}
|
||||
|
||||
antlrcpp::Any CypherMainVisitor::visitConfigMap(MemgraphCypher::ConfigMapContext *ctx) {
|
||||
std::unordered_map<Expression *, Expression *> map;
|
||||
for (auto *key_value_pair : ctx->configKeyValuePair()) {
|
||||
// If the queries are cached, then only the stripped query is parsed, so the actual keys cannot be determined
|
||||
// here. That means duplicates cannot be checked.
|
||||
map.insert(key_value_pair->accept(this).as<std::pair<Expression *, Expression *>>());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
antlrcpp::Any CypherMainVisitor::visitKafkaCreateStream(MemgraphCypher::KafkaCreateStreamContext *ctx) {
|
||||
auto *stream_query = storage_->Create<StreamQuery>();
|
||||
stream_query->action_ = StreamQuery::Action::CREATE_STREAM;
|
||||
@@ -606,10 +597,6 @@ antlrcpp::Any CypherMainVisitor::visitKafkaCreateStream(MemgraphCypher::KafkaCre
|
||||
MapConfig<true, std::vector<std::string>, Expression *>(memory_, KafkaConfigKey::TOPICS, stream_query->topic_names_);
|
||||
MapConfig<false, std::string>(memory_, KafkaConfigKey::CONSUMER_GROUP, stream_query->consumer_group_);
|
||||
MapConfig<false, Expression *>(memory_, KafkaConfigKey::BOOTSTRAP_SERVERS, stream_query->bootstrap_servers_);
|
||||
MapConfig<false, std::unordered_map<Expression *, Expression *>>(memory_, KafkaConfigKey::CONFIGS,
|
||||
stream_query->configs_);
|
||||
MapConfig<false, std::unordered_map<Expression *, Expression *>>(memory_, KafkaConfigKey::CREDENTIALS,
|
||||
stream_query->credentials_);
|
||||
|
||||
MapCommonStreamConfigs(memory_, *stream_query);
|
||||
|
||||
@@ -645,33 +632,18 @@ antlrcpp::Any CypherMainVisitor::visitKafkaCreateStreamConfig(MemgraphCypher::Ka
|
||||
|
||||
if (ctx->TOPICS()) {
|
||||
ThrowIfExists(memory_, KafkaConfigKey::TOPICS);
|
||||
constexpr auto topics_key = static_cast<uint8_t>(KafkaConfigKey::TOPICS);
|
||||
const auto topics_key = static_cast<uint8_t>(KafkaConfigKey::TOPICS);
|
||||
GetTopicNames(memory_[topics_key], ctx->topicNames(), *this);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (ctx->CONSUMER_GROUP()) {
|
||||
ThrowIfExists(memory_, KafkaConfigKey::CONSUMER_GROUP);
|
||||
constexpr auto consumer_group_key = static_cast<uint8_t>(KafkaConfigKey::CONSUMER_GROUP);
|
||||
const auto consumer_group_key = static_cast<uint8_t>(KafkaConfigKey::CONSUMER_GROUP);
|
||||
memory_[consumer_group_key] = JoinSymbolicNamesWithDotsAndMinus(*this, *ctx->consumerGroup);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (ctx->CONFIGS()) {
|
||||
ThrowIfExists(memory_, KafkaConfigKey::CONFIGS);
|
||||
constexpr auto configs_key = static_cast<uint8_t>(KafkaConfigKey::CONFIGS);
|
||||
memory_.emplace(configs_key, ctx->configsMap->accept(this).as<std::unordered_map<Expression *, Expression *>>());
|
||||
return {};
|
||||
}
|
||||
|
||||
if (ctx->CREDENTIALS()) {
|
||||
ThrowIfExists(memory_, KafkaConfigKey::CREDENTIALS);
|
||||
constexpr auto credentials_key = static_cast<uint8_t>(KafkaConfigKey::CREDENTIALS);
|
||||
memory_.emplace(credentials_key,
|
||||
ctx->credentialsMap->accept(this).as<std::unordered_map<Expression *, Expression *>>());
|
||||
return {};
|
||||
}
|
||||
|
||||
MG_ASSERT(ctx->BOOTSTRAP_SERVERS());
|
||||
ThrowIfExists(memory_, KafkaConfigKey::BOOTSTRAP_SERVERS);
|
||||
if (!ctx->bootstrapServers->StringLiteral()) {
|
||||
@@ -870,12 +842,6 @@ antlrcpp::Any CypherMainVisitor::visitShowSettings(MemgraphCypher::ShowSettingsC
|
||||
return setting_query;
|
||||
}
|
||||
|
||||
antlrcpp::Any CypherMainVisitor::visitVersionQuery(MemgraphCypher::VersionQueryContext * /*ctx*/) {
|
||||
auto *version_query = storage_->Create<VersionQuery>();
|
||||
query_ = version_query;
|
||||
return version_query;
|
||||
}
|
||||
|
||||
antlrcpp::Any CypherMainVisitor::visitCypherUnion(MemgraphCypher::CypherUnionContext *ctx) {
|
||||
bool distinct = !ctx->ALL();
|
||||
auto *cypher_union = storage_->Create<CypherUnion>(distinct);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -269,16 +269,6 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
|
||||
*/
|
||||
antlrcpp::Any visitCreateStream(MemgraphCypher::CreateStreamContext *ctx) override;
|
||||
|
||||
/**
|
||||
* @return StreamQuery*
|
||||
*/
|
||||
antlrcpp::Any visitConfigKeyValuePair(MemgraphCypher::ConfigKeyValuePairContext *ctx) override;
|
||||
|
||||
/**
|
||||
* @return StreamQuery*
|
||||
*/
|
||||
antlrcpp::Any visitConfigMap(MemgraphCypher::ConfigMapContext *ctx) override;
|
||||
|
||||
/**
|
||||
* @return StreamQuery*
|
||||
*/
|
||||
@@ -359,11 +349,6 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
|
||||
*/
|
||||
antlrcpp::Any visitShowSettings(MemgraphCypher::ShowSettingsContext *ctx) override;
|
||||
|
||||
/**
|
||||
* @return VersionQuery*
|
||||
*/
|
||||
antlrcpp::Any visitVersionQuery(MemgraphCypher::VersionQueryContext *ctx) override;
|
||||
|
||||
/**
|
||||
* @return CypherUnion*
|
||||
*/
|
||||
@@ -864,9 +849,7 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
|
||||
ParsingContext context_;
|
||||
AstStorage *storage_;
|
||||
|
||||
std::unordered_map<uint8_t, std::variant<Expression *, std::string, std::vector<std::string>,
|
||||
std::unordered_map<Expression *, Expression *>>>
|
||||
memory_;
|
||||
std::unordered_map<uint8_t, std::variant<Expression *, std::string, std::vector<std::string>>> memory_;
|
||||
// Set of identifiers from queries.
|
||||
std::unordered_set<std::string> users_identifiers;
|
||||
// Identifiers that user didn't name.
|
||||
|
||||
@@ -83,7 +83,6 @@ template <typename T>
|
||||
void PrintObject(std::ostream *out, const T &arg);
|
||||
|
||||
void PrintObject(std::ostream *out, const std::string &str);
|
||||
void PrintObject(std::ostream *out, const utils::pmr::string &str);
|
||||
|
||||
void PrintObject(std::ostream *out, Aggregation::Op op);
|
||||
|
||||
@@ -96,15 +95,9 @@ void PrintObject(std::ostream *out, const storage::PropertyValue &value);
|
||||
template <typename T>
|
||||
void PrintObject(std::ostream *out, const std::vector<T> &vec);
|
||||
|
||||
template <typename T>
|
||||
void PrintObject(std::ostream *out, const utils::pmr::vector<T> &vec);
|
||||
|
||||
template <typename K, typename V>
|
||||
void PrintObject(std::ostream *out, const std::map<K, V> &map);
|
||||
|
||||
template <typename K, typename V>
|
||||
void PrintObject(std::ostream *out, const utils::pmr::map<K, V> &map);
|
||||
|
||||
template <typename T>
|
||||
void PrintObject(std::ostream *out, const T &arg) {
|
||||
static_assert(!std::is_convertible<T, Expression *>::value,
|
||||
@@ -116,7 +109,6 @@ void PrintObject(std::ostream *out, const T &arg) {
|
||||
}
|
||||
|
||||
void PrintObject(std::ostream *out, const std::string &str) { *out << utils::Escape(str); }
|
||||
void PrintObject(std::ostream *out, const utils::pmr::string &str) { *out << utils::Escape(str); }
|
||||
|
||||
void PrintObject(std::ostream *out, Aggregation::Op op) { *out << Aggregation::OpToString(op); }
|
||||
|
||||
@@ -173,13 +165,6 @@ void PrintObject(std::ostream *out, const std::vector<T> &vec) {
|
||||
*out << "]";
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void PrintObject(std::ostream *out, const utils::pmr::vector<T> &vec) {
|
||||
*out << "[";
|
||||
utils::PrintIterable(*out, vec, ", ", [](auto &stream, const auto &item) { PrintObject(&stream, item); });
|
||||
*out << "]";
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void PrintObject(std::ostream *out, const std::map<K, V> &map) {
|
||||
*out << "{";
|
||||
@@ -191,17 +176,6 @@ void PrintObject(std::ostream *out, const std::map<K, V> &map) {
|
||||
*out << "}";
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
void PrintObject(std::ostream *out, const utils::pmr::map<K, V> &map) {
|
||||
*out << "{";
|
||||
utils::PrintIterable(*out, map, ", ", [](auto &stream, const auto &item) {
|
||||
PrintObject(&stream, item.first);
|
||||
stream << ": ";
|
||||
PrintObject(&stream, item.second);
|
||||
});
|
||||
*out << "}";
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void PrintOperatorArgs(std::ostream *out, const T &arg) {
|
||||
*out << " ";
|
||||
|
||||
@@ -35,9 +35,7 @@ memgraphCypherKeyword : cypherKeyword
|
||||
| COMMIT
|
||||
| COMMITTED
|
||||
| CONFIG
|
||||
| CONFIGS
|
||||
| CONSUMER_GROUP
|
||||
| CREDENTIALS
|
||||
| CSV
|
||||
| DATA
|
||||
| DELIMITER
|
||||
@@ -54,7 +52,6 @@ memgraphCypherKeyword : cypherKeyword
|
||||
| HEADER
|
||||
| IDENTIFIED
|
||||
| ISOLATION
|
||||
| KAFKA
|
||||
| LEVEL
|
||||
| LOAD
|
||||
| LOCK
|
||||
@@ -63,7 +60,6 @@ memgraphCypherKeyword : cypherKeyword
|
||||
| NEXT
|
||||
| NO
|
||||
| PASSWORD
|
||||
| PULSAR
|
||||
| PORT
|
||||
| PRIVILEGES
|
||||
| READ
|
||||
@@ -96,7 +92,6 @@ memgraphCypherKeyword : cypherKeyword
|
||||
| UPDATE
|
||||
| USER
|
||||
| USERS
|
||||
| VERSION
|
||||
;
|
||||
|
||||
symbolicName : UnescapedSymbolicName
|
||||
@@ -120,7 +115,6 @@ query : cypherQuery
|
||||
| createSnapshotQuery
|
||||
| streamQuery
|
||||
| settingQuery
|
||||
| versionQuery
|
||||
;
|
||||
|
||||
authQuery : createRole
|
||||
@@ -312,15 +306,9 @@ commonCreateStreamConfig : TRANSFORM transformationName=procedureName
|
||||
|
||||
createStream : kafkaCreateStream | pulsarCreateStream ;
|
||||
|
||||
configKeyValuePair : literal ':' literal ;
|
||||
|
||||
configMap : '{' ( configKeyValuePair ( ',' configKeyValuePair )* )? '}' ;
|
||||
|
||||
kafkaCreateStreamConfig : TOPICS topicNames
|
||||
| CONSUMER_GROUP consumerGroup=symbolicNameWithDotsAndMinus
|
||||
| BOOTSTRAP_SERVERS bootstrapServers=literal
|
||||
| CONFIGS configsMap=configMap
|
||||
| CREDENTIALS credentialsMap=configMap
|
||||
| commonCreateStreamConfig
|
||||
;
|
||||
|
||||
@@ -357,5 +345,3 @@ setSetting : SET DATABASE SETTING settingName TO settingValue ;
|
||||
showSetting : SHOW DATABASE SETTING settingName ;
|
||||
|
||||
showSettings : SHOW DATABASE SETTINGS ;
|
||||
|
||||
versionQuery : SHOW VERSION ;
|
||||
|
||||
@@ -40,9 +40,7 @@ CLEAR : C L E A R ;
|
||||
COMMIT : C O M M I T ;
|
||||
COMMITTED : C O M M I T T E D ;
|
||||
CONFIG : C O N F I G ;
|
||||
CONFIGS : C O N F I G S;
|
||||
CONSUMER_GROUP : C O N S U M E R UNDERSCORE G R O U P ;
|
||||
CREDENTIALS : C R E D E N T I A L S ;
|
||||
CSV : C S V ;
|
||||
DATA : D A T A ;
|
||||
DELIMITER : D E L I M I T E R ;
|
||||
@@ -109,4 +107,3 @@ UNLOCK : U N L O C K ;
|
||||
UPDATE : U P D A T E ;
|
||||
USER : U S E R ;
|
||||
USERS : U S E R S ;
|
||||
VERSION : V E R S I O N ;
|
||||
|
||||
@@ -76,8 +76,6 @@ class PrivilegeExtractor : public QueryVisitor<void>, public HierarchicalTreeVis
|
||||
|
||||
void Visit(SettingQuery & /*setting_query*/) override { AddPrivilege(AuthQuery::Privilege::CONFIG); }
|
||||
|
||||
void Visit(VersionQuery & /*version_query*/) override { AddPrivilege(AuthQuery::Privilege::STATS); }
|
||||
|
||||
bool PreVisit(Create & /*unused*/) override {
|
||||
AddPrivilege(AuthQuery::Privilege::CREATE);
|
||||
return false;
|
||||
|
||||
@@ -202,8 +202,7 @@ const trie::Trie kKeywords = {"union",
|
||||
"bootstrap_servers",
|
||||
"kafka",
|
||||
"pulsar",
|
||||
"service_url",
|
||||
"version"};
|
||||
"service_url"};
|
||||
|
||||
// Unicode codepoints that are allowed at the start of the unescaped name.
|
||||
const std::bitset<kBitsetSize> kUnescapedNameAllowedStarts(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -1080,7 +1080,7 @@ void MapNumericParameters(auto ¶meter_mappings, const auto &input_parameters
|
||||
TypedValue Date(const TypedValue *args, int64_t nargs, const FunctionContext &ctx) {
|
||||
FType<Optional<Or<String, Map>>>("date", args, nargs);
|
||||
if (nargs == 0) {
|
||||
return TypedValue(utils::LocalDateTime(ctx.timestamp).date, ctx.memory);
|
||||
return TypedValue(utils::UtcToday(), ctx.memory);
|
||||
}
|
||||
|
||||
if (args[0].IsString()) {
|
||||
@@ -1103,7 +1103,7 @@ TypedValue LocalTime(const TypedValue *args, int64_t nargs, const FunctionContex
|
||||
FType<Optional<Or<String, Map>>>("localtime", args, nargs);
|
||||
|
||||
if (nargs == 0) {
|
||||
return TypedValue(utils::LocalDateTime(ctx.timestamp).local_time, ctx.memory);
|
||||
return TypedValue(utils::UtcLocalTime(), ctx.memory);
|
||||
}
|
||||
|
||||
if (args[0].IsString()) {
|
||||
@@ -1130,7 +1130,7 @@ TypedValue LocalDateTime(const TypedValue *args, int64_t nargs, const FunctionCo
|
||||
FType<Optional<Or<String, Map>>>("localdatetime", args, nargs);
|
||||
|
||||
if (nargs == 0) {
|
||||
return TypedValue(utils::LocalDateTime(ctx.timestamp), ctx.memory);
|
||||
return TypedValue(utils::UtcLocalDateTime(), ctx.memory);
|
||||
}
|
||||
|
||||
if (args[0].IsString()) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -564,26 +564,10 @@ Callback::CallbackFunction GetKafkaCreateCallback(StreamQuery *stream_query, Exp
|
||||
}
|
||||
auto common_stream_info = GetCommonStreamInfo(stream_query, evaluator);
|
||||
|
||||
const auto get_config_map = [&evaluator](std::unordered_map<Expression *, Expression *> map,
|
||||
std::string_view map_name) -> std::unordered_map<std::string, std::string> {
|
||||
std::unordered_map<std::string, std::string> config_map;
|
||||
for (const auto [key_expr, value_expr] : map) {
|
||||
const auto key = key_expr->Accept(evaluator);
|
||||
const auto value = value_expr->Accept(evaluator);
|
||||
if (!key.IsString() || !value.IsString()) {
|
||||
throw SemanticException("{} must contain only string keys and values!", map_name);
|
||||
}
|
||||
config_map.emplace(key.ValueString(), value.ValueString());
|
||||
}
|
||||
return config_map;
|
||||
};
|
||||
|
||||
return [interpreter_context, stream_name = stream_query->stream_name_,
|
||||
topic_names = EvaluateTopicNames(evaluator, stream_query->topic_names_),
|
||||
consumer_group = std::move(consumer_group), common_stream_info = std::move(common_stream_info),
|
||||
bootstrap_servers = std::move(bootstrap), owner = StringPointerToOptional(username),
|
||||
configs = get_config_map(stream_query->configs_, "Configs"),
|
||||
credentials = get_config_map(stream_query->credentials_, "Credentials")]() mutable {
|
||||
bootstrap_servers = std::move(bootstrap), owner = StringPointerToOptional(username)]() mutable {
|
||||
std::string bootstrap = bootstrap_servers
|
||||
? std::move(*bootstrap_servers)
|
||||
: std::string{interpreter_context->config.default_kafka_bootstrap_servers};
|
||||
@@ -591,9 +575,7 @@ Callback::CallbackFunction GetKafkaCreateCallback(StreamQuery *stream_query, Exp
|
||||
{.common_info = std::move(common_stream_info),
|
||||
.topics = std::move(topic_names),
|
||||
.consumer_group = std::move(consumer_group),
|
||||
.bootstrap_servers = std::move(bootstrap),
|
||||
.configs = std::move(configs),
|
||||
.credentials = std::move(credentials)},
|
||||
.bootstrap_servers = std::move(bootstrap)},
|
||||
std::move(owner));
|
||||
|
||||
return std::vector<std::vector<TypedValue>>{};
|
||||
@@ -908,7 +890,7 @@ std::optional<plan::ProfilingStatsWithTotalTime> PullPlan::Pull(AnyStream *strea
|
||||
// Also, we want to throw only when the query engine requests more memory and not the storage
|
||||
// so we add the exception to the allocator.
|
||||
// TODO (mferencevic): Tune the parameters accordingly.
|
||||
utils::FixedSizePoolResource pool_memory(128, 1024, &monotonic_memory);
|
||||
utils::PoolResource pool_memory(128, 1024, &monotonic_memory);
|
||||
std::optional<utils::LimitedMemoryResource> maybe_limited_resource;
|
||||
|
||||
if (memory_limit_) {
|
||||
@@ -1503,7 +1485,8 @@ TriggerEventType ToTriggerEventType(const TriggerQuery::EventType event_type) {
|
||||
}
|
||||
}
|
||||
|
||||
Callback CreateTrigger(TriggerQuery *trigger_query, const storage::PropertyValue::TMap &user_parameters,
|
||||
Callback CreateTrigger(TriggerQuery *trigger_query,
|
||||
const std::map<std::string, storage::PropertyValue> &user_parameters,
|
||||
InterpreterContext *interpreter_context, DbAccessor *dba, std::optional<std::string> owner) {
|
||||
return {
|
||||
{},
|
||||
@@ -1553,7 +1536,7 @@ Callback ShowTriggers(InterpreterContext *interpreter_context) {
|
||||
|
||||
PreparedQuery PrepareTriggerQuery(ParsedQuery parsed_query, const bool in_explicit_transaction,
|
||||
std::vector<Notification> *notifications, InterpreterContext *interpreter_context,
|
||||
DbAccessor *dba, const storage::PropertyValue::TMap &user_parameters,
|
||||
DbAccessor *dba, const std::map<std::string, storage::PropertyValue> &user_parameters,
|
||||
const std::string *username) {
|
||||
if (in_explicit_transaction) {
|
||||
throw TriggerModificationInMulticommandTxException();
|
||||
@@ -1603,7 +1586,8 @@ PreparedQuery PrepareTriggerQuery(ParsedQuery parsed_query, const bool in_explic
|
||||
|
||||
PreparedQuery PrepareStreamQuery(ParsedQuery parsed_query, const bool in_explicit_transaction,
|
||||
std::vector<Notification> *notifications, InterpreterContext *interpreter_context,
|
||||
DbAccessor *dba, const storage::PropertyValue::TMap & /*user_parameters*/,
|
||||
DbAccessor *dba,
|
||||
const std::map<std::string, storage::PropertyValue> & /*user_parameters*/,
|
||||
const std::string *username) {
|
||||
if (in_explicit_transaction) {
|
||||
throw StreamQueryInMulticommandTxException();
|
||||
@@ -1723,24 +1707,6 @@ PreparedQuery PrepareSettingQuery(ParsedQuery parsed_query, const bool in_explic
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
}
|
||||
|
||||
PreparedQuery PrepareVersionQuery(ParsedQuery parsed_query, const bool in_explicit_transaction) {
|
||||
if (in_explicit_transaction) {
|
||||
throw VersionInfoInMulticommandTxException();
|
||||
}
|
||||
|
||||
return PreparedQuery{{"version"},
|
||||
std::move(parsed_query.required_privileges),
|
||||
[](AnyStream *stream, std::optional<int> /*n*/) {
|
||||
std::vector<TypedValue> version_value;
|
||||
version_value.reserve(1);
|
||||
|
||||
version_value.emplace_back(gflags::VersionString());
|
||||
stream->Result(version_value);
|
||||
return QueryHandlerResult::COMMIT;
|
||||
},
|
||||
RWType::NONE};
|
||||
}
|
||||
|
||||
PreparedQuery PrepareInfoQuery(ParsedQuery parsed_query, bool in_explicit_transaction,
|
||||
std::map<std::string, TypedValue> *summary, InterpreterContext *interpreter_context,
|
||||
storage::Storage *db, utils::MemoryResource *execution_memory) {
|
||||
@@ -2031,7 +1997,7 @@ void Interpreter::RollbackTransaction() {
|
||||
}
|
||||
|
||||
Interpreter::PrepareResult Interpreter::Prepare(const std::string &query_string,
|
||||
const storage::PropertyValue::TMap ¶ms,
|
||||
const std::map<std::string, storage::PropertyValue> ¶ms,
|
||||
const std::string *username) {
|
||||
if (!in_explicit_transaction_) {
|
||||
query_executions_.clear();
|
||||
@@ -2144,8 +2110,6 @@ Interpreter::PrepareResult Interpreter::Prepare(const std::string &query_string,
|
||||
PrepareCreateSnapshotQuery(std::move(parsed_query), in_explicit_transaction_, interpreter_context_);
|
||||
} else if (utils::Downcast<SettingQuery>(parsed_query.query)) {
|
||||
prepared_query = PrepareSettingQuery(std::move(parsed_query), in_explicit_transaction_, &*execution_db_accessor_);
|
||||
} else if (utils::Downcast<VersionQuery>(parsed_query.query)) {
|
||||
prepared_query = PrepareVersionQuery(std::move(parsed_query), in_explicit_transaction_);
|
||||
} else {
|
||||
LOG_FATAL("Should not get here -- unknown query type!");
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ class Interpreter final {
|
||||
*
|
||||
* @throw query::QueryException
|
||||
*/
|
||||
PrepareResult Prepare(const std::string &query, const storage::PropertyValue::TMap ¶ms,
|
||||
PrepareResult Prepare(const std::string &query, const std::map<std::string, storage::PropertyValue> ¶ms,
|
||||
const std::string *username);
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
// License, and you may not use this file except in compliance with the Business Source License.
|
||||
//
|
||||
// As of the Change Date specified in that file, in accordance with
|
||||
// the Business Source License, use of this software will be governed
|
||||
// by the Apache License, Version 2.0, included in the file
|
||||
// licenses/APL.txt.
|
||||
|
||||
#include "query/procedure/mg_procedure_helpers.hpp"
|
||||
|
||||
namespace query::procedure {
|
||||
MgpUniquePtr<mgp_value> GetStringValueOrSetError(const char *string, mgp_memory *memory, mgp_result *result) {
|
||||
procedure::MgpUniquePtr<mgp_value> value{nullptr, mgp_value_destroy};
|
||||
const auto success =
|
||||
TryOrSetError([&] { return procedure::CreateMgpObject(value, mgp_value_make_string, string, memory); }, result);
|
||||
if (!success) {
|
||||
value.reset();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
bool InsertResultOrSetError(mgp_result *result, mgp_result_record *record, const char *result_name, mgp_value *value) {
|
||||
if (const auto err = mgp_result_record_insert(record, result_name, value); err != MGP_ERROR_NO_ERROR) {
|
||||
const auto error_msg = fmt::format("Unable to set the result for {}, error = {}", result_name, err);
|
||||
static_cast<void>(mgp_result_set_error_msg(result, error_msg.c_str()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace query::procedure
|
||||
@@ -15,8 +15,6 @@
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "mg_procedure.h"
|
||||
|
||||
namespace query::procedure {
|
||||
@@ -47,23 +45,4 @@ mgp_error CreateMgpObject(MgpUniquePtr<TObj> &obj, TFunc func, TArgs &&...args)
|
||||
obj.reset(raw_obj);
|
||||
return err;
|
||||
}
|
||||
|
||||
template <typename Fun>
|
||||
[[nodiscard]] bool TryOrSetError(Fun &&func, mgp_result *result) {
|
||||
if (const auto err = func(); err == MGP_ERROR_UNABLE_TO_ALLOCATE) {
|
||||
static_cast<void>(mgp_result_set_error_msg(result, "Not enough memory!"));
|
||||
return false;
|
||||
} else if (err != MGP_ERROR_NO_ERROR) {
|
||||
const auto error_msg = fmt::format("Unexpected error ({})!", err);
|
||||
static_cast<void>(mgp_result_set_error_msg(result, error_msg.c_str()));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] MgpUniquePtr<mgp_value> GetStringValueOrSetError(const char *string, mgp_memory *memory,
|
||||
mgp_result *result);
|
||||
|
||||
[[nodiscard]] bool InsertResultOrSetError(mgp_result *result, mgp_result_record *record, const char *result_name,
|
||||
mgp_value *value);
|
||||
} // namespace query::procedure
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -1178,7 +1178,7 @@ mgp_error mgp_date_timestamp(mgp_date *date, int64_t *timestamp) {
|
||||
}
|
||||
|
||||
mgp_error mgp_date_now(mgp_memory *memory, mgp_date **date) {
|
||||
return WrapExceptions([memory] { return NewRawMgpObject<mgp_date>(memory, utils::CurrentDate()); }, date);
|
||||
return WrapExceptions([memory] { return NewRawMgpObject<mgp_date>(memory, utils::UtcToday()); }, date);
|
||||
}
|
||||
|
||||
mgp_error mgp_date_add_duration(mgp_date *date, mgp_duration *dur, mgp_memory *memory, mgp_date **result) {
|
||||
@@ -1241,7 +1241,7 @@ mgp_error mgp_local_time_timestamp(mgp_local_time *local_time, int64_t *timestam
|
||||
}
|
||||
|
||||
mgp_error mgp_local_time_now(mgp_memory *memory, mgp_local_time **local_time) {
|
||||
return WrapExceptions([memory] { return NewRawMgpObject<mgp_local_time>(memory, utils::CurrentLocalTime()); },
|
||||
return WrapExceptions([memory] { return NewRawMgpObject<mgp_local_time>(memory, utils::UtcLocalTime()); },
|
||||
local_time);
|
||||
}
|
||||
|
||||
@@ -1334,9 +1334,8 @@ mgp_error mgp_local_date_time_timestamp(mgp_local_date_time *local_date_time, in
|
||||
}
|
||||
|
||||
mgp_error mgp_local_date_time_now(mgp_memory *memory, mgp_local_date_time **local_date_time) {
|
||||
return WrapExceptions(
|
||||
[memory] { return NewRawMgpObject<mgp_local_date_time>(memory, utils::CurrentLocalDateTime()); },
|
||||
local_date_time);
|
||||
return WrapExceptions([memory] { return NewRawMgpObject<mgp_local_date_time>(memory, utils::UtcLocalDateTime()); },
|
||||
local_date_time);
|
||||
}
|
||||
|
||||
mgp_error mgp_local_date_time_add_duration(mgp_local_date_time *local_date_time, mgp_duration *dur, mgp_memory *memory,
|
||||
@@ -1520,7 +1519,7 @@ storage::PropertyValue ToPropertyValue(const mgp_map &map) {
|
||||
storage::PropertyValue result{std::map<std::string, storage::PropertyValue>{}};
|
||||
auto &result_map = result.ValueMap();
|
||||
for (const auto &[key, value] : map.items) {
|
||||
result_map.insert_or_assign(utils::pmr::string{key}, ToPropertyValue(value));
|
||||
result_map.insert_or_assign(std::string{key}, ToPropertyValue(value));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
|
||||
@@ -18,9 +18,7 @@ extern "C" {
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "fmt/format.h"
|
||||
#include "py/py.hpp"
|
||||
#include "query/procedure/mg_procedure_helpers.hpp"
|
||||
#include "query/procedure/py_module.hpp"
|
||||
@@ -55,8 +53,6 @@ class BuiltinModule final : public Module {
|
||||
|
||||
void AddTransformation(std::string_view name, mgp_trans trans);
|
||||
|
||||
std::optional<std::filesystem::path> Path() const override { return std::nullopt; }
|
||||
|
||||
private:
|
||||
/// Registered procedures
|
||||
std::map<std::string, mgp_proc, std::less<>> procedures_;
|
||||
@@ -137,20 +133,6 @@ void RegisterMgLoad(ModuleRegistry *module_registry, utils::RWLock *lock, Builti
|
||||
module->AddProcedure("load", std::move(load));
|
||||
}
|
||||
|
||||
namespace {
|
||||
[[nodiscard]] bool IsFileEditable(const std::optional<std::filesystem::path> &path) {
|
||||
return path && access(path->c_str(), W_OK) == 0;
|
||||
}
|
||||
|
||||
std::string GetPathString(const std::optional<std::filesystem::path> &path) {
|
||||
if (!path) {
|
||||
return "builtin";
|
||||
}
|
||||
|
||||
return std::filesystem::canonical(*path).generic_string();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void RegisterMgProcedures(
|
||||
// We expect modules to be sorted by name.
|
||||
const std::map<std::string, std::unique_ptr<Module>, std::less<>> *all_modules, BuiltinModule *module) {
|
||||
@@ -165,80 +147,57 @@ void RegisterMgProcedures(
|
||||
static_assert(
|
||||
std::is_same_v<decltype(module->Procedures()), const std::map<std::string, mgp_proc, std::less<>> *>,
|
||||
"Expected module procedures to be sorted by name");
|
||||
|
||||
const auto path = module->Path();
|
||||
const auto path_string = GetPathString(path);
|
||||
const auto is_editable = IsFileEditable(path);
|
||||
|
||||
for (const auto &[proc_name, proc] : *module->Procedures()) {
|
||||
mgp_result_record *record{nullptr};
|
||||
{
|
||||
const auto success = TryOrSetError([&] { return mgp_result_new_record(result, &record); }, result);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const auto path_value = GetStringValueOrSetError(path_string.c_str(), memory, result);
|
||||
if (!path_value) {
|
||||
if (const auto err = mgp_result_new_record(result, &record); err == MGP_ERROR_UNABLE_TO_ALLOCATE) {
|
||||
static_cast<void>(mgp_result_set_error_msg(result, "Not enough memory!"));
|
||||
return;
|
||||
} else if (err != MGP_ERROR_NO_ERROR) {
|
||||
static_cast<void>(mgp_result_set_error_msg(result, "Unexpected error"));
|
||||
return;
|
||||
}
|
||||
|
||||
MgpUniquePtr<mgp_value> is_editable_value{nullptr, mgp_value_destroy};
|
||||
{
|
||||
const auto success = TryOrSetError(
|
||||
[&] { return CreateMgpObject(is_editable_value, mgp_value_make_bool, is_editable, memory); }, result);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
utils::pmr::string full_name(module_name, memory->impl);
|
||||
full_name.append(1, '.');
|
||||
full_name.append(proc_name);
|
||||
const auto name_value = GetStringValueOrSetError(full_name.c_str(), memory, result);
|
||||
if (!name_value) {
|
||||
MgpUniquePtr<mgp_value> name_value{nullptr, mgp_value_destroy};
|
||||
if (const auto err = CreateMgpObject(name_value, mgp_value_make_string, full_name.c_str(), memory);
|
||||
err == MGP_ERROR_UNABLE_TO_ALLOCATE) {
|
||||
static_cast<void>(mgp_result_set_error_msg(result, "Not enough memory!"));
|
||||
return;
|
||||
} else if (err != MGP_ERROR_NO_ERROR) {
|
||||
static_cast<void>(mgp_result_set_error_msg(result, "Unexpected error"));
|
||||
return;
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << module_name << ".";
|
||||
PrintProcSignature(proc, &ss);
|
||||
const auto signature = ss.str();
|
||||
const auto signature_value = GetStringValueOrSetError(signature.c_str(), memory, result);
|
||||
if (!signature_value) {
|
||||
MgpUniquePtr<mgp_value> signature_value{nullptr, mgp_value_destroy};
|
||||
if (const auto err = CreateMgpObject(signature_value, mgp_value_make_string, signature.c_str(), memory);
|
||||
err == MGP_ERROR_UNABLE_TO_ALLOCATE) {
|
||||
static_cast<void>(mgp_result_set_error_msg(result, "Not enough memory!"));
|
||||
return;
|
||||
} else if (err != MGP_ERROR_NO_ERROR) {
|
||||
static_cast<void>(mgp_result_set_error_msg(result, "Unexpected error"));
|
||||
return;
|
||||
}
|
||||
|
||||
MgpUniquePtr<mgp_value> is_write_value{nullptr, mgp_value_destroy};
|
||||
{
|
||||
const auto success = TryOrSetError(
|
||||
[&, &proc = proc] {
|
||||
return CreateMgpObject(is_write_value, mgp_value_make_bool, proc.is_write_procedure ? 1 : 0, memory);
|
||||
},
|
||||
result);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!InsertResultOrSetError(result, record, "name", name_value.get())) {
|
||||
if (const auto err =
|
||||
CreateMgpObject(is_write_value, mgp_value_make_bool, proc.is_write_procedure ? 1 : 0, memory);
|
||||
err == MGP_ERROR_UNABLE_TO_ALLOCATE) {
|
||||
static_cast<void>(mgp_result_set_error_msg(result, "Not enough memory!"));
|
||||
return;
|
||||
} else if (err != MGP_ERROR_NO_ERROR) {
|
||||
static_cast<void>(mgp_result_set_error_msg(result, "Unexpected error"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!InsertResultOrSetError(result, record, "signature", signature_value.get())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!InsertResultOrSetError(result, record, "is_write", is_write_value.get())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!InsertResultOrSetError(result, record, "path", path_value.get())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!InsertResultOrSetError(result, record, "is_editable", is_editable_value.get())) {
|
||||
const auto err1 = mgp_result_record_insert(record, "name", name_value.get());
|
||||
const auto err2 = mgp_result_record_insert(record, "signature", signature_value.get());
|
||||
const auto err3 = mgp_result_record_insert(record, "is_write", is_write_value.get());
|
||||
if (err1 != MGP_ERROR_NO_ERROR || err2 != MGP_ERROR_NO_ERROR || err3 != MGP_ERROR_NO_ERROR) {
|
||||
static_cast<void>(mgp_result_set_error_msg(result, "Unable to set the result!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -248,8 +207,6 @@ void RegisterMgProcedures(
|
||||
MG_ASSERT(mgp_proc_add_result(&procedures, "name", Call<mgp_type *>(mgp_type_string)) == MGP_ERROR_NO_ERROR);
|
||||
MG_ASSERT(mgp_proc_add_result(&procedures, "signature", Call<mgp_type *>(mgp_type_string)) == MGP_ERROR_NO_ERROR);
|
||||
MG_ASSERT(mgp_proc_add_result(&procedures, "is_write", Call<mgp_type *>(mgp_type_bool)) == MGP_ERROR_NO_ERROR);
|
||||
MG_ASSERT(mgp_proc_add_result(&procedures, "path", Call<mgp_type *>(mgp_type_string)) == MGP_ERROR_NO_ERROR);
|
||||
MG_ASSERT(mgp_proc_add_result(&procedures, "is_editable", Call<mgp_type *>(mgp_type_bool)) == MGP_ERROR_NO_ERROR);
|
||||
module->AddProcedure("procedures", std::move(procedures));
|
||||
}
|
||||
|
||||
@@ -262,52 +219,32 @@ void RegisterMgTransformations(const std::map<std::string, std::unique_ptr<Modul
|
||||
static_assert(
|
||||
std::is_same_v<decltype(module->Transformations()), const std::map<std::string, mgp_trans, std::less<>> *>,
|
||||
"Expected module transformations to be sorted by name");
|
||||
|
||||
const auto path = module->Path();
|
||||
const auto path_string = GetPathString(path);
|
||||
const auto is_editable = IsFileEditable(path);
|
||||
|
||||
for (const auto &[trans_name, proc] : *module->Transformations()) {
|
||||
mgp_result_record *record{nullptr};
|
||||
{
|
||||
const auto success = TryOrSetError([&] { return mgp_result_new_record(result, &record); }, result);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const auto path_value = GetStringValueOrSetError(path_string.c_str(), memory, result);
|
||||
if (!path_value) {
|
||||
if (const auto err = mgp_result_new_record(result, &record); err == MGP_ERROR_UNABLE_TO_ALLOCATE) {
|
||||
static_cast<void>(mgp_result_set_error_msg(result, "Not enough memory!"));
|
||||
return;
|
||||
} else if (err != MGP_ERROR_NO_ERROR) {
|
||||
static_cast<void>(mgp_result_set_error_msg(result, "Unexpected error"));
|
||||
return;
|
||||
}
|
||||
|
||||
MgpUniquePtr<mgp_value> is_editable_value{nullptr, mgp_value_destroy};
|
||||
{
|
||||
const auto success = TryOrSetError(
|
||||
[&] { return CreateMgpObject(is_editable_value, mgp_value_make_bool, is_editable, memory); }, result);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
utils::pmr::string full_name(module_name, memory->impl);
|
||||
full_name.append(1, '.');
|
||||
full_name.append(trans_name);
|
||||
|
||||
const auto name_value = GetStringValueOrSetError(full_name.c_str(), memory, result);
|
||||
if (!name_value) {
|
||||
MgpUniquePtr<mgp_value> name_value{nullptr, mgp_value_destroy};
|
||||
if (const auto err = CreateMgpObject(name_value, mgp_value_make_string, full_name.c_str(), memory);
|
||||
err == MGP_ERROR_UNABLE_TO_ALLOCATE) {
|
||||
static_cast<void>(mgp_result_set_error_msg(result, "Not enough memory!"));
|
||||
return;
|
||||
} else if (err != MGP_ERROR_NO_ERROR) {
|
||||
static_cast<void>(mgp_result_set_error_msg(result, "Unexpected error"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!InsertResultOrSetError(result, record, "name", name_value.get())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!InsertResultOrSetError(result, record, "path", path_value.get())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!InsertResultOrSetError(result, record, "is_editable", is_editable_value.get())) {
|
||||
if (const auto err = mgp_result_record_insert(record, "name", name_value.get()); err != MGP_ERROR_NO_ERROR) {
|
||||
static_cast<void>(mgp_result_set_error_msg(result, "Unable to set the result!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -315,8 +252,6 @@ void RegisterMgTransformations(const std::map<std::string, std::unique_ptr<Modul
|
||||
};
|
||||
mgp_proc procedures("transformations", transformations_cb, utils::NewDeleteResource(), false);
|
||||
MG_ASSERT(mgp_proc_add_result(&procedures, "name", Call<mgp_type *>(mgp_type_string)) == MGP_ERROR_NO_ERROR);
|
||||
MG_ASSERT(mgp_proc_add_result(&procedures, "path", Call<mgp_type *>(mgp_type_string)) == MGP_ERROR_NO_ERROR);
|
||||
MG_ASSERT(mgp_proc_add_result(&procedures, "is_editable", Call<mgp_type *>(mgp_type_bool)) == MGP_ERROR_NO_ERROR);
|
||||
module->AddProcedure("transformations", std::move(procedures));
|
||||
}
|
||||
|
||||
@@ -362,8 +297,6 @@ class SharedLibraryModule final : public Module {
|
||||
|
||||
const std::map<std::string, mgp_trans, std::less<>> *Transformations() const override;
|
||||
|
||||
std::optional<std::filesystem::path> Path() const override { return file_path_; }
|
||||
|
||||
private:
|
||||
/// Path as requested for loading the module from a library.
|
||||
std::filesystem::path file_path_;
|
||||
@@ -491,7 +424,6 @@ class PythonModule final : public Module {
|
||||
|
||||
const std::map<std::string, mgp_proc, std::less<>> *Procedures() const override;
|
||||
const std::map<std::string, mgp_trans, std::less<>> *Transformations() const override;
|
||||
std::optional<std::filesystem::path> Path() const override { return file_path_; }
|
||||
|
||||
private:
|
||||
std::filesystem::path file_path_;
|
||||
@@ -745,9 +677,9 @@ template <typename T>
|
||||
concept ModuleProperties = utils::SameAsAnyOf<T, mgp_proc, mgp_trans>;
|
||||
|
||||
template <ModuleProperties T>
|
||||
std::optional<std::pair<ModulePtr, const T *>> MakePairIfPropFound(const ModuleRegistry &module_registry,
|
||||
std::string_view fully_qualified_name,
|
||||
utils::MemoryResource *memory) {
|
||||
std::optional<std::pair<procedure::ModulePtr, const T *>> MakePairIfPropFound(const ModuleRegistry &module_registry,
|
||||
std::string_view fully_qualified_name,
|
||||
utils::MemoryResource *memory) {
|
||||
auto prop_fun = [](auto &module) {
|
||||
if constexpr (std::is_same_v<T, mgp_proc>) {
|
||||
return module->Procedures();
|
||||
@@ -768,13 +700,13 @@ std::optional<std::pair<ModulePtr, const T *>> MakePairIfPropFound(const ModuleR
|
||||
|
||||
} // namespace
|
||||
|
||||
std::optional<std::pair<ModulePtr, const mgp_proc *>> FindProcedure(const ModuleRegistry &module_registry,
|
||||
std::string_view fully_qualified_procedure_name,
|
||||
utils::MemoryResource *memory) {
|
||||
std::optional<std::pair<procedure::ModulePtr, const mgp_proc *>> FindProcedure(
|
||||
const ModuleRegistry &module_registry, std::string_view fully_qualified_procedure_name,
|
||||
utils::MemoryResource *memory) {
|
||||
return MakePairIfPropFound<mgp_proc>(module_registry, fully_qualified_procedure_name, memory);
|
||||
}
|
||||
|
||||
std::optional<std::pair<ModulePtr, const mgp_trans *>> FindTransformation(
|
||||
std::optional<std::pair<procedure::ModulePtr, const mgp_trans *>> FindTransformation(
|
||||
const ModuleRegistry &module_registry, std::string_view fully_qualified_transformation_name,
|
||||
utils::MemoryResource *memory) {
|
||||
return MakePairIfPropFound<mgp_trans>(module_registry, fully_qualified_transformation_name, memory);
|
||||
|
||||
@@ -45,8 +45,6 @@ class Module {
|
||||
virtual const std::map<std::string, mgp_proc, std::less<>> *Procedures() const = 0;
|
||||
/// Returns registered transformations of this module
|
||||
virtual const std::map<std::string, mgp_trans, std::less<>> *Transformations() const = 0;
|
||||
|
||||
virtual std::optional<std::filesystem::path> Path() const = 0;
|
||||
};
|
||||
|
||||
/// Proxy for a registered Module, acquires a read lock from ModuleRegistry.
|
||||
|
||||
@@ -181,7 +181,6 @@ PyObject *PyVerticesIteratorGet(PyVerticesIterator *self, PyObject *Py_UNUSED(ig
|
||||
return nullptr;
|
||||
}
|
||||
if (vertex == nullptr) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
return MakePyVertex(*vertex, self->py_graph);
|
||||
@@ -196,7 +195,6 @@ PyObject *PyVerticesIteratorNext(PyVerticesIterator *self, PyObject *Py_UNUSED(i
|
||||
return nullptr;
|
||||
}
|
||||
if (vertex == nullptr) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
return MakePyVertex(*vertex, self->py_graph);
|
||||
@@ -253,7 +251,6 @@ PyObject *PyEdgesIteratorGet(PyEdgesIterator *self, PyObject *Py_UNUSED(ignored)
|
||||
return nullptr;
|
||||
}
|
||||
if (edge == nullptr) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
return MakePyEdge(*edge, self->py_graph);
|
||||
@@ -268,7 +265,6 @@ PyObject *PyEdgesIteratorNext(PyEdgesIterator *self, PyObject *Py_UNUSED(ignored
|
||||
return nullptr;
|
||||
}
|
||||
if (edge == nullptr) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
return MakePyEdge(*edge, self->py_graph);
|
||||
@@ -1244,7 +1240,6 @@ PyObject *PyPropertiesIteratorGet(PyPropertiesIterator *self, PyObject *Py_UNUSE
|
||||
return nullptr;
|
||||
}
|
||||
if (property == nullptr) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
py::Object py_name(PyUnicode_FromString(property->name));
|
||||
@@ -1263,7 +1258,6 @@ PyObject *PyPropertiesIteratorNext(PyPropertiesIterator *self, PyObject *Py_UNUS
|
||||
return nullptr;
|
||||
}
|
||||
if (property == nullptr) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
py::Object py_name(PyUnicode_FromString(property->name));
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "query/serialization/property_value.hpp"
|
||||
#include "storage/v2/property_value.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
#include "utils/memory.hpp"
|
||||
|
||||
namespace query::serialization {
|
||||
|
||||
@@ -47,7 +46,7 @@ nlohmann::json SerializePropertyValue(const storage::PropertyValue &property_val
|
||||
}
|
||||
}
|
||||
|
||||
nlohmann::json SerializePropertyValueVector(const storage::PropertyValue::TVector &values) {
|
||||
nlohmann::json SerializePropertyValueVector(const std::vector<storage::PropertyValue> &values) {
|
||||
nlohmann::json array = nlohmann::json::array();
|
||||
for (const auto &value : values) {
|
||||
array.push_back(SerializePropertyValue(value));
|
||||
@@ -55,18 +54,6 @@ nlohmann::json SerializePropertyValueVector(const storage::PropertyValue::TVecto
|
||||
return array;
|
||||
}
|
||||
|
||||
nlohmann::json SerializePropertyValueMap(const storage::PropertyValue::TMap ¶meters) {
|
||||
nlohmann::json data = nlohmann::json::object();
|
||||
data.emplace("type", static_cast<uint64_t>(ObjectType::MAP));
|
||||
data.emplace("value", nlohmann::json::object());
|
||||
|
||||
for (const auto &[key, value] : parameters) {
|
||||
data["value"][std::string{key}] = SerializePropertyValue(value);
|
||||
}
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
nlohmann::json SerializePropertyValueMap(const std::map<std::string, storage::PropertyValue> ¶meters) {
|
||||
nlohmann::json data = nlohmann::json::object();
|
||||
data.emplace("type", static_cast<uint64_t>(ObjectType::MAP));
|
||||
@@ -125,9 +112,9 @@ std::vector<storage::PropertyValue> DeserializePropertyValueList(const nlohmann:
|
||||
return property_values;
|
||||
}
|
||||
|
||||
storage::PropertyValue::TMap DeserializePropertyValueMap(const nlohmann::json::object_t &data) {
|
||||
std::map<std::string, storage::PropertyValue> DeserializePropertyValueMap(const nlohmann::json::object_t &data) {
|
||||
MG_ASSERT(data.at("type").get<ObjectType>() == ObjectType::MAP, "Invalid map serialization");
|
||||
storage::PropertyValue::TMap property_values{utils::NewDeleteResource()};
|
||||
std::map<std::string, storage::PropertyValue> property_values;
|
||||
|
||||
const nlohmann::json::object_t &values = data.at("value");
|
||||
for (const auto &[key, value] : values) {
|
||||
|
||||
@@ -19,9 +19,7 @@ namespace query::serialization {
|
||||
|
||||
nlohmann::json SerializePropertyValue(const storage::PropertyValue &property_value);
|
||||
|
||||
nlohmann::json SerializePropertyValueVector(const storage::PropertyValue::TVector &values);
|
||||
|
||||
nlohmann::json SerializePropertyValueMap(const storage::PropertyValue::TMap ¶meters);
|
||||
nlohmann::json SerializePropertyValueVector(const std::vector<storage::PropertyValue> &values);
|
||||
|
||||
nlohmann::json SerializePropertyValueMap(const std::map<std::string, storage::PropertyValue> ¶meters);
|
||||
|
||||
@@ -29,6 +27,6 @@ storage::PropertyValue DeserializePropertyValue(const nlohmann::json &data);
|
||||
|
||||
std::vector<storage::PropertyValue> DeserializePropertyValueList(const nlohmann::json::array_t &data);
|
||||
|
||||
storage::PropertyValue::TMap DeserializePropertyValueMap(const nlohmann::json::object_t &data);
|
||||
std::map<std::string, storage::PropertyValue> DeserializePropertyValueMap(const nlohmann::json::object_t &data);
|
||||
|
||||
} // namespace query::serialization
|
||||
|
||||
@@ -58,8 +58,7 @@ concept Stream = requires(TStream stream) {
|
||||
stream.Check(std::optional<std::chrono::milliseconds>{}, std::optional<int64_t>{},
|
||||
ConsumerFunction<typename TStream::Message>{})
|
||||
} -> std::same_as<void>;
|
||||
requires std::same_as<std::decay_t<decltype(std::declval<typename TStream::StreamInfo>().common_info)>,
|
||||
CommonStreamInfo>;
|
||||
{ typename TStream::StreamInfo{}.common_info } -> std::same_as<CommonStreamInfo>;
|
||||
|
||||
requires ConvertableToMgpMessage<typename TStream::Message>;
|
||||
requires ConvertableToJson<typename TStream::StreamInfo>;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -13,8 +13,6 @@
|
||||
|
||||
#include <json/json.hpp>
|
||||
|
||||
#include "integrations/constants.hpp"
|
||||
|
||||
namespace query::stream {
|
||||
KafkaStream::KafkaStream(std::string stream_name, StreamInfo stream_info,
|
||||
ConsumerFunction<integrations::kafka::Message> consumer_function) {
|
||||
@@ -25,8 +23,6 @@ KafkaStream::KafkaStream(std::string stream_name, StreamInfo stream_info,
|
||||
.bootstrap_servers = std::move(stream_info.bootstrap_servers),
|
||||
.batch_interval = stream_info.common_info.batch_interval,
|
||||
.batch_size = stream_info.common_info.batch_size,
|
||||
.public_configs = std::move(stream_info.configs),
|
||||
.private_configs = std::move(stream_info.credentials),
|
||||
};
|
||||
consumer_.emplace(std::move(consumer_info), std::move(consumer_function));
|
||||
};
|
||||
@@ -38,9 +34,7 @@ KafkaStream::StreamInfo KafkaStream::Info(std::string transformation_name) const
|
||||
.transformation_name = std::move(transformation_name)},
|
||||
.topics = info.topics,
|
||||
.consumer_group = info.consumer_group,
|
||||
.bootstrap_servers = info.bootstrap_servers,
|
||||
.configs = info.public_configs,
|
||||
.credentials = info.private_configs};
|
||||
.bootstrap_servers = info.bootstrap_servers};
|
||||
}
|
||||
|
||||
void KafkaStream::Start() { consumer_->Start(); }
|
||||
@@ -60,10 +54,6 @@ namespace {
|
||||
const std::string kTopicsKey{"topics"};
|
||||
const std::string kConsumerGroupKey{"consumer_group"};
|
||||
const std::string kBoostrapServers{"bootstrap_servers"};
|
||||
const std::string kConfigs{"configs"};
|
||||
const std::string kCredentials{"credentials"};
|
||||
|
||||
const std::unordered_map<std::string, std::string> kDefaultConfigsMap;
|
||||
} // namespace
|
||||
|
||||
void to_json(nlohmann::json &data, KafkaStream::StreamInfo &&info) {
|
||||
@@ -71,8 +61,6 @@ void to_json(nlohmann::json &data, KafkaStream::StreamInfo &&info) {
|
||||
data[kTopicsKey] = std::move(info.topics);
|
||||
data[kConsumerGroupKey] = info.consumer_group;
|
||||
data[kBoostrapServers] = std::move(info.bootstrap_servers);
|
||||
data[kConfigs] = std::move(info.configs);
|
||||
data[kCredentials] = std::move(info.credentials);
|
||||
}
|
||||
|
||||
void from_json(const nlohmann::json &data, KafkaStream::StreamInfo &info) {
|
||||
@@ -80,9 +68,6 @@ void from_json(const nlohmann::json &data, KafkaStream::StreamInfo &info) {
|
||||
data.at(kTopicsKey).get_to(info.topics);
|
||||
data.at(kConsumerGroupKey).get_to(info.consumer_group);
|
||||
data.at(kBoostrapServers).get_to(info.bootstrap_servers);
|
||||
// These values might not be present in the persisted JSON object
|
||||
info.configs = data.value(kConfigs, kDefaultConfigsMap);
|
||||
info.credentials = data.value(kCredentials, kDefaultConfigsMap);
|
||||
}
|
||||
|
||||
PulsarStream::PulsarStream(std::string stream_name, StreamInfo stream_info,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -24,8 +24,6 @@ struct KafkaStream {
|
||||
std::vector<std::string> topics;
|
||||
std::string consumer_group;
|
||||
std::string bootstrap_servers;
|
||||
std::unordered_map<std::string, std::string> configs;
|
||||
std::unordered_map<std::string, std::string> credentials;
|
||||
};
|
||||
|
||||
using Message = integrations::kafka::Message;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -18,7 +18,6 @@
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <json/json.hpp>
|
||||
|
||||
#include "integrations/constants.hpp"
|
||||
#include "mg_procedure.h"
|
||||
#include "query/db_accessor.hpp"
|
||||
#include "query/discard_value_stream.hpp"
|
||||
@@ -30,7 +29,6 @@
|
||||
#include "query/stream/sources.hpp"
|
||||
#include "query/typed_value.hpp"
|
||||
#include "utils/event_counter.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
#include "utils/memory.hpp"
|
||||
#include "utils/on_scope_exit.hpp"
|
||||
#include "utils/pmr/string.hpp"
|
||||
@@ -56,7 +54,7 @@ auto GetStream(auto &map, const std::string &stream_name) {
|
||||
}
|
||||
|
||||
std::pair<TypedValue /*query*/, TypedValue /*parameters*/> ExtractTransformationResult(
|
||||
const utils::pmr::map<utils::pmr::string, TypedValue> &values, const std::string_view transformation_name,
|
||||
utils::pmr::map<utils::pmr::string, TypedValue> &&values, const std::string_view transformation_name,
|
||||
const std::string_view stream_name) {
|
||||
if (values.size() != kExpectedTransformationResultSize) {
|
||||
throw StreamsException(
|
||||
@@ -64,7 +62,7 @@ std::pair<TypedValue /*query*/, TypedValue /*parameters*/> ExtractTransformation
|
||||
transformation_name, stream_name);
|
||||
}
|
||||
|
||||
auto get_value = [&](const utils::pmr::string &field_name) mutable -> const TypedValue & {
|
||||
auto get_value = [&](const utils::pmr::string &field_name) mutable -> TypedValue & {
|
||||
auto it = values.find(field_name);
|
||||
if (it == values.end()) {
|
||||
throw StreamsException{"Transformation '{}' in stream '{}' did not yield a record with '{}' field.",
|
||||
@@ -73,11 +71,11 @@ std::pair<TypedValue /*query*/, TypedValue /*parameters*/> ExtractTransformation
|
||||
return it->second;
|
||||
};
|
||||
|
||||
const auto &query_value = get_value(query_param_name);
|
||||
auto &query_value = get_value(query_param_name);
|
||||
MG_ASSERT(query_value.IsString());
|
||||
const auto ¶ms_value = get_value(params_param_name);
|
||||
auto ¶ms_value = get_value(params_param_name);
|
||||
MG_ASSERT(params_value.IsNull() || params_value.IsMap());
|
||||
return {query_value, params_value};
|
||||
return {std::move(query_value), std::move(params_value)};
|
||||
}
|
||||
|
||||
template <typename TMessage>
|
||||
@@ -160,6 +158,43 @@ void from_json(const nlohmann::json &data, StreamStatus<TStream> &status) {
|
||||
from_json(data, status.info);
|
||||
}
|
||||
|
||||
namespace {
|
||||
template <typename Fun>
|
||||
[[nodiscard]] bool TryOrSetError(Fun &&func, mgp_result *result) {
|
||||
if (const auto err = func(); err == MGP_ERROR_UNABLE_TO_ALLOCATE) {
|
||||
static_cast<void>(mgp_result_set_error_msg(result, "Not enough memory!"));
|
||||
return false;
|
||||
} else if (err != MGP_ERROR_NO_ERROR) {
|
||||
const auto error_msg = fmt::format("Unexpected error ({})!", err);
|
||||
static_cast<void>(mgp_result_set_error_msg(result, error_msg.c_str()));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto GetStringValueOrSetError(const char *string, mgp_memory *memory, mgp_result *result) {
|
||||
procedure::MgpUniquePtr<mgp_value> value{nullptr, mgp_value_destroy};
|
||||
const auto success =
|
||||
TryOrSetError([&] { return procedure::CreateMgpObject(value, mgp_value_make_string, string, memory); }, result);
|
||||
if (!success) {
|
||||
value.reset();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool InsertResultOrSetError(mgp_result *result, mgp_result_record *record, const auto *result_name,
|
||||
mgp_value *value) {
|
||||
if (const auto err = mgp_result_record_insert(record, result_name, value); err != MGP_ERROR_NO_ERROR) {
|
||||
const auto error_msg = fmt::format("Unable to set the result for {}, error = {}", result_name, err);
|
||||
static_cast<void>(mgp_result_set_error_msg(result, error_msg.c_str()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Streams::Streams(InterpreterContext *interpreter_context, std::filesystem::path directory)
|
||||
: interpreter_context_(interpreter_context), storage_(std::move(directory)) {
|
||||
RegisterProcedures();
|
||||
@@ -210,12 +245,10 @@ void Streams::RegisterKafkaProcedures() {
|
||||
constexpr std::string_view consumer_group_result_name = "consumer_group";
|
||||
constexpr std::string_view topics_result_name = "topics";
|
||||
constexpr std::string_view bootstrap_servers_result_name = "bootstrap_servers";
|
||||
constexpr std::string_view configs_result_name = "configs";
|
||||
constexpr std::string_view credentials_result_name = "credentials";
|
||||
|
||||
auto get_stream_info = [this, proc_name, consumer_group_result_name, topics_result_name,
|
||||
bootstrap_servers_result_name, configs_result_name, credentials_result_name](
|
||||
mgp_list *args, mgp_graph * /*graph*/, mgp_result *result, mgp_memory *memory) {
|
||||
bootstrap_servers_result_name](mgp_list *args, mgp_graph * /*graph*/, mgp_result *result,
|
||||
mgp_memory *memory) {
|
||||
auto *arg_stream_name = procedure::Call<mgp_value *>(mgp_list_at, args, 0);
|
||||
const auto *stream_name = procedure::Call<const char *>(mgp_value_get_string, arg_stream_name);
|
||||
auto lock_ptr = streams_.Lock();
|
||||
@@ -227,22 +260,20 @@ void Streams::RegisterKafkaProcedures() {
|
||||
const auto info = stream_source_ptr->Info(kafka_stream.transformation_name);
|
||||
mgp_result_record *record{nullptr};
|
||||
{
|
||||
const auto success =
|
||||
procedure::TryOrSetError([&] { return mgp_result_new_record(result, &record); }, result);
|
||||
const auto success = TryOrSetError([&] { return mgp_result_new_record(result, &record); }, result);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const auto consumer_group_value =
|
||||
procedure::GetStringValueOrSetError(info.consumer_group.c_str(), memory, result);
|
||||
const auto consumer_group_value = GetStringValueOrSetError(info.consumer_group.c_str(), memory, result);
|
||||
if (!consumer_group_value) {
|
||||
return;
|
||||
}
|
||||
|
||||
procedure::MgpUniquePtr<mgp_list> topic_names{nullptr, mgp_list_destroy};
|
||||
{
|
||||
const auto success = procedure::TryOrSetError(
|
||||
const auto success = TryOrSetError(
|
||||
[&] {
|
||||
return procedure::CreateMgpObject(topic_names, mgp_list_make_empty, info.topics.size(), memory);
|
||||
},
|
||||
@@ -253,7 +284,7 @@ void Streams::RegisterKafkaProcedures() {
|
||||
}
|
||||
|
||||
for (const auto &topic : info.topics) {
|
||||
auto topic_value = procedure::GetStringValueOrSetError(topic.c_str(), memory, result);
|
||||
auto topic_value = GetStringValueOrSetError(topic.c_str(), memory, result);
|
||||
if (!topic_value) {
|
||||
return;
|
||||
}
|
||||
@@ -262,93 +293,33 @@ void Streams::RegisterKafkaProcedures() {
|
||||
|
||||
procedure::MgpUniquePtr<mgp_value> topics_value{nullptr, mgp_value_destroy};
|
||||
{
|
||||
const auto success = procedure::TryOrSetError(
|
||||
[&] { return procedure::CreateMgpObject(topics_value, mgp_value_make_list, topic_names.get()); },
|
||||
const auto success = TryOrSetError(
|
||||
[&] {
|
||||
return procedure::CreateMgpObject(topics_value, mgp_value_make_list, topic_names.release());
|
||||
},
|
||||
result);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
static_cast<void>(topic_names.release());
|
||||
}
|
||||
|
||||
const auto bootstrap_servers_value =
|
||||
procedure::GetStringValueOrSetError(info.bootstrap_servers.c_str(), memory, result);
|
||||
GetStringValueOrSetError(info.bootstrap_servers.c_str(), memory, result);
|
||||
if (!bootstrap_servers_value) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto convert_config_map =
|
||||
[result, memory](const std::unordered_map<std::string, std::string> &configs_to_convert)
|
||||
-> procedure::MgpUniquePtr<mgp_value> {
|
||||
procedure::MgpUniquePtr<mgp_value> configs_value{nullptr, mgp_value_destroy};
|
||||
procedure::MgpUniquePtr<mgp_map> configs{nullptr, mgp_map_destroy};
|
||||
{
|
||||
const auto success = procedure::TryOrSetError(
|
||||
[&] { return procedure::CreateMgpObject(configs, mgp_map_make_empty, memory); }, result);
|
||||
if (!success) {
|
||||
return configs_value;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &[key, value] : configs_to_convert) {
|
||||
auto value_value = procedure::GetStringValueOrSetError(value.c_str(), memory, result);
|
||||
if (!value_value) {
|
||||
return configs_value;
|
||||
}
|
||||
configs->items.emplace(key, std::move(*value_value));
|
||||
}
|
||||
|
||||
{
|
||||
const auto success = procedure::TryOrSetError(
|
||||
[&] { return procedure::CreateMgpObject(configs_value, mgp_value_make_map, configs.get()); },
|
||||
result);
|
||||
if (!success) {
|
||||
return configs_value;
|
||||
}
|
||||
static_cast<void>(configs.release());
|
||||
}
|
||||
return configs_value;
|
||||
};
|
||||
|
||||
const auto configs_value = convert_config_map(info.configs);
|
||||
if (configs_value == nullptr) {
|
||||
if (!InsertResultOrSetError(result, record, consumer_group_result_name.data(),
|
||||
consumer_group_value.get())) {
|
||||
return;
|
||||
}
|
||||
|
||||
using CredentialsType = decltype(KafkaStream::StreamInfo::credentials);
|
||||
CredentialsType reducted_credentials;
|
||||
std::transform(info.credentials.begin(), info.credentials.end(),
|
||||
std::inserter(reducted_credentials, reducted_credentials.end()),
|
||||
[](const auto &pair) -> CredentialsType::value_type {
|
||||
return {pair.first, integrations::kReducted};
|
||||
});
|
||||
|
||||
const auto credentials_value = convert_config_map(reducted_credentials);
|
||||
if (credentials_value == nullptr) {
|
||||
if (!InsertResultOrSetError(result, record, topics_result_name.data(), topics_value.get())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!procedure::InsertResultOrSetError(result, record, consumer_group_result_name.data(),
|
||||
consumer_group_value.get())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!procedure::InsertResultOrSetError(result, record, topics_result_name.data(), topics_value.get())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!procedure::InsertResultOrSetError(result, record, bootstrap_servers_result_name.data(),
|
||||
bootstrap_servers_value.get())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!procedure::InsertResultOrSetError(result, record, configs_result_name.data(),
|
||||
configs_value.get())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!procedure::InsertResultOrSetError(result, record, credentials_result_name.data(),
|
||||
credentials_value.get())) {
|
||||
if (!InsertResultOrSetError(result, record, bootstrap_servers_result_name.data(),
|
||||
bootstrap_servers_value.get())) {
|
||||
return;
|
||||
}
|
||||
},
|
||||
@@ -369,10 +340,6 @@ void Streams::RegisterKafkaProcedures() {
|
||||
MGP_ERROR_NO_ERROR);
|
||||
MG_ASSERT(mgp_proc_add_result(&proc, bootstrap_servers_result_name.data(),
|
||||
procedure::Call<mgp_type *>(mgp_type_string)) == MGP_ERROR_NO_ERROR);
|
||||
MG_ASSERT(mgp_proc_add_result(&proc, configs_result_name.data(), procedure::Call<mgp_type *>(mgp_type_map)) ==
|
||||
MGP_ERROR_NO_ERROR);
|
||||
MG_ASSERT(mgp_proc_add_result(&proc, credentials_result_name.data(), procedure::Call<mgp_type *>(mgp_type_map)) ==
|
||||
MGP_ERROR_NO_ERROR);
|
||||
|
||||
procedure::gModuleRegistry.RegisterMgProcedure(proc_name, std::move(proc));
|
||||
}
|
||||
@@ -396,21 +363,20 @@ void Streams::RegisterPulsarProcedures() {
|
||||
const auto info = stream_source_ptr->Info(pulsar_stream.transformation_name);
|
||||
mgp_result_record *record{nullptr};
|
||||
{
|
||||
const auto success =
|
||||
procedure::TryOrSetError([&] { return mgp_result_new_record(result, &record); }, result);
|
||||
const auto success = TryOrSetError([&] { return mgp_result_new_record(result, &record); }, result);
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto service_url_value = procedure::GetStringValueOrSetError(info.service_url.c_str(), memory, result);
|
||||
auto service_url_value = GetStringValueOrSetError(info.service_url.c_str(), memory, result);
|
||||
if (!service_url_value) {
|
||||
return;
|
||||
}
|
||||
|
||||
procedure::MgpUniquePtr<mgp_list> topic_names{nullptr, mgp_list_destroy};
|
||||
{
|
||||
const auto success = procedure::TryOrSetError(
|
||||
const auto success = TryOrSetError(
|
||||
[&] {
|
||||
return procedure::CreateMgpObject(topic_names, mgp_list_make_empty, info.topics.size(), memory);
|
||||
},
|
||||
@@ -421,7 +387,7 @@ void Streams::RegisterPulsarProcedures() {
|
||||
}
|
||||
|
||||
for (const auto &topic : info.topics) {
|
||||
auto topic_value = procedure::GetStringValueOrSetError(topic.c_str(), memory, result);
|
||||
auto topic_value = GetStringValueOrSetError(topic.c_str(), memory, result);
|
||||
if (!topic_value) {
|
||||
return;
|
||||
}
|
||||
@@ -430,7 +396,7 @@ void Streams::RegisterPulsarProcedures() {
|
||||
|
||||
procedure::MgpUniquePtr<mgp_value> topics_value{nullptr, mgp_value_destroy};
|
||||
{
|
||||
const auto success = procedure::TryOrSetError(
|
||||
const auto success = TryOrSetError(
|
||||
[&] {
|
||||
return procedure::CreateMgpObject(topics_value, mgp_value_make_list, topic_names.release());
|
||||
},
|
||||
@@ -440,12 +406,11 @@ void Streams::RegisterPulsarProcedures() {
|
||||
}
|
||||
}
|
||||
|
||||
if (!procedure::InsertResultOrSetError(result, record, topics_result_name.data(), topics_value.get())) {
|
||||
if (!InsertResultOrSetError(result, record, topics_result_name.data(), topics_value.get())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!procedure::InsertResultOrSetError(result, record, service_url_result_name.data(),
|
||||
service_url_value.get())) {
|
||||
if (!InsertResultOrSetError(result, record, service_url_result_name.data(), service_url_value.get())) {
|
||||
return;
|
||||
}
|
||||
},
|
||||
@@ -523,14 +488,15 @@ Streams::StreamsMap::iterator Streams::CreateConsumer(StreamsMap &map, const std
|
||||
interpreter->Abort();
|
||||
}};
|
||||
|
||||
const static storage::PropertyValue::TMap empty_parameters{utils::NewDeleteResource()};
|
||||
const static std::map<std::string, storage::PropertyValue> empty_parameters{};
|
||||
uint32_t i = 0;
|
||||
while (true) {
|
||||
try {
|
||||
interpreter->BeginTransaction();
|
||||
for (auto &row : result.rows) {
|
||||
spdlog::trace("Processing row in stream '{}'", stream_name);
|
||||
auto [query_value, params_value] = ExtractTransformationResult(row.values, transformation_name, stream_name);
|
||||
auto [query_value, params_value] =
|
||||
ExtractTransformationResult(std::move(row.values), transformation_name, stream_name);
|
||||
storage::PropertyValue params_prop{params_value};
|
||||
|
||||
std::string query{query_value.ValueString()};
|
||||
@@ -551,7 +517,6 @@ Streams::StreamsMap::iterator Streams::CreateConsumer(StreamsMap &map, const std
|
||||
result.rows.clear();
|
||||
break;
|
||||
} catch (const query::TransactionSerializationException &e) {
|
||||
interpreter->Abort();
|
||||
if (i == total_retries) {
|
||||
throw;
|
||||
}
|
||||
@@ -748,7 +713,8 @@ TransformationResult Streams::Check(const std::string &stream_name, std::optiona
|
||||
CallCustomTransformation(transformation_name, messages, result, accessor, *memory_resource, stream_name);
|
||||
|
||||
for (auto &row : result.rows) {
|
||||
auto [query, parameters] = ExtractTransformationResult(row.values, transformation_name, stream_name);
|
||||
auto [query, parameters] =
|
||||
ExtractTransformationResult(std::move(row.values), transformation_name, stream_name);
|
||||
std::vector<TypedValue> result_row;
|
||||
result_row.reserve(kExpectedTransformationResultSize);
|
||||
result_row.push_back(std::move(query));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2022 Memgraph Ltd.
|
||||
// Copyright 2021 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@@ -31,7 +31,6 @@
|
||||
#include "utils/rw_lock.hpp"
|
||||
#include "utils/synchronized.hpp"
|
||||
|
||||
class StreamsTest;
|
||||
namespace query {
|
||||
|
||||
struct InterpreterContext;
|
||||
@@ -74,8 +73,6 @@ using TransformationResult = std::vector<std::vector<TypedValue>>;
|
||||
///
|
||||
/// This class is responsible for all query supported actions to happen.
|
||||
class Streams final {
|
||||
friend StreamsTest;
|
||||
|
||||
public:
|
||||
/// Initializes the streams.
|
||||
///
|
||||
|
||||
@@ -150,7 +150,8 @@ std::vector<std::pair<Identifier, TriggerIdentifierTag>> GetPredefinedIdentifier
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Trigger::Trigger(std::string name, const std::string &query, const storage::PropertyValue::TMap &user_parameters,
|
||||
Trigger::Trigger(std::string name, const std::string &query,
|
||||
const std::map<std::string, storage::PropertyValue> &user_parameters,
|
||||
const TriggerEventType event_type, utils::SkipList<QueryCacheEntry> *query_cache,
|
||||
DbAccessor *db_accessor, utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config,
|
||||
std::optional<std::string> owner, const query::AuthChecker *auth_checker)
|
||||
@@ -332,11 +333,11 @@ void TriggerStore::RestoreTriggers(utils::SkipList<QueryCacheEntry> *query_cache
|
||||
}
|
||||
|
||||
void TriggerStore::AddTrigger(std::string name, const std::string &query,
|
||||
const storage::PropertyValue::TMap &user_parameters, TriggerEventType event_type,
|
||||
TriggerPhase phase, utils::SkipList<QueryCacheEntry> *query_cache,
|
||||
DbAccessor *db_accessor, utils::SpinLock *antlr_lock,
|
||||
const InterpreterConfig::Query &query_config, std::optional<std::string> owner,
|
||||
const query::AuthChecker *auth_checker) {
|
||||
const std::map<std::string, storage::PropertyValue> &user_parameters,
|
||||
TriggerEventType event_type, TriggerPhase phase,
|
||||
utils::SkipList<QueryCacheEntry> *query_cache, DbAccessor *db_accessor,
|
||||
utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config,
|
||||
std::optional<std::string> owner, const query::AuthChecker *auth_checker) {
|
||||
std::unique_lock store_guard{store_lock_};
|
||||
if (storage_.Get(name)) {
|
||||
throw utils::BasicException("Trigger with the same name already exists.");
|
||||
|
||||
@@ -32,10 +32,11 @@
|
||||
|
||||
namespace query {
|
||||
struct Trigger {
|
||||
explicit Trigger(std::string name, const std::string &query, const storage::PropertyValue::TMap &user_parameters,
|
||||
TriggerEventType event_type, utils::SkipList<QueryCacheEntry> *query_cache, DbAccessor *db_accessor,
|
||||
utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config,
|
||||
std::optional<std::string> owner, const query::AuthChecker *auth_checker);
|
||||
explicit Trigger(std::string name, const std::string &query,
|
||||
const std::map<std::string, storage::PropertyValue> &user_parameters, TriggerEventType event_type,
|
||||
utils::SkipList<QueryCacheEntry> *query_cache, DbAccessor *db_accessor, utils::SpinLock *antlr_lock,
|
||||
const InterpreterConfig::Query &query_config, std::optional<std::string> owner,
|
||||
const query::AuthChecker *auth_checker);
|
||||
|
||||
void Execute(DbAccessor *dba, utils::MonotonicBufferResource *execution_memory, double max_execution_time_sec,
|
||||
std::atomic<bool> *is_shutting_down, const TriggerContext &context,
|
||||
@@ -83,9 +84,10 @@ struct TriggerStore {
|
||||
utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config,
|
||||
const query::AuthChecker *auth_checker);
|
||||
|
||||
void AddTrigger(std::string name, const std::string &query, const storage::PropertyValue::TMap &user_parameters,
|
||||
TriggerEventType event_type, TriggerPhase phase, utils::SkipList<QueryCacheEntry> *query_cache,
|
||||
DbAccessor *db_accessor, utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config,
|
||||
void AddTrigger(std::string name, const std::string &query,
|
||||
const std::map<std::string, storage::PropertyValue> &user_parameters, TriggerEventType event_type,
|
||||
TriggerPhase phase, utils::SkipList<QueryCacheEntry> *query_cache, DbAccessor *db_accessor,
|
||||
utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config,
|
||||
std::optional<std::string> owner, const query::AuthChecker *auth_checker);
|
||||
|
||||
void DropTrigger(const std::string &name);
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#include "storage/v2/property_value.hpp"
|
||||
#include "storage/v2/temporal.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils/fnv.hpp"
|
||||
@@ -279,18 +278,12 @@ TypedValue::operator storage::PropertyValue() const {
|
||||
case TypedValue::Type::Double:
|
||||
return storage::PropertyValue(double_v);
|
||||
case TypedValue::Type::String:
|
||||
return storage::PropertyValue(string_v, memory_);
|
||||
case TypedValue::Type::List: {
|
||||
storage::PropertyValue::TVector list{memory_};
|
||||
list.reserve(list_v.size());
|
||||
for (const auto &tv : list_v) {
|
||||
list.emplace_back(storage::PropertyValue(tv));
|
||||
}
|
||||
return storage::PropertyValue(std::move(list));
|
||||
}
|
||||
return storage::PropertyValue(std::string(string_v));
|
||||
case TypedValue::Type::List:
|
||||
return storage::PropertyValue(std::vector<storage::PropertyValue>(list_v.begin(), list_v.end()));
|
||||
case TypedValue::Type::Map: {
|
||||
storage::PropertyValue::TMap map{memory_};
|
||||
for (const auto &kv : map_v) map.emplace(kv.first, storage::PropertyValue(kv.second));
|
||||
std::map<std::string, storage::PropertyValue> map;
|
||||
for (const auto &kv : map_v) map.emplace(kv.first, kv.second);
|
||||
return storage::PropertyValue(std::move(map));
|
||||
}
|
||||
case Type::Date:
|
||||
|
||||
@@ -2,9 +2,6 @@ set(requests_src_files
|
||||
requests.cpp)
|
||||
|
||||
find_package(CURL REQUIRED)
|
||||
find_package(fmt REQUIRED)
|
||||
find_package(gflags REQUIRED)
|
||||
|
||||
|
||||
add_library(mg-requests STATIC ${requests_src_files})
|
||||
target_link_libraries(mg-requests mg-utils spdlog::spdlog fmt::fmt gflags json ${CURL_LIBRARIES})
|
||||
|
||||
@@ -3,9 +3,6 @@ set(rpc_src_files
|
||||
protocol.cpp
|
||||
server.cpp)
|
||||
|
||||
find_package(fmt REQUIRED)
|
||||
find_package(gflags REQUIRED)
|
||||
|
||||
add_library(mg-rpc STATIC ${rpc_src_files})
|
||||
target_link_libraries(mg-rpc Threads::Threads mg-communication mg-utils mg-io fmt::fmt gflags)
|
||||
target_link_libraries(mg-rpc mg-slk)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
set(slk_src_files
|
||||
streams.cpp)
|
||||
|
||||
find_package(gflags REQUIRED)
|
||||
|
||||
add_library(mg-slk STATIC ${slk_src_files})
|
||||
target_link_libraries(mg-slk gflags)
|
||||
target_link_libraries(mg-slk mg-utils)
|
||||
|
||||
@@ -30,9 +30,6 @@ set(storage_v2_src_files
|
||||
|
||||
#######################
|
||||
|
||||
find_package(gflags REQUIRED)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
add_library(mg-storage-v2 STATIC ${storage_v2_src_files})
|
||||
target_link_libraries(mg-storage-v2 Threads::Threads mg-utils gflags)
|
||||
|
||||
|
||||
@@ -903,6 +903,9 @@ uint64_t ToPowerOf8(uint64_t size) {
|
||||
// of the two sets of data is currently active. Because the first byte of the
|
||||
// buffer is used to distinguish which of the two sets of data is used, we can
|
||||
// only use the leftover 15 bytes for raw data storage.
|
||||
#ifndef __x86_64__
|
||||
#error The PropertyStore only supports x86_64
|
||||
#endif
|
||||
|
||||
const uint8_t kUseLocalBuffer = 0x01;
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
namespace storage {
|
||||
|
||||
class PropertyStore {
|
||||
static_assert(std::endian::native == std::endian::little, "PropertyStore supports only architectures using little-endian.");
|
||||
public:
|
||||
PropertyStore();
|
||||
|
||||
|
||||
@@ -19,10 +19,6 @@
|
||||
#include "storage/v2/temporal.hpp"
|
||||
#include "utils/algorithm.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils/memory.hpp"
|
||||
#include "utils/pmr/map.hpp"
|
||||
#include "utils/pmr/string.hpp"
|
||||
#include "utils/pmr/vector.hpp"
|
||||
|
||||
namespace storage {
|
||||
|
||||
@@ -52,12 +48,6 @@ class PropertyValue {
|
||||
TemporalData = 7
|
||||
};
|
||||
|
||||
using TString = utils::pmr::string;
|
||||
using TVector = utils::pmr::vector<PropertyValue>;
|
||||
using TMap = utils::pmr::map<utils::pmr::string, PropertyValue>;
|
||||
|
||||
using allocator_type = utils::Allocator<PropertyValue>;
|
||||
|
||||
static bool AreComparableTypes(Type a, Type b) {
|
||||
return (a == b) || (a == Type::Int && b == Type::Double) || (a == Type::Double && b == Type::Int);
|
||||
}
|
||||
@@ -66,204 +56,45 @@ class PropertyValue {
|
||||
PropertyValue() : type_(Type::Null) {}
|
||||
|
||||
// constructors for primitive types
|
||||
explicit PropertyValue(const bool value, utils::MemoryResource *memory = utils::NewDeleteResource())
|
||||
: type_(Type::Bool), memory_{memory} {
|
||||
bool_v = value;
|
||||
}
|
||||
explicit PropertyValue(const int value, utils::MemoryResource *memory = utils::NewDeleteResource())
|
||||
: type_(Type::Int), memory_{memory} {
|
||||
int_v = value;
|
||||
}
|
||||
explicit PropertyValue(const int64_t value, utils::MemoryResource *memory = utils::NewDeleteResource())
|
||||
: type_(Type::Int), memory_{memory} {
|
||||
int_v = value;
|
||||
}
|
||||
explicit PropertyValue(const double value, utils::MemoryResource *memory = utils::NewDeleteResource())
|
||||
: type_(Type::Double), memory_{memory} {
|
||||
double_v = value;
|
||||
}
|
||||
explicit PropertyValue(const TemporalData value, utils::MemoryResource *memory = utils::NewDeleteResource())
|
||||
: type_{Type::TemporalData}, memory_{memory} {
|
||||
temporal_data_v = value;
|
||||
}
|
||||
explicit PropertyValue(const bool value) : type_(Type::Bool) { bool_v = value; }
|
||||
explicit PropertyValue(const int value) : type_(Type::Int) { int_v = value; }
|
||||
explicit PropertyValue(const int64_t value) : type_(Type::Int) { int_v = value; }
|
||||
explicit PropertyValue(const double value) : type_(Type::Double) { double_v = value; }
|
||||
explicit PropertyValue(const TemporalData value) : type_{Type::TemporalData} { temporal_data_v = value; }
|
||||
|
||||
// copy constructors for non-primitive types
|
||||
/// @throw std::bad_alloc
|
||||
explicit PropertyValue(const std::string &value, utils::MemoryResource *memory = utils::NewDeleteResource())
|
||||
: type_(Type::String), memory_{memory} {
|
||||
new (&string_v) TString(value, memory);
|
||||
}
|
||||
explicit PropertyValue(const std::string &value) : type_(Type::String) { new (&string_v) std::string(value); }
|
||||
/// @throw std::bad_alloc
|
||||
/// @throw std::length_error if length of value exceeds
|
||||
/// std::string::max_length().
|
||||
explicit PropertyValue(const char *value, utils::MemoryResource *memory = utils::NewDeleteResource())
|
||||
: type_(Type::String), memory_{memory} {
|
||||
new (&string_v) TString(value, memory);
|
||||
explicit PropertyValue(const char *value) : type_(Type::String) { new (&string_v) std::string(value); }
|
||||
/// @throw std::bad_alloc
|
||||
explicit PropertyValue(const std::vector<PropertyValue> &value) : type_(Type::List) {
|
||||
new (&list_v) std::vector<PropertyValue>(value);
|
||||
}
|
||||
/// @throw std::bad_alloc
|
||||
explicit PropertyValue(const std::map<std::string, PropertyValue> &value) : type_(Type::Map) {
|
||||
new (&map_v) std::map<std::string, PropertyValue>(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a copy of other.
|
||||
* utils::MemoryResource is obtained by calling
|
||||
* std::allocator_traits<>::
|
||||
* select_on_container_copy_construction(other.get_allocator()).
|
||||
* Since we use utils::Allocator, which does not propagate, this means that
|
||||
* memory_ will be the default utils::NewDeleteResource().
|
||||
*/
|
||||
explicit PropertyValue(const TString &other)
|
||||
: PropertyValue(other,
|
||||
std::allocator_traits<utils::Allocator<PropertyValue>>::select_on_container_copy_construction(
|
||||
other.get_allocator())
|
||||
.GetMemoryResource()) {}
|
||||
|
||||
/** Construct a copy using the given utils::MemoryResource */
|
||||
PropertyValue(const TString &other, utils::MemoryResource *memory) : type_(Type::String), memory_{memory} {
|
||||
new (&string_v) TString(other, memory_);
|
||||
// move constructors for non-primitive types
|
||||
explicit PropertyValue(std::string &&value) noexcept : type_(Type::String) {
|
||||
new (&string_v) std::string(std::move(value));
|
||||
}
|
||||
|
||||
/** Construct a copy using the given utils::MemoryResource */
|
||||
explicit PropertyValue(const std::vector<PropertyValue> &value,
|
||||
utils::MemoryResource *memory = utils::NewDeleteResource())
|
||||
: type_(Type::List), memory_(memory) {
|
||||
new (&list_v) TVector(memory_);
|
||||
list_v.reserve(value.size());
|
||||
list_v.assign(value.begin(), value.end());
|
||||
explicit PropertyValue(std::vector<PropertyValue> &&value) noexcept : type_(Type::List) {
|
||||
new (&list_v) std::vector<PropertyValue>(std::move(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a copy of other.
|
||||
* utils::MemoryResource is obtained by calling
|
||||
* std::allocator_traits<>::
|
||||
* select_on_container_copy_construction(other.get_allocator()).
|
||||
* Since we use utils::Allocator, which does not propagate, this means that
|
||||
* memory_ will be the default utils::NewDeleteResource().
|
||||
*/
|
||||
explicit PropertyValue(const TVector &other)
|
||||
: PropertyValue(other,
|
||||
std::allocator_traits<utils::Allocator<PropertyValue>>::select_on_container_copy_construction(
|
||||
other.get_allocator())
|
||||
.GetMemoryResource()) {}
|
||||
|
||||
/** Construct a copy using the given utils::MemoryResource */
|
||||
PropertyValue(const TVector &value, utils::MemoryResource *memory) : type_(Type::List), memory_(memory) {
|
||||
new (&list_v) TVector(value, memory_);
|
||||
explicit PropertyValue(std::map<std::string, PropertyValue> &&value) noexcept : type_(Type::Map) {
|
||||
new (&map_v) std::map<std::string, PropertyValue>(std::move(value));
|
||||
}
|
||||
|
||||
/** Construct a copy using the given utils::MemoryResource */
|
||||
explicit PropertyValue(const std::map<std::string, PropertyValue> &value,
|
||||
utils::MemoryResource *memory = utils::NewDeleteResource())
|
||||
: type_(Type::Map), memory_{memory} {
|
||||
new (&map_v) TMap(memory_);
|
||||
for (const auto &kv : value) map_v.emplace(kv.first, kv.second);
|
||||
}
|
||||
/**
|
||||
* Construct a copy of other.
|
||||
* utils::MemoryResource is obtained by calling
|
||||
* std::allocator_traits<>::
|
||||
* select_on_container_copy_construction(other.get_allocator()).
|
||||
* Since we use utils::Allocator, which does not propagate, this means that
|
||||
* memory_ will be the default utils::NewDeleteResource().
|
||||
*/
|
||||
explicit PropertyValue(const TMap &other)
|
||||
: PropertyValue(other,
|
||||
std::allocator_traits<utils::Allocator<PropertyValue>>::select_on_container_copy_construction(
|
||||
other.get_allocator())
|
||||
.GetMemoryResource()) {}
|
||||
|
||||
/** Construct a copy using the given utils::MemoryResource */
|
||||
PropertyValue(const TMap &value, utils::MemoryResource *memory) : type_(Type::Map), memory_{memory} {
|
||||
new (&map_v) TMap(value, memory_);
|
||||
}
|
||||
/**
|
||||
* Construct with the value of other.
|
||||
* utils::MemoryResource is obtained from other. After the move, other will be
|
||||
* left in unspecified state.
|
||||
*/
|
||||
explicit PropertyValue(TString &&other) noexcept
|
||||
: PropertyValue(std::move(other), other.get_allocator().GetMemoryResource()) {}
|
||||
|
||||
/**
|
||||
* Construct with the value of other and use the given MemoryResource
|
||||
* After the move, other will be left in unspecified state.
|
||||
*/
|
||||
PropertyValue(TString &&other, utils::MemoryResource *memory) : type_(Type::String), memory_{memory} {
|
||||
new (&string_v) TString(std::move(other), memory_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an element-wise move using default utils::NewDeleteResource().
|
||||
* Other will be not be empty, though elements may be Null.
|
||||
*/
|
||||
explicit PropertyValue(std::vector<PropertyValue> &&other)
|
||||
: PropertyValue(std::move(other), utils::NewDeleteResource()) {}
|
||||
|
||||
/**
|
||||
* Perform an element-wise move of the other and use the given MemoryResource.
|
||||
* Other will be not be left empty, though elements may be Null.
|
||||
*/
|
||||
PropertyValue(std::vector<PropertyValue> &&other, utils::MemoryResource *memory)
|
||||
: type_(Type::List), memory_{memory} {
|
||||
new (&list_v) TVector(memory_);
|
||||
list_v.reserve(other.size());
|
||||
// std::vector<PropertyValue> has std::allocator and there's no move
|
||||
// constructor for std::vector using different allocator types. Since
|
||||
// std::allocator is not propagated to elements, it is possible that some
|
||||
// PropertyValue elements have a MemoryResource that is the same as the one we
|
||||
// are given. In such a case we would like to move those PropertyValue
|
||||
// instances, so we use move_iterator.
|
||||
list_v.assign(std::make_move_iterator(other.begin()), std::make_move_iterator(other.end()));
|
||||
}
|
||||
/**
|
||||
* Construct with the value of other.
|
||||
* utils::MemoryResource is obtained from other. After the move, other will be
|
||||
* left empty.
|
||||
*/
|
||||
explicit PropertyValue(TVector &&other) noexcept
|
||||
: PropertyValue(std::move(other), other.get_allocator().GetMemoryResource()) {}
|
||||
|
||||
/**
|
||||
* Construct with the value of other and use the given MemoryResource.
|
||||
* If `other.get_allocator() != *memory`, this call will perform an
|
||||
* element-wise move and other is not guaranteed to be empty.
|
||||
*/
|
||||
PropertyValue(TVector &&other, utils::MemoryResource *memory) : type_(Type::List), memory_{memory} {
|
||||
new (&list_v) TVector(std::move(other), memory_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an element-wise move using default utils::NewDeleteResource().
|
||||
* Other will not be left empty, i.e. keys will exist but their values may
|
||||
* be Null.
|
||||
*/
|
||||
explicit PropertyValue(std::map<std::string, PropertyValue> &&other)
|
||||
: PropertyValue(std::move(other), utils::NewDeleteResource()) {}
|
||||
|
||||
/**
|
||||
* Perform an element-wise move using the given MemoryResource.
|
||||
* Other will not be left empty, i.e. keys will exist but their values may
|
||||
* be Null.
|
||||
*/
|
||||
PropertyValue(std::map<std::string, PropertyValue> &&other, utils::MemoryResource *memory)
|
||||
: type_(Type::Map), memory_{memory} {
|
||||
new (&map_v) TMap(memory_);
|
||||
for (auto &kv : other) map_v.emplace(kv.first, std::move(kv.second));
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct with the value of other.
|
||||
* utils::MemoryResource is obtained from other. After the move, other will be
|
||||
* left empty.
|
||||
*/
|
||||
explicit PropertyValue(TMap &&other) noexcept
|
||||
: PropertyValue(std::move(other), other.get_allocator().GetMemoryResource()) {}
|
||||
|
||||
// copy constructor
|
||||
/// @throw std::bad_alloc
|
||||
PropertyValue(const PropertyValue &other);
|
||||
PropertyValue(const PropertyValue &other, utils::MemoryResource *memory);
|
||||
|
||||
// move constructor
|
||||
PropertyValue(PropertyValue &&other) noexcept;
|
||||
PropertyValue(PropertyValue &&other, utils::MemoryResource *memory) noexcept;
|
||||
|
||||
// copy assignment
|
||||
/// @throw std::bad_alloc
|
||||
@@ -322,7 +153,7 @@ class PropertyValue {
|
||||
|
||||
// const value getters for non-primitive types
|
||||
/// @throw PropertyValueException if value isn't of correct type.
|
||||
const TString &ValueString() const {
|
||||
const std::string &ValueString() const {
|
||||
if (type_ != Type::String) {
|
||||
throw PropertyValueException("The value isn't a string!");
|
||||
}
|
||||
@@ -330,7 +161,7 @@ class PropertyValue {
|
||||
}
|
||||
|
||||
/// @throw PropertyValueException if value isn't of correct type.
|
||||
const TVector &ValueList() const {
|
||||
const std::vector<PropertyValue> &ValueList() const {
|
||||
if (type_ != Type::List) {
|
||||
throw PropertyValueException("The value isn't a list!");
|
||||
}
|
||||
@@ -338,7 +169,7 @@ class PropertyValue {
|
||||
}
|
||||
|
||||
/// @throw PropertyValueException if value isn't of correct type.
|
||||
const TMap &ValueMap() const {
|
||||
const std::map<std::string, PropertyValue> &ValueMap() const {
|
||||
if (type_ != Type::Map) {
|
||||
throw PropertyValueException("The value isn't a map!");
|
||||
}
|
||||
@@ -347,7 +178,7 @@ class PropertyValue {
|
||||
|
||||
// reference value getters for non-primitive types
|
||||
/// @throw PropertyValueException if value isn't of correct type.
|
||||
TString &ValueString() {
|
||||
std::string &ValueString() {
|
||||
if (type_ != Type::String) {
|
||||
throw PropertyValueException("The value isn't a string!");
|
||||
}
|
||||
@@ -355,7 +186,7 @@ class PropertyValue {
|
||||
}
|
||||
|
||||
/// @throw PropertyValueException if value isn't of correct type.
|
||||
TVector &ValueList() {
|
||||
std::vector<PropertyValue> &ValueList() {
|
||||
if (type_ != Type::List) {
|
||||
throw PropertyValueException("The value isn't a list!");
|
||||
}
|
||||
@@ -363,7 +194,7 @@ class PropertyValue {
|
||||
}
|
||||
|
||||
/// @throw PropertyValueException if value isn't of correct type.
|
||||
TMap &ValueMap() {
|
||||
std::map<std::string, PropertyValue> &ValueMap() {
|
||||
if (type_ != Type::Map) {
|
||||
throw PropertyValueException("The value isn't a map!");
|
||||
}
|
||||
@@ -377,14 +208,13 @@ class PropertyValue {
|
||||
bool bool_v;
|
||||
int64_t int_v;
|
||||
double double_v;
|
||||
TString string_v;
|
||||
TVector list_v;
|
||||
TMap map_v;
|
||||
std::string string_v;
|
||||
std::vector<PropertyValue> list_v;
|
||||
std::map<std::string, PropertyValue> map_v;
|
||||
TemporalData temporal_data_v;
|
||||
};
|
||||
|
||||
Type type_;
|
||||
utils::MemoryResource *memory_{utils::NewDeleteResource()};
|
||||
};
|
||||
|
||||
// stream output
|
||||
@@ -499,14 +329,8 @@ inline bool operator<(const PropertyValue &first, const PropertyValue &second) n
|
||||
return first.ValueTemporalData() < second.ValueTemporalData();
|
||||
}
|
||||
}
|
||||
inline PropertyValue::PropertyValue(const PropertyValue &other)
|
||||
: PropertyValue(
|
||||
other,
|
||||
std::allocator_traits<utils::Allocator<PropertyValue>>::select_on_container_copy_construction(other.memory_)
|
||||
.GetMemoryResource()) {}
|
||||
|
||||
inline PropertyValue::PropertyValue(const PropertyValue &other, utils::MemoryResource *memory)
|
||||
: type_(other.type_), memory_{memory} {
|
||||
inline PropertyValue::PropertyValue(const PropertyValue &other) : type_(other.type_) {
|
||||
switch (other.type_) {
|
||||
case Type::Null:
|
||||
return;
|
||||
@@ -520,13 +344,13 @@ inline PropertyValue::PropertyValue(const PropertyValue &other, utils::MemoryRes
|
||||
this->double_v = other.double_v;
|
||||
return;
|
||||
case Type::String:
|
||||
new (&string_v) TString(other.string_v, memory_);
|
||||
new (&string_v) std::string(other.string_v);
|
||||
return;
|
||||
case Type::List:
|
||||
new (&list_v) TVector(other.list_v, memory_);
|
||||
new (&list_v) std::vector<PropertyValue>(other.list_v);
|
||||
return;
|
||||
case Type::Map:
|
||||
new (&map_v) TMap(other.map_v, memory_);
|
||||
new (&map_v) std::map<std::string, PropertyValue>(other.map_v);
|
||||
return;
|
||||
case Type::TemporalData:
|
||||
this->temporal_data_v = other.temporal_data_v;
|
||||
@@ -534,10 +358,7 @@ inline PropertyValue::PropertyValue(const PropertyValue &other, utils::MemoryRes
|
||||
}
|
||||
}
|
||||
|
||||
inline PropertyValue::PropertyValue(PropertyValue &&other) noexcept : PropertyValue(std::move(other), other.memory_) {}
|
||||
|
||||
inline PropertyValue::PropertyValue(PropertyValue &&other, utils::MemoryResource *memory) noexcept
|
||||
: type_(other.type_), memory_{memory} {
|
||||
inline PropertyValue::PropertyValue(PropertyValue &&other) noexcept : type_(other.type_) {
|
||||
switch (other.type_) {
|
||||
case Type::Null:
|
||||
break;
|
||||
@@ -551,13 +372,13 @@ inline PropertyValue::PropertyValue(PropertyValue &&other, utils::MemoryResource
|
||||
this->double_v = other.double_v;
|
||||
break;
|
||||
case Type::String:
|
||||
new (&string_v) TString(std::move(other.string_v), memory_);
|
||||
new (&string_v) std::string(std::move(other.string_v));
|
||||
break;
|
||||
case Type::List:
|
||||
new (&list_v) TVector(std::move(other.list_v), memory_);
|
||||
new (&list_v) std::vector<PropertyValue>(std::move(other.list_v));
|
||||
break;
|
||||
case Type::Map:
|
||||
new (&map_v) TMap(std::move(other.map_v), memory_);
|
||||
new (&map_v) std::map<std::string, PropertyValue>(std::move(other.map_v));
|
||||
break;
|
||||
case Type::TemporalData:
|
||||
this->temporal_data_v = other.temporal_data_v;
|
||||
@@ -588,13 +409,13 @@ inline PropertyValue &PropertyValue::operator=(const PropertyValue &other) {
|
||||
this->double_v = other.double_v;
|
||||
break;
|
||||
case Type::String:
|
||||
new (&string_v) TString(other.string_v, memory_);
|
||||
new (&string_v) std::string(other.string_v);
|
||||
break;
|
||||
case Type::List:
|
||||
new (&list_v) TVector(other.list_v, memory_);
|
||||
new (&list_v) std::vector<PropertyValue>(other.list_v);
|
||||
break;
|
||||
case Type::Map:
|
||||
new (&map_v) TMap(other.map_v, memory_);
|
||||
new (&map_v) std::map<std::string, PropertyValue>(other.map_v);
|
||||
break;
|
||||
case Type::TemporalData:
|
||||
this->temporal_data_v = other.temporal_data_v;
|
||||
@@ -623,13 +444,13 @@ inline PropertyValue &PropertyValue::operator=(PropertyValue &&other) noexcept {
|
||||
this->double_v = other.double_v;
|
||||
break;
|
||||
case Type::String:
|
||||
new (&string_v) TString(std::move(other.string_v), memory_);
|
||||
new (&string_v) std::string(std::move(other.string_v));
|
||||
break;
|
||||
case Type::List:
|
||||
new (&list_v) TVector(std::move(other.list_v), memory_);
|
||||
new (&list_v) std::vector<PropertyValue>(std::move(other.list_v));
|
||||
break;
|
||||
case Type::Map:
|
||||
new (&map_v) TMap(std::move(other.map_v), memory_);
|
||||
new (&map_v) std::map<std::string, PropertyValue>(std::move(other.map_v));
|
||||
break;
|
||||
case Type::TemporalData:
|
||||
this->temporal_data_v = other.temporal_data_v;
|
||||
|
||||
@@ -13,17 +13,13 @@ set(utils_src_files
|
||||
temporal.cpp
|
||||
thread.cpp
|
||||
thread_pool.cpp
|
||||
tsc.cpp
|
||||
uuid.cpp)
|
||||
|
||||
find_package(Boost REQUIRED)
|
||||
find_package(fmt REQUIRED)
|
||||
find_package(gflags REQUIRED)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
add_library(mg-utils STATIC ${utils_src_files})
|
||||
target_link_libraries(mg-utils PUBLIC Boost::headers fmt::fmt spdlog::spdlog)
|
||||
target_link_libraries(mg-utils PRIVATE librdtsc stdc++fs Threads::Threads gflags uuid rt)
|
||||
target_link_libraries(mg-utils PRIVATE stdc++fs Threads::Threads gflags uuid rt)
|
||||
|
||||
set(settings_src_files
|
||||
settings.cpp)
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
@@ -165,9 +164,8 @@ void *Pool::Allocate() {
|
||||
--chunk->blocks_available;
|
||||
return available_block;
|
||||
};
|
||||
if (last_alloc_chunk_ && last_alloc_chunk_->blocks_available > 0U) {
|
||||
if (last_alloc_chunk_ && last_alloc_chunk_->blocks_available > 0U)
|
||||
return allocate_block_from_chunk(last_alloc_chunk_);
|
||||
}
|
||||
// Find a Chunk with available memory.
|
||||
for (auto &chunk : chunks_) {
|
||||
if (chunk.blocks_available > 0U) {
|
||||
@@ -349,141 +347,4 @@ void PoolResource::Release() {
|
||||
|
||||
// PoolResource END
|
||||
|
||||
namespace impl {
|
||||
namespace {
|
||||
constexpr size_t kInitialChunkSize = 1;
|
||||
} // namespace
|
||||
FixedSizePool::FixedSizePool(const size_t block_size, const size_t max_blocks_per_chunk_,
|
||||
utils::MemoryResource *upstream)
|
||||
: block_size_{block_size},
|
||||
max_blocks_per_chunk_{max_blocks_per_chunk_},
|
||||
chunk_size_{kInitialChunkSize},
|
||||
upstream_{upstream} {
|
||||
internal_block_size_ = RoundUp(block_size, alignof(std::max_align_t));
|
||||
}
|
||||
|
||||
void *FixedSizePool::Allocate() {
|
||||
if (begin_ == end_) {
|
||||
if (free_list_) {
|
||||
Link *p = free_list_;
|
||||
free_list_ = p->next;
|
||||
return p;
|
||||
}
|
||||
|
||||
Replenish();
|
||||
}
|
||||
|
||||
auto *p = begin_;
|
||||
begin_ += internal_block_size_;
|
||||
return p;
|
||||
}
|
||||
|
||||
void FixedSizePool::Deallocate(void *p) {
|
||||
static_cast<Link *>(p)->next = free_list_;
|
||||
free_list_ = static_cast<Link *>(p);
|
||||
}
|
||||
|
||||
void FixedSizePool::Release() {
|
||||
chunk_list_.Release(upstream_);
|
||||
|
||||
chunk_size_ = kInitialChunkSize;
|
||||
begin_ = nullptr;
|
||||
end_ = nullptr;
|
||||
free_list_ = nullptr;
|
||||
}
|
||||
|
||||
FixedSizePool::~FixedSizePool() { Release(); }
|
||||
|
||||
void FixedSizePool::Replenish() {
|
||||
begin_ = static_cast<std::byte *>(chunk_list_.Allocate(chunk_size_ * internal_block_size_, upstream_));
|
||||
end_ = begin_ + chunk_size_ * internal_block_size_;
|
||||
|
||||
// TODO (antonio2368): Add more growth strategies
|
||||
const auto next_chunk_size = chunk_size_ * 2;
|
||||
if (next_chunk_size <= max_blocks_per_chunk_) {
|
||||
chunk_size_ = next_chunk_size;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace impl
|
||||
|
||||
namespace {
|
||||
inline uint64_t CeilLog2(const uint64_t x) { return utils::Log2(x) + !utils::IsPow2(x); }
|
||||
} // namespace
|
||||
|
||||
FixedSizePoolResource::FixedSizePoolResource(const size_t max_blocks_per_chunk, const size_t max_block_size,
|
||||
utils::MemoryResource *upstream)
|
||||
: upstream_{upstream} {
|
||||
max_block_size_ = min_block_size_;
|
||||
|
||||
num_pools_ = CeilLog2(max_block_size) - CeilLog2(min_block_size_) + 1;
|
||||
MG_ASSERT(num_pools_ > 0, "Invalid max size of the block.");
|
||||
|
||||
auto allocator = Allocator<impl::FixedSizePool>(upstream_);
|
||||
pools_ = allocator.allocate(num_pools_);
|
||||
|
||||
for (size_t i = 0; i < num_pools_; ++i) {
|
||||
allocator.construct(pools_ + i, max_block_size_, max_blocks_per_chunk, upstream);
|
||||
MG_ASSERT(max_block_size_ <= std::numeric_limits<size_t>::max() / 2);
|
||||
max_block_size_ *= 2;
|
||||
}
|
||||
|
||||
max_block_size_ /= 2;
|
||||
}
|
||||
|
||||
void *FixedSizePoolResource::DoAllocate(const size_t bytes, const size_t alignment) {
|
||||
MG_ASSERT(bytes > 0);
|
||||
void *ret{nullptr};
|
||||
if (bytes <= max_block_size_) {
|
||||
auto *pool = FindPool(bytes);
|
||||
ret = pool->Allocate();
|
||||
} else {
|
||||
// add to the list of allocated chunks
|
||||
ret = large_blocks_.Allocate(bytes, upstream_);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FixedSizePoolResource::DoDeallocate(void *p, const size_t bytes, const size_t alignment) {
|
||||
auto *pool = FindPool(bytes);
|
||||
|
||||
if (pool == nullptr) {
|
||||
large_blocks_.Deallocate(p, upstream_);
|
||||
} else {
|
||||
pool->Deallocate(p);
|
||||
}
|
||||
}
|
||||
|
||||
impl::FixedSizePool *FixedSizePoolResource::FindPool(const size_t size) const {
|
||||
if (size > max_block_size_) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto *pool = pools_;
|
||||
while (size > pool->BlockSize()) {
|
||||
++pool;
|
||||
}
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
void FixedSizePoolResource::Release() {
|
||||
for (size_t i = 0; i < num_pools_; ++i) {
|
||||
pools_[i].Release();
|
||||
}
|
||||
|
||||
large_blocks_.Release(upstream_);
|
||||
}
|
||||
|
||||
FixedSizePoolResource::~FixedSizePoolResource() {
|
||||
Release();
|
||||
|
||||
for (size_t i = 0; i < num_pools_; ++i) {
|
||||
pools_[i].~FixedSizePool();
|
||||
}
|
||||
|
||||
upstream_->Deallocate(pools_, sizeof(impl::FixedSizePool) * num_pools_, alignof(impl::FixedSizePool));
|
||||
}
|
||||
|
||||
} // namespace utils
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <new>
|
||||
@@ -24,9 +23,6 @@
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#ifndef NDEBUG
|
||||
#include <iostream>
|
||||
#endif
|
||||
// Although <memory_resource> is in C++17, gcc libstdc++ still needs to
|
||||
// implement it fully. It should be available in the next major release
|
||||
// version, i.e. gcc 9.x.
|
||||
@@ -568,217 +564,6 @@ class LimitedMemoryResource final : public utils::MemoryResource {
|
||||
bool DoIsEqual(const MemoryResource &other) const noexcept override { return this == &other; }
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
|
||||
// https://stackoverflow.com/a/9194117
|
||||
// if y is power 2 we can do (x + y - 1) & ~(y - 1);
|
||||
// https://stackoverflow.com/a/14561794
|
||||
constexpr size_t RoundUp(const size_t x, const size_t y) {
|
||||
MG_ASSERT(y >= 1);
|
||||
return (x + y - 1) / y * y;
|
||||
}
|
||||
|
||||
struct LinkedListNode {
|
||||
LinkedListNode *next;
|
||||
LinkedListNode *previous;
|
||||
};
|
||||
|
||||
struct BlockLinkedListHeaderBase : public LinkedListNode {
|
||||
size_t size;
|
||||
|
||||
using NodeType = LinkedListNode;
|
||||
};
|
||||
|
||||
struct SingleLinkedListNode {
|
||||
SingleLinkedListNode *next;
|
||||
};
|
||||
|
||||
struct BlockSingleLinkedListHeaderBase : public SingleLinkedListNode {
|
||||
size_t size;
|
||||
|
||||
using NodeType = SingleLinkedListNode;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
concept BlockLinkedListHeader = std::is_base_of_v<BlockLinkedListHeaderBase, T>;
|
||||
|
||||
template <typename T>
|
||||
concept BlockSingleLinkedListHeader = std::is_base_of_v<BlockSingleLinkedListHeaderBase, T>;
|
||||
|
||||
template <typename T>
|
||||
concept BlockListHeader = BlockLinkedListHeader<T> || BlockSingleLinkedListHeader<T>;
|
||||
|
||||
template <BlockListHeader THeader>
|
||||
class BlockList {
|
||||
using NodeType = typename THeader::NodeType;
|
||||
|
||||
public:
|
||||
static const size_t header_size = RoundUp(sizeof(THeader), alignof(std::max_align_t));
|
||||
|
||||
explicit BlockList() {
|
||||
// create a circular linked list
|
||||
list_.next = &list_;
|
||||
|
||||
if constexpr (BlockLinkedListHeader<THeader>) {
|
||||
list_.previous = &list_;
|
||||
}
|
||||
}
|
||||
|
||||
void *Allocate(const size_t bytes, utils::MemoryResource *rsrc) {
|
||||
if (bytes > static_cast<size_t>(-1) - header_size) {
|
||||
throw utils::BadAlloc("Requested too many bytes to allocate");
|
||||
}
|
||||
|
||||
void *p = rsrc->Allocate(bytes + header_size);
|
||||
auto *node = new (p) THeader;
|
||||
node->size = bytes + header_size;
|
||||
|
||||
auto *next = list_.next;
|
||||
node->next = next;
|
||||
list_.next = node;
|
||||
|
||||
if constexpr (BlockLinkedListHeader<THeader>) {
|
||||
node->previous = &list_;
|
||||
next->previous = node;
|
||||
}
|
||||
|
||||
return static_cast<std::byte *>(p) + header_size;
|
||||
}
|
||||
|
||||
template <typename T = THeader>
|
||||
requires BlockLinkedListHeader<T> void Deallocate(void *p, utils::MemoryResource *rsrc) {
|
||||
auto *header = static_cast<THeader *>(static_cast<void *>(static_cast<std::byte *>(p) - header_size));
|
||||
auto *next = header->next;
|
||||
auto *previous = header->previous;
|
||||
previous->next = next;
|
||||
next->previous = previous;
|
||||
|
||||
const size_t size = header->size;
|
||||
header->~THeader();
|
||||
rsrc->Deallocate(header, size, alignof(std::max_align_t));
|
||||
}
|
||||
|
||||
void Release(utils::MemoryResource *rsrc) {
|
||||
NodeType *node = list_.next;
|
||||
while (node != &list_) {
|
||||
auto *header = static_cast<THeader *>(node);
|
||||
node = node->next;
|
||||
const size_t size = header->size;
|
||||
header->~THeader();
|
||||
rsrc->Deallocate(header, size, alignof(std::max_align_t));
|
||||
}
|
||||
|
||||
// create a circular linked list
|
||||
list_.next = &list_;
|
||||
|
||||
if constexpr (BlockLinkedListHeader<THeader>) {
|
||||
list_.previous = &list_;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
NodeType list_;
|
||||
};
|
||||
|
||||
// https://github.com/bloomberg/bde/blob/master/groups/bdl/bdlma/bdlma_pool.h
|
||||
class FixedSizePool final {
|
||||
public:
|
||||
FixedSizePool(size_t block_size, size_t max_blocks_per_chunk, utils::MemoryResource *upstream);
|
||||
|
||||
FixedSizePool(const FixedSizePool &) = delete;
|
||||
FixedSizePool &operator=(const FixedSizePool &) = delete;
|
||||
|
||||
FixedSizePool(FixedSizePool &&) = default;
|
||||
FixedSizePool &operator=(FixedSizePool &&) = default;
|
||||
|
||||
void *Allocate();
|
||||
void Deallocate(void *p);
|
||||
|
||||
void Release();
|
||||
|
||||
auto BlockSize() const { return block_size_; }
|
||||
|
||||
~FixedSizePool();
|
||||
|
||||
private:
|
||||
struct Link {
|
||||
Link *next;
|
||||
};
|
||||
|
||||
std::byte *begin_{nullptr};
|
||||
std::byte *end_{nullptr};
|
||||
|
||||
Link *free_list_{nullptr};
|
||||
|
||||
size_t internal_block_size_;
|
||||
size_t block_size_;
|
||||
size_t max_blocks_per_chunk_;
|
||||
size_t chunk_size_;
|
||||
|
||||
BlockList<BlockSingleLinkedListHeaderBase> chunk_list_;
|
||||
|
||||
utils::MemoryResource *upstream_;
|
||||
|
||||
void Replenish();
|
||||
};
|
||||
} // namespace impl
|
||||
|
||||
// https://github.com/bloomberg/bde/blob/master/groups/bdl/bdlma/bdlma_multipool.h
|
||||
class FixedSizePoolResource : public MemoryResource {
|
||||
public:
|
||||
explicit FixedSizePoolResource(size_t max_blocks_per_chunk, size_t max_block_size,
|
||||
utils::MemoryResource *upstream = utils::NewDeleteResource());
|
||||
|
||||
void Release();
|
||||
|
||||
FixedSizePoolResource(const FixedSizePoolResource &) = delete;
|
||||
FixedSizePoolResource &operator=(const FixedSizePoolResource &) = delete;
|
||||
|
||||
FixedSizePoolResource(FixedSizePoolResource &&) = default;
|
||||
FixedSizePoolResource &operator=(FixedSizePoolResource &&) = default;
|
||||
|
||||
~FixedSizePoolResource() override;
|
||||
|
||||
private:
|
||||
impl::FixedSizePool *FindPool(size_t size) const;
|
||||
|
||||
void *DoAllocate(size_t bytes, size_t alignment) override;
|
||||
void DoDeallocate(void *p, size_t bytes, size_t alignment) override;
|
||||
|
||||
bool DoIsEqual(const MemoryResource &other) const noexcept override { return this == &other; }
|
||||
|
||||
impl::FixedSizePool *pools_{nullptr};
|
||||
size_t max_block_size_;
|
||||
size_t min_block_size_{8};
|
||||
size_t num_pools_{0};
|
||||
|
||||
impl::BlockList<impl::BlockLinkedListHeaderBase> large_blocks_;
|
||||
|
||||
utils::MemoryResource *upstream_;
|
||||
};
|
||||
|
||||
#ifndef NDEBUG
|
||||
class PrintMemoryResource : public MemoryResource {
|
||||
public:
|
||||
explicit PrintMemoryResource(utils::MemoryResource *memory) : memory_(memory) {}
|
||||
|
||||
private:
|
||||
void *DoAllocate(size_t bytes, size_t alignment) override {
|
||||
std::cout << "Allocating " << bytes << std::endl;
|
||||
return memory_->Allocate(bytes, alignment);
|
||||
}
|
||||
|
||||
void DoDeallocate(void *p, size_t bytes, size_t alignment) override {
|
||||
std::cout << "Deallocating " << bytes << std::endl;
|
||||
return memory_->Deallocate(p, bytes, alignment);
|
||||
}
|
||||
|
||||
bool DoIsEqual(const utils::MemoryResource &other) const noexcept override { return memory_->IsEqual(other); }
|
||||
|
||||
utils::MemoryResource *memory_;
|
||||
};
|
||||
#endif
|
||||
|
||||
// Allocate memory with the OutOfMemoryException enabled if the requested size
|
||||
// puts total allocated amount over the limit.
|
||||
class ResourceWithOutOfMemoryException : public MemoryResource {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user