Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9fa8ac31dc | |||
| d45f888b9a | |||
| 1af7949d1b | |||
| 9330c2ee49 | |||
| 9f100b3fb1 | |||
| 97741e796d | |||
| 48dbab6de8 | |||
| ebc0275572 | |||
| ed77870ccc | |||
| 2ff10561bd | |||
| 85601037ef | |||
| 3fb27eb32e | |||
| 535b51d6fe | |||
| cda4489045 | |||
| 044ecc93c6 | |||
| 55492d5a14 | |||
| 15a7442759 | |||
| 9c4bd6d711 | |||
| 54bf15afef | |||
| 8663ed1c21 | |||
| 5a6292db4e | |||
| 5f5101adc3 | |||
| 26a0326dc5 | |||
| 44ec20773e | |||
| 22eeb2914f | |||
| ad7a61b745 | |||
| 96b9a1d5fd | |||
| dbac16ad65 | |||
| 780e646ff5 | |||
| 07684bced7 | |||
| e7dc77695c | |||
| 5f408ae7f5 | |||
| cc6f67cec9 | |||
| 675d6fb210 | |||
| dbee9bf49a | |||
| d6a0956c35 | |||
| a0546dbc86 | |||
| e3fe048411 | |||
| e275292728 | |||
| 27416441b3 |
@@ -0,0 +1,16 @@
|
||||
name: CI
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
Ubuntu:
|
||||
uses: named-data/actions/.github/workflows/jenkins-script-ubuntu.yml@v1
|
||||
macOS:
|
||||
uses: named-data/actions/.github/workflows/jenkins-script-macos.yml@v1
|
||||
PPA:
|
||||
uses: named-data/actions/.github/workflows/ppa.yml@v1
|
||||
with:
|
||||
extra-deps: libboost-iostreams-dev
|
||||
@@ -0,0 +1,10 @@
|
||||
name: Docs
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
html:
|
||||
uses: named-data/actions/.github/workflows/docs-html.yml@v1
|
||||
+1
-1
@@ -26,4 +26,4 @@ __pycache__/
|
||||
*.py[cod]
|
||||
|
||||
# Other
|
||||
/VERSION
|
||||
/VERSION.info
|
||||
|
||||
@@ -1,10 +1,52 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
set -eo pipefail
|
||||
|
||||
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
case $(uname) in
|
||||
Linux)
|
||||
if [[ -e /etc/os-release ]]; then
|
||||
source /etc/os-release
|
||||
else
|
||||
source /usr/lib/os-release
|
||||
fi
|
||||
export ID VERSION_ID
|
||||
export ID_LIKE="${ID} ${ID_LIKE} linux"
|
||||
export PATH="${HOME}/.local/bin${PATH:+:}${PATH}"
|
||||
;;
|
||||
Darwin)
|
||||
# Emulate a subset of os-release(5)
|
||||
export ID=macos
|
||||
export VERSION_ID=$(sw_vers -productVersion)
|
||||
export PATH="/usr/local/bin${PATH:+:}${PATH}"
|
||||
if [[ -x /opt/homebrew/bin/brew ]]; then
|
||||
eval "$(/opt/homebrew/bin/brew shellenv)"
|
||||
elif [[ -x /usr/local/bin/brew ]]; then
|
||||
eval "$(/usr/local/bin/brew shellenv)"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
for file in "$DIR"/.jenkins.d/*; do
|
||||
export CACHE_DIR=${CACHE_DIR:-/tmp}
|
||||
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
export DISABLE_ASAN=yes
|
||||
export DISABLE_HEADERS_CHECK=yes
|
||||
fi
|
||||
|
||||
# https://reproducible-builds.org/docs/source-date-epoch/
|
||||
export SOURCE_DATE_EPOCH=$(git log -1 --format=%ct)
|
||||
|
||||
for file in .jenkins.d/*; do
|
||||
[[ -f $file && -x $file ]] || continue
|
||||
echo "Run: $file"
|
||||
|
||||
if [[ -n $GITHUB_ACTIONS ]]; then
|
||||
label=$(basename "$file" | sed -E 's/[[:digit:]]+-(.*)\..*/\1/')
|
||||
echo "::group::${label}"
|
||||
fi
|
||||
|
||||
echo "\$ $file"
|
||||
"$file"
|
||||
|
||||
if [[ -n $GITHUB_ACTIONS ]]; then
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
done
|
||||
|
||||
+29
-20
@@ -1,29 +1,38 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
set -eo pipefail
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
APT_PKGS=(build-essential pkg-config python3-minimal
|
||||
libboost-all-dev libssl-dev libsqlite3-dev)
|
||||
FORMULAE=(boost openssl pkg-config)
|
||||
PIP_PKGS=()
|
||||
case $JOB_NAME in
|
||||
*code-coverage)
|
||||
APT_PKGS+=(lcov python3-pip)
|
||||
PIP_PKGS+=('gcovr~=5.2')
|
||||
;;
|
||||
*Docs)
|
||||
APT_PKGS+=(doxygen graphviz python3-pip)
|
||||
FORMULAE+=(doxygen graphviz)
|
||||
PIP_PKGS+=(sphinx sphinxcontrib-doxylink)
|
||||
;;
|
||||
esac
|
||||
|
||||
set -x
|
||||
|
||||
if has OSX $NODE_LABELS; then
|
||||
FORMULAE=(boost openssl pkg-config)
|
||||
brew update
|
||||
if [[ -n $TRAVIS ]]; then
|
||||
# travis images come with a large number of brew packages
|
||||
# pre-installed, don't waste time upgrading all of them
|
||||
for FORMULA in "${FORMULAE[@]}"; do
|
||||
brew outdated $FORMULA || brew upgrade $FORMULA
|
||||
done
|
||||
else
|
||||
brew upgrade
|
||||
if [[ $ID == macos ]]; then
|
||||
if [[ -n $GITHUB_ACTIONS ]]; then
|
||||
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
|
||||
fi
|
||||
brew install "${FORMULAE[@]}"
|
||||
brew cleanup
|
||||
brew update
|
||||
brew install --formula "${FORMULAE[@]}"
|
||||
elif [[ $ID_LIKE == *debian* ]]; then
|
||||
sudo apt-get -qq update
|
||||
sudo apt-get -qy install "${APT_PKGS[@]}"
|
||||
elif [[ $ID_LIKE == *fedora* ]]; then
|
||||
sudo dnf -y install gcc-c++ libasan lld pkgconf-pkg-config python3 \
|
||||
boost-devel openssl-devel sqlite-devel
|
||||
fi
|
||||
|
||||
if has Ubuntu $NODE_LABELS; then
|
||||
sudo apt-get -qq update
|
||||
sudo apt-get -qy install build-essential pkg-config libboost-all-dev \
|
||||
libsqlite3-dev libssl-dev
|
||||
if (( ${#PIP_PKGS[@]} )); then
|
||||
pip3 install --user --upgrade --upgrade-strategy=eager "${PIP_PKGS[@]}"
|
||||
fi
|
||||
|
||||
+16
-22
@@ -1,16 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
set -exo pipefail
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
|
||||
set -x
|
||||
|
||||
pushd "${CACHE_DIR:-/tmp}" >/dev/null
|
||||
pushd "$CACHE_DIR" >/dev/null
|
||||
|
||||
INSTALLED_VERSION=
|
||||
if has OSX $NODE_LABELS; then
|
||||
BOOST=$(brew ls --versions boost)
|
||||
if [[ $ID == macos ]]; then
|
||||
BOOST=$(brew list --formula --versions boost)
|
||||
OLD_BOOST=$(cat boost.txt || :)
|
||||
if [[ $OLD_BOOST != $BOOST ]]; then
|
||||
echo "$BOOST" > boost.txt
|
||||
@@ -22,17 +17,15 @@ if [[ -z $INSTALLED_VERSION ]]; then
|
||||
INSTALLED_VERSION=$(git -C ndn-cxx rev-parse HEAD 2>/dev/null || echo NONE)
|
||||
fi
|
||||
|
||||
sudo rm -Rf ndn-cxx-latest
|
||||
|
||||
git clone --depth 1 git://github.com/named-data/ndn-cxx ndn-cxx-latest
|
||||
|
||||
sudo rm -rf ndn-cxx-latest
|
||||
git clone --depth 1 https://github.com/named-data/ndn-cxx.git ndn-cxx-latest
|
||||
LATEST_VERSION=$(git -C ndn-cxx-latest rev-parse HEAD 2>/dev/null || echo UNKNOWN)
|
||||
|
||||
if [[ $INSTALLED_VERSION != $LATEST_VERSION ]]; then
|
||||
sudo rm -Rf ndn-cxx
|
||||
sudo rm -rf ndn-cxx
|
||||
mv ndn-cxx-latest ndn-cxx
|
||||
else
|
||||
sudo rm -Rf ndn-cxx-latest
|
||||
sudo rm -rf ndn-cxx-latest
|
||||
fi
|
||||
|
||||
sudo rm -f /usr/local/bin/ndnsec*
|
||||
@@ -42,15 +35,16 @@ sudo rm -f /usr/local/lib{,64}/pkgconfig/libndn-cxx.pc
|
||||
|
||||
pushd ndn-cxx >/dev/null
|
||||
|
||||
./waf configure --color=yes --enable-shared --disable-static --without-osx-keychain
|
||||
./waf build --color=yes -j${WAF_JOBS:-1}
|
||||
sudo_preserve_env PATH -- ./waf install --color=yes
|
||||
./waf --color=yes configure --without-osx-keychain
|
||||
./waf --color=yes build
|
||||
sudo ./waf --color=yes install
|
||||
|
||||
popd >/dev/null
|
||||
popd >/dev/null
|
||||
|
||||
if has Linux $NODE_LABELS; then
|
||||
sudo ldconfig
|
||||
elif has FreeBSD10 $NODE_LABELS; then
|
||||
sudo ldconfig -m
|
||||
if [[ $ID_LIKE == *fedora* ]]; then
|
||||
sudo tee /etc/ld.so.conf.d/ndn.conf >/dev/null <<< /usr/local/lib64
|
||||
fi
|
||||
if [[ $ID_LIKE == *linux* ]]; then
|
||||
sudo ldconfig
|
||||
fi
|
||||
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -exo pipefail
|
||||
|
||||
PROJ=ChronoSync
|
||||
|
||||
sudo rm -fr /usr/local/include/"$PROJ"
|
||||
sudo rm -f /usr/local/lib{,64}/lib"$PROJ"*
|
||||
sudo rm -f /usr/local/lib{,64}/pkgconfig/{,lib}"$PROJ".pc
|
||||
+26
-30
@@ -1,47 +1,43 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
set -eo pipefail
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
if [[ -z $DISABLE_ASAN ]]; then
|
||||
ASAN="--with-sanitizer=address"
|
||||
fi
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
COVERAGE="--with-coverage"
|
||||
fi
|
||||
|
||||
set -x
|
||||
|
||||
if [[ $JOB_NAME == *"code-coverage" ]]; then
|
||||
COVERAGE="--with-coverage"
|
||||
elif [[ -z $DISABLE_ASAN ]]; then
|
||||
ASAN="--with-sanitizer=address"
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
sudo_preserve_env PATH -- ./waf --color=yes distclean
|
||||
|
||||
if [[ $JOB_NAME != *"code-coverage" && $JOB_NAME != *"limited-build" ]]; then
|
||||
# Configure/build in optimized mode with tests
|
||||
./waf --color=yes configure --with-tests
|
||||
./waf --color=yes build -j${WAF_JOBS:-1}
|
||||
# Build in release mode with tests
|
||||
./waf --color=yes configure --with-tests
|
||||
./waf --color=yes build
|
||||
|
||||
# Cleanup
|
||||
sudo_preserve_env PATH -- ./waf --color=yes distclean
|
||||
# Cleanup
|
||||
./waf --color=yes distclean
|
||||
|
||||
# Configure/build in optimized mode without tests
|
||||
./waf --color=yes configure
|
||||
./waf --color=yes build -j${WAF_JOBS:-1}
|
||||
# Build in release mode without tests
|
||||
./waf --color=yes configure
|
||||
./waf --color=yes build
|
||||
|
||||
# Cleanup
|
||||
sudo_preserve_env PATH -- ./waf --color=yes distclean
|
||||
# Cleanup
|
||||
./waf --color=yes distclean
|
||||
fi
|
||||
|
||||
# Configure/build in debug mode with tests
|
||||
# Build in debug mode with tests
|
||||
./waf --color=yes configure --debug --with-tests $ASAN $COVERAGE
|
||||
./waf --color=yes build -j${WAF_JOBS:-1}
|
||||
./waf --color=yes build
|
||||
|
||||
# (tests will be run against debug version)
|
||||
# (tests will be run against the debug version)
|
||||
|
||||
# Install
|
||||
sudo_preserve_env PATH -- ./waf --color=yes install
|
||||
sudo ./waf --color=yes install
|
||||
|
||||
if has Linux $NODE_LABELS; then
|
||||
sudo ldconfig
|
||||
elif has FreeBSD $NODE_LABELS; then
|
||||
sudo ldconfig -a
|
||||
if [[ $ID_LIKE == *fedora* ]]; then
|
||||
sudo tee /etc/ld.so.conf.d/ndn.conf >/dev/null <<< /usr/local/lib64
|
||||
fi
|
||||
if [[ $ID_LIKE == *linux* ]]; then
|
||||
sudo ldconfig
|
||||
fi
|
||||
|
||||
+18
-39
@@ -1,47 +1,26 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
set -eo pipefail
|
||||
|
||||
JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
source "$JDIR"/util.sh
|
||||
# https://github.com/google/sanitizers/wiki/AddressSanitizerFlags
|
||||
ASAN_OPTIONS="color=always"
|
||||
ASAN_OPTIONS+=":check_initialization_order=1"
|
||||
ASAN_OPTIONS+=":detect_stack_use_after_return=1"
|
||||
ASAN_OPTIONS+=":strict_init_order=1"
|
||||
ASAN_OPTIONS+=":strict_string_checks=1"
|
||||
ASAN_OPTIONS+=":detect_invalid_pointer_pairs=2"
|
||||
ASAN_OPTIONS+=":strip_path_prefix=${PWD}/"
|
||||
export ASAN_OPTIONS
|
||||
|
||||
# https://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/runtime_config/summary.html
|
||||
export BOOST_TEST_BUILD_INFO=1
|
||||
export BOOST_TEST_COLOR_OUTPUT=1
|
||||
export BOOST_TEST_DETECT_MEMORY_LEAK=0
|
||||
export BOOST_TEST_LOGGER=HRF,test_suite,stdout:XML,all,build/xunit-log.xml
|
||||
|
||||
set -x
|
||||
|
||||
# Prepare environment
|
||||
rm -Rf ~/.ndn
|
||||
|
||||
if has OSX $NODE_LABELS; then
|
||||
security unlock-keychain -p named-data
|
||||
fi
|
||||
|
||||
ndnsec-keygen "/tmp/jenkins/$NODE_NAME" | ndnsec-install-cert -
|
||||
|
||||
BOOST_VERSION=$(python -c "import sys; sys.path.append('build/c4che'); import _cache; print(_cache.BOOST_VERSION_NUMBER);")
|
||||
|
||||
ut_log_args() {
|
||||
if (( BOOST_VERSION >= 106200 )); then
|
||||
echo --logger=HRF,test_suite,stdout:XML,all,build/xunit-${1:-report}.xml
|
||||
else
|
||||
if [[ -n $XUNIT ]]; then
|
||||
echo --log_level=all $( (( BOOST_VERSION >= 106000 )) && echo -- ) \
|
||||
--log_format2=XML --log_sink2=build/xunit-${1:-report}.xml
|
||||
else
|
||||
echo --log_level=test_suite
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
ASAN_OPTIONS="color=always"
|
||||
ASAN_OPTIONS+=":detect_stack_use_after_return=true"
|
||||
ASAN_OPTIONS+=":check_initialization_order=true"
|
||||
ASAN_OPTIONS+=":strict_init_order=true"
|
||||
ASAN_OPTIONS+=":detect_invalid_pointer_pairs=1"
|
||||
ASAN_OPTIONS+=":detect_container_overflow=false"
|
||||
ASAN_OPTIONS+=":strict_string_checks=true"
|
||||
ASAN_OPTIONS+=":strip_path_prefix=${PWD}/"
|
||||
export ASAN_OPTIONS
|
||||
|
||||
export BOOST_TEST_BUILD_INFO=1
|
||||
export BOOST_TEST_COLOR_OUTPUT=1
|
||||
rm -rf ~/.ndn
|
||||
|
||||
# Run unit tests
|
||||
./build/unit-tests $(ut_log_args)
|
||||
./build/unit-tests
|
||||
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
# It's intentional not to use `set -x`, because this script explicitly prints useful information
|
||||
# and should not run in trace mode.
|
||||
|
||||
PROJ=ChronoSync
|
||||
PCFILE=ChronoSync
|
||||
|
||||
if [[ -n $DISABLE_HEADERS_CHECK ]]; then
|
||||
echo 'Skipping headers check.'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ $ID_LIKE == *fedora* ]]; then
|
||||
export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig
|
||||
fi
|
||||
|
||||
CXX=${CXX:-g++}
|
||||
STD=-std=c++17
|
||||
CXXFLAGS="-O2 -Wall -Wno-unneeded-internal-declaration -Wno-unused-const-variable $(pkg-config --cflags libndn-cxx $PCFILE)"
|
||||
INCLUDEDIR="$(pkg-config --variable=includedir $PCFILE)"/$PROJ
|
||||
|
||||
echo "Using: $CXX $STD $CXXFLAGS"
|
||||
|
||||
NCHECKED=0
|
||||
NERRORS=0
|
||||
while IFS= read -r -d '' H; do
|
||||
echo "Checking header ${H#${INCLUDEDIR}/}"
|
||||
"$CXX" -xc++ $STD $CXXFLAGS -c -o /dev/null "$H" || : $((NERRORS++))
|
||||
: $((NCHECKED++))
|
||||
done < <(find "$INCLUDEDIR" -name '*.hpp' -type f -print0 2>/dev/null)
|
||||
|
||||
if [[ $NCHECKED -eq 0 ]]; then
|
||||
echo "No headers found. Is $PROJ installed?"
|
||||
exit 1
|
||||
else
|
||||
echo "$NCHECKED headers checked."
|
||||
fi
|
||||
|
||||
if [[ $NERRORS -gt 0 ]]; then
|
||||
echo "$NERRORS headers could not be compiled."
|
||||
exit 1
|
||||
fi
|
||||
+24
-24
@@ -1,36 +1,36 @@
|
||||
CONTINUOUS INTEGRATION SCRIPTS
|
||||
==============================
|
||||
# Continuous Integration Scripts
|
||||
|
||||
Environment Variables Used in Build Scripts
|
||||
-------------------------------------------
|
||||
## Environment Variables
|
||||
|
||||
- `NODE_LABELS`: the variable defines a list of OS properties. The set values are used by the
|
||||
build scripts to select proper behavior for different OS.
|
||||
- `ID`: lower-case string that identifies the operating system, for example: `ID=ubuntu`,
|
||||
`ID=centos`. See [os-release(5)] for more information. On macOS, where `os-release` is
|
||||
not available, we emulate it by setting `ID=macos`.
|
||||
|
||||
The list should include at least `[OS_TYPE]`, `[DISTRO_TYPE]`, and `[DISTRO_VERSION]`.
|
||||
- `ID_LIKE`: space-separated list of operating system identifiers that are closely related
|
||||
to the running OS. See [os-release(5)] for more information. The listed values are used
|
||||
by the CI scripts to select the proper behavior for different platforms and OS flavors.
|
||||
|
||||
Possible values for Linux:
|
||||
Examples:
|
||||
|
||||
* `[OS_TYPE]`: `Linux`
|
||||
* `[DISTRO_TYPE]`: `Ubuntu`
|
||||
* `[DISTRO_VERSION]`: `Ubuntu-16.04`, `Ubuntu-18.04`
|
||||
- On CentOS, `ID_LIKE="centos rhel fedora linux"`
|
||||
- On Ubuntu, `ID_LIKE="ubuntu debian linux"`
|
||||
|
||||
Possible values for OS X / macOS:
|
||||
- `VERSION_ID`: identifies the operating system version, excluding any release code names.
|
||||
See [os-release(5)] for more information. Examples: `VERSION_ID=42`, `VERSION_ID=22.04`.
|
||||
|
||||
* `[OS_TYPE]`: `OSX`
|
||||
* `[DISTRO_TYPE]`: `OSX` (can be absent)
|
||||
* `[DISTRO_VERSION]`: `OSX-10.11`, `OSX-10.12`, `OSX-10.13`
|
||||
- `JOB_NAME`: defines the type of the current CI job. Depending on the job type, the CI
|
||||
scripts can perform different tasks.
|
||||
|
||||
- `JOB_NAME`: optional variable to define type of the job. Depending on the defined job type,
|
||||
the build scripts can perform different tasks.
|
||||
Supported values:
|
||||
|
||||
Possible values:
|
||||
- empty: default build task
|
||||
- `code-coverage`: debug build with tests and code coverage analysis
|
||||
- `limited-build`: only a single debug build with tests
|
||||
|
||||
* empty: default build process
|
||||
* `code-coverage` (Ubuntu Linux is assumed): debug build with tests and code coverage analysis
|
||||
* `limited-build`: only a single debug build with tests
|
||||
- `CACHE_DIR`: directory containing cached files from previous builds, e.g., a compiled
|
||||
version of ndn-cxx. If not set, `/tmp` is used.
|
||||
|
||||
- `CACHE_DIR`: the variable defines a path to folder containing cached files from previous builds,
|
||||
e.g., a compiled version of ndn-cxx library. If not set, `/tmp` is used.
|
||||
- `DISABLE_ASAN`: disable building with AddressSanitizer. This is automatically set for
|
||||
the `code-coverage` job type.
|
||||
|
||||
- `WAF_JOBS`: number of parallel build jobs used by waf, defaults to 1.
|
||||
[os-release(5)]: https://www.freedesktop.org/software/systemd/man/os-release.html
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
has() {
|
||||
local saved_xtrace
|
||||
[[ $- == *x* ]] && saved_xtrace=-x || saved_xtrace=+x
|
||||
set +x
|
||||
|
||||
local p=$1
|
||||
shift
|
||||
local i ret=1
|
||||
for i in "$@"; do
|
||||
if [[ "${i}" == "${p}" ]]; then
|
||||
ret=0
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
set ${saved_xtrace}
|
||||
return ${ret}
|
||||
}
|
||||
|
||||
sudo_preserve_env() {
|
||||
local saved_xtrace
|
||||
[[ $- == *x* ]] && saved_xtrace=-x || saved_xtrace=+x
|
||||
set +x
|
||||
|
||||
local vars=()
|
||||
while [[ $# -gt 0 ]]; do
|
||||
local arg=$1
|
||||
shift
|
||||
case ${arg} in
|
||||
--) break ;;
|
||||
*) vars+=("${arg}=${!arg}") ;;
|
||||
esac
|
||||
done
|
||||
|
||||
set ${saved_xtrace}
|
||||
sudo env "${vars[@]}" "$@"
|
||||
}
|
||||
-98
@@ -1,98 +0,0 @@
|
||||
language: cpp
|
||||
dist: bionic
|
||||
env:
|
||||
global:
|
||||
- WAF_JOBS=2
|
||||
|
||||
matrix:
|
||||
include:
|
||||
# Linux/gcc
|
||||
# https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test/+packages
|
||||
- os: linux
|
||||
env: COMPILER=g++-5
|
||||
- os: linux
|
||||
env: COMPILER=g++-6
|
||||
- os: linux
|
||||
env: COMPILER=g++-7
|
||||
- os: linux
|
||||
env: COMPILER=g++-8
|
||||
- os: linux
|
||||
env: COMPILER=g++-9
|
||||
|
||||
# Linux/clang
|
||||
# https://apt.llvm.org/
|
||||
- os: linux
|
||||
env: COMPILER=clang++-3.9
|
||||
- os: linux
|
||||
env: COMPILER=clang++-4.0
|
||||
- os: linux
|
||||
env: COMPILER=clang++-5.0
|
||||
- os: linux
|
||||
env: COMPILER=clang++-6.0
|
||||
# disable AddressSanitizer with clang 7 and 8
|
||||
# due to https://bugs.llvm.org/show_bug.cgi?id=40808
|
||||
- os: linux
|
||||
env: COMPILER=clang++-7 DISABLE_ASAN=yes
|
||||
- os: linux
|
||||
env: COMPILER=clang++-8 DISABLE_ASAN=yes
|
||||
- os: linux
|
||||
env: COMPILER=clang++-9
|
||||
- os: linux
|
||||
env: COMPILER=clang++-10
|
||||
|
||||
# macOS/clang
|
||||
# https://docs.travis-ci.com/user/reference/osx/#macos-version
|
||||
- os: osx
|
||||
osx_image: xcode9.2
|
||||
env: OSX_VERSION=10.12
|
||||
- os: osx
|
||||
osx_image: xcode9.4
|
||||
env: OSX_VERSION=10.13
|
||||
- os: osx
|
||||
osx_image: xcode10.1
|
||||
env: OSX_VERSION=10.13
|
||||
- os: osx
|
||||
osx_image: xcode10.3
|
||||
env: OSX_VERSION=10.14
|
||||
- os: osx
|
||||
osx_image: xcode11
|
||||
env: OSX_VERSION=10.14
|
||||
|
||||
allow_failures:
|
||||
- env: COMPILER=clang++-10
|
||||
|
||||
fast_finish: true
|
||||
|
||||
before_install: |
|
||||
case ${COMPILER} in
|
||||
g++-[567]|clang++-[3456].*)
|
||||
;;
|
||||
g++-*)
|
||||
travis_retry sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
travis_retry sudo apt-get -qq update
|
||||
;;
|
||||
clang++-*)
|
||||
LLVM_REPO=${COMPILER/clang++/llvm-toolchain-${TRAVIS_DIST}}
|
||||
travis_retry wget -nv -O - "https://apt.llvm.org/llvm-snapshot.gpg.key" | sudo apt-key add -
|
||||
travis_retry sudo add-apt-repository -y "deb http://apt.llvm.org/${TRAVIS_DIST}/ ${LLVM_REPO%-10} main"
|
||||
travis_retry sudo apt-get -qq update
|
||||
;;
|
||||
esac
|
||||
|
||||
install:
|
||||
- if [[ -n ${COMPILER} ]]; then travis_retry sudo apt-get -qy install "${COMPILER/clang++/clang}"; fi
|
||||
|
||||
before_script:
|
||||
- if [[ ${TRAVIS_OS_NAME} == linux ]]; then export NODE_LABELS="Linux Ubuntu Ubuntu-18.04"; fi
|
||||
- if [[ ${TRAVIS_OS_NAME} == osx ]]; then export NODE_LABELS="OSX OSX-${OSX_VERSION}"; fi
|
||||
- if [[ ${OSX_VERSION} == 10.12 ]]; then brew update; fi
|
||||
# workaround for https://github.com/Homebrew/homebrew-core/issues/26358
|
||||
- if [[ ${OSX_VERSION} == 10.12 ]]; then brew outdated python || brew upgrade python; fi
|
||||
# workaround for https://github.com/travis-ci/travis-ci/issues/6688
|
||||
- if [[ ${OSX_VERSION} == 10.12 ]]; then /usr/bin/yes | pip2 uninstall numpy || true; fi
|
||||
- if [[ -n ${COMPILER} ]]; then export CXX=${COMPILER}; fi
|
||||
- ${CXX:-c++} --version
|
||||
- python --version
|
||||
|
||||
script:
|
||||
- ./.jenkins
|
||||
+2
-2
@@ -54,8 +54,8 @@ from waflib import Utils, Logs, Errors
|
||||
from waflib.Configure import conf
|
||||
from waflib.TaskGen import feature, after_method
|
||||
|
||||
BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib']
|
||||
BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include']
|
||||
BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/homebrew/lib', '/opt/local/lib', '/sw/lib', '/lib']
|
||||
BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/homebrew/include', '/opt/local/include', '/sw/include']
|
||||
|
||||
BOOST_VERSION_FILE = 'boost/version.hpp'
|
||||
BOOST_VERSION_CODE = '''
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
import platform
|
||||
from waflib import Configure, Logs, Utils
|
||||
|
||||
|
||||
def options(opt):
|
||||
opt.add_option('--debug', '--with-debug', action='store_true', default=False,
|
||||
help='Compile in debugging mode with minimal optimizations (-O0 or -Og)')
|
||||
help='Compile in debugging mode with minimal optimizations (-Og)')
|
||||
|
||||
|
||||
def configure(conf):
|
||||
conf.start_msg('Checking C++ compiler version')
|
||||
@@ -15,17 +18,27 @@ def configure(conf):
|
||||
errmsg = ''
|
||||
warnmsg = ''
|
||||
if cxx == 'gcc':
|
||||
if ccver < (5, 3, 0):
|
||||
if ccver < (7, 4, 0):
|
||||
errmsg = ('The version of gcc you are using is too old.\n'
|
||||
'The minimum supported gcc version is 5.3.0.')
|
||||
'The minimum supported gcc version is 9.3.')
|
||||
elif ccver < (9, 3, 0):
|
||||
warnmsg = ('Using a version of gcc older than 9.3 is not '
|
||||
'officially supported and may result in build failures.')
|
||||
conf.flags = GccFlags()
|
||||
elif cxx == 'clang':
|
||||
if ccver < (3, 6, 0):
|
||||
if Utils.unversioned_sys_platform() == 'darwin':
|
||||
if ccver < (10, 0, 0):
|
||||
errmsg = ('The version of Xcode you are using is too old.\n'
|
||||
'The minimum supported Xcode version is 12.4.')
|
||||
elif ccver < (12, 0, 0):
|
||||
warnmsg = ('Using a version of Xcode older than 12.4 is not '
|
||||
'officially supported and may result in build failures.')
|
||||
elif ccver < (7, 0, 0):
|
||||
errmsg = ('The version of clang you are using is too old.\n'
|
||||
'The minimum supported clang version is 3.6.0.')
|
||||
'The minimum supported clang version is 7.0.')
|
||||
conf.flags = ClangFlags()
|
||||
else:
|
||||
warnmsg = 'Note: %s compiler is unsupported' % cxx
|
||||
warnmsg = f'{cxx} compiler is unsupported'
|
||||
conf.flags = CompilerFlags()
|
||||
|
||||
if errmsg:
|
||||
@@ -33,11 +46,11 @@ def configure(conf):
|
||||
conf.fatal(errmsg)
|
||||
elif warnmsg:
|
||||
conf.end_msg(ccverstr, color='YELLOW')
|
||||
Logs.warn(warnmsg)
|
||||
Logs.warn('WARNING: ' + warnmsg)
|
||||
else:
|
||||
conf.end_msg(ccverstr)
|
||||
|
||||
conf.areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0)
|
||||
conf.areCustomCxxflagsPresent = len(conf.env.CXXFLAGS) > 0
|
||||
|
||||
# General flags are always applied (e.g., selecting C++ language standard)
|
||||
generalFlags = conf.flags.getGeneralFlags(conf)
|
||||
@@ -45,6 +58,7 @@ def configure(conf):
|
||||
conf.add_supported_linkflags(generalFlags['LINKFLAGS'])
|
||||
conf.env.DEFINES += generalFlags['DEFINES']
|
||||
|
||||
|
||||
@Configure.conf
|
||||
def check_compiler_flags(conf):
|
||||
# Debug or optimized CXXFLAGS and LINKFLAGS are applied only if the
|
||||
@@ -67,10 +81,11 @@ def check_compiler_flags(conf):
|
||||
|
||||
conf.env.DEFINES += extraFlags['DEFINES']
|
||||
|
||||
|
||||
@Configure.conf
|
||||
def add_supported_cxxflags(self, cxxflags):
|
||||
"""
|
||||
Check which cxxflags are supported by compiler and add them to env.CXXFLAGS variable
|
||||
Check which cxxflags are supported by the active compiler and add them to env.CXXFLAGS variable.
|
||||
"""
|
||||
if len(cxxflags) == 0:
|
||||
return
|
||||
@@ -86,10 +101,11 @@ def add_supported_cxxflags(self, cxxflags):
|
||||
self.end_msg(' '.join(supportedFlags))
|
||||
self.env.prepend_value('CXXFLAGS', supportedFlags)
|
||||
|
||||
|
||||
@Configure.conf
|
||||
def add_supported_linkflags(self, linkflags):
|
||||
"""
|
||||
Check which linkflags are supported by compiler and add them to env.LINKFLAGS variable
|
||||
Check which linkflags are supported by the active compiler and add them to env.LINKFLAGS variable.
|
||||
"""
|
||||
if len(linkflags) == 0:
|
||||
return
|
||||
@@ -106,13 +122,17 @@ def add_supported_linkflags(self, linkflags):
|
||||
self.env.prepend_value('LINKFLAGS', supportedFlags)
|
||||
|
||||
|
||||
class CompilerFlags(object):
|
||||
class CompilerFlags:
|
||||
def getCompilerVersion(self, conf):
|
||||
return tuple(int(i) for i in conf.env.CC_VERSION)
|
||||
|
||||
def getGeneralFlags(self, conf):
|
||||
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are always needed"""
|
||||
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': []}
|
||||
return {
|
||||
'CXXFLAGS': [],
|
||||
'LINKFLAGS': [],
|
||||
'DEFINES': ['BOOST_ASIO_NO_DEPRECATED', 'BOOST_FILESYSTEM_NO_DEPRECATED'],
|
||||
}
|
||||
|
||||
def getDebugFlags(self, conf):
|
||||
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in debug mode"""
|
||||
@@ -122,95 +142,100 @@ class CompilerFlags(object):
|
||||
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in optimized mode"""
|
||||
return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': ['NDEBUG']}
|
||||
|
||||
class GccBasicFlags(CompilerFlags):
|
||||
|
||||
class GccClangCommonFlags(CompilerFlags):
|
||||
"""
|
||||
This class defines basic flags that work for both gcc and clang compilers
|
||||
This class defines common flags that work for both gcc and clang compilers.
|
||||
"""
|
||||
|
||||
def getGeneralFlags(self, conf):
|
||||
flags = super(GccBasicFlags, self).getGeneralFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-std=c++14']
|
||||
if Utils.unversioned_sys_platform() == 'linux':
|
||||
flags['LINKFLAGS'] += ['-fuse-ld=gold']
|
||||
elif Utils.unversioned_sys_platform() == 'freebsd':
|
||||
flags = super().getGeneralFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-std=c++17']
|
||||
if Utils.unversioned_sys_platform() != 'darwin':
|
||||
flags['LINKFLAGS'] += ['-fuse-ld=lld']
|
||||
return flags
|
||||
|
||||
__cxxFlags = [
|
||||
'-fdiagnostics-color',
|
||||
'-Wall',
|
||||
'-Wextra',
|
||||
'-Wpedantic',
|
||||
'-Wenum-conversion',
|
||||
'-Wextra-semi',
|
||||
'-Wnon-virtual-dtor',
|
||||
'-Wno-unused-parameter',
|
||||
]
|
||||
__linkFlags = ['-Wl,-O1']
|
||||
|
||||
def getDebugFlags(self, conf):
|
||||
flags = super(GccBasicFlags, self).getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-O0',
|
||||
'-Og', # gcc >= 4.8, clang >= 4.0
|
||||
'-g3',
|
||||
'-pedantic',
|
||||
'-Wall',
|
||||
'-Wextra',
|
||||
'-Werror',
|
||||
'-Wnon-virtual-dtor',
|
||||
'-Wno-error=deprecated-declarations', # Bug #3795
|
||||
'-Wno-error=maybe-uninitialized', # Bug #1615
|
||||
'-Wno-unused-parameter',
|
||||
]
|
||||
flags['LINKFLAGS'] += ['-Wl,-O1']
|
||||
flags = super().getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-Og', '-g'] + self.__cxxFlags + [
|
||||
'-Werror',
|
||||
'-Wno-error=deprecated-declarations', # Bug #3795
|
||||
'-Wno-error=maybe-uninitialized', # Bug #1615
|
||||
]
|
||||
flags['LINKFLAGS'] += self.__linkFlags
|
||||
return flags
|
||||
|
||||
def getOptimizedFlags(self, conf):
|
||||
flags = super(GccBasicFlags, self).getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-O2',
|
||||
'-g',
|
||||
'-pedantic',
|
||||
'-Wall',
|
||||
'-Wextra',
|
||||
'-Wnon-virtual-dtor',
|
||||
'-Wno-unused-parameter',
|
||||
]
|
||||
flags['LINKFLAGS'] += ['-Wl,-O1']
|
||||
flags = super().getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-O2', '-g1'] + self.__cxxFlags
|
||||
flags['LINKFLAGS'] += self.__linkFlags
|
||||
return flags
|
||||
|
||||
class GccFlags(GccBasicFlags):
|
||||
|
||||
class GccFlags(GccClangCommonFlags):
|
||||
__cxxFlags = [
|
||||
'-Wcatch-value=2',
|
||||
'-Wcomma-subscript', # enabled by default in C++20
|
||||
'-Wduplicated-branches',
|
||||
'-Wduplicated-cond',
|
||||
'-Wlogical-op',
|
||||
'-Wredundant-tags',
|
||||
'-Wvolatile', # enabled by default in C++20
|
||||
]
|
||||
|
||||
def getDebugFlags(self, conf):
|
||||
flags = super(GccFlags, self).getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-fdiagnostics-color']
|
||||
flags = super().getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += self.__cxxFlags
|
||||
if platform.machine() == 'armv7l':
|
||||
flags['CXXFLAGS'] += ['-Wno-psabi'] # Bug #5106
|
||||
return flags
|
||||
|
||||
def getOptimizedFlags(self, conf):
|
||||
flags = super(GccFlags, self).getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-fdiagnostics-color']
|
||||
flags = super().getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += self.__cxxFlags
|
||||
if platform.machine() == 'armv7l':
|
||||
flags['CXXFLAGS'] += ['-Wno-psabi'] # Bug #5106
|
||||
return flags
|
||||
|
||||
class ClangFlags(GccBasicFlags):
|
||||
|
||||
class ClangFlags(GccClangCommonFlags):
|
||||
def getGeneralFlags(self, conf):
|
||||
flags = super(ClangFlags, self).getGeneralFlags(conf)
|
||||
if Utils.unversioned_sys_platform() == 'darwin' and self.getCompilerVersion(conf) >= (9, 0, 0):
|
||||
flags = super().getGeneralFlags(conf)
|
||||
if Utils.unversioned_sys_platform() == 'darwin':
|
||||
# Bug #4296
|
||||
flags['CXXFLAGS'] += [['-isystem', '/usr/local/include'], # for Homebrew
|
||||
['-isystem', '/opt/local/include']] # for MacPorts
|
||||
if Utils.unversioned_sys_platform() == 'freebsd':
|
||||
flags['CXXFLAGS'] += [['-isystem', '/usr/local/include']] # Bug #4790
|
||||
brewdir = '/opt/homebrew' if platform.machine() == 'arm64' else '/usr/local'
|
||||
flags['CXXFLAGS'] += [
|
||||
['-isystem', f'{brewdir}/include'], # for Homebrew
|
||||
['-isystem', '/opt/local/include'], # for MacPorts
|
||||
]
|
||||
elif Utils.unversioned_sys_platform() == 'freebsd':
|
||||
# Bug #4790
|
||||
flags['CXXFLAGS'] += [['-isystem', '/usr/local/include']]
|
||||
return flags
|
||||
|
||||
__cxxFlags = [
|
||||
'-Wundefined-func-template',
|
||||
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
|
||||
]
|
||||
|
||||
def getDebugFlags(self, conf):
|
||||
flags = super(ClangFlags, self).getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
|
||||
'-Wextra-semi',
|
||||
'-Wundefined-func-template',
|
||||
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
|
||||
]
|
||||
version = self.getCompilerVersion(conf)
|
||||
if version < (3, 9, 0) or (Utils.unversioned_sys_platform() == 'darwin' and version < (8, 1, 0)):
|
||||
flags['CXXFLAGS'] += ['-Wno-unknown-pragmas']
|
||||
if version < (6, 0, 0):
|
||||
flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
|
||||
flags = super().getDebugFlags(conf)
|
||||
flags['CXXFLAGS'] += self.__cxxFlags
|
||||
return flags
|
||||
|
||||
def getOptimizedFlags(self, conf):
|
||||
flags = super(ClangFlags, self).getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
|
||||
'-Wextra-semi',
|
||||
'-Wundefined-func-template',
|
||||
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
|
||||
]
|
||||
version = self.getCompilerVersion(conf)
|
||||
if version < (3, 9, 0) or (Utils.unversioned_sys_platform() == 'darwin' and version < (8, 1, 0)):
|
||||
flags['CXXFLAGS'] += ['-Wno-unknown-pragmas']
|
||||
if version < (6, 0, 0):
|
||||
flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
|
||||
flags = super().getOptimizedFlags(conf)
|
||||
flags['CXXFLAGS'] += self.__cxxFlags
|
||||
return flags
|
||||
|
||||
+16
-7
@@ -1,8 +1,17 @@
|
||||
ChronoSync authors
|
||||
==================
|
||||
# ChronoSync Authors
|
||||
|
||||
- Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
|
||||
- Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
|
||||
- Chaoyi Bian <bcy@pku.edu.cn>
|
||||
- Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/web/index.html>
|
||||
- Sonu Mishra <https://www.linkedin.com/in/mishrasonu>
|
||||
The following lists maintainers, primary developers, and all much-appreciated contributors to ChronoSync in alphabetical order.
|
||||
The specific contributions of individual authors can be obtained from the git history of the [official ChronoSync repository](https://github.com/named-data/ChronoSync).
|
||||
If you would like to become a contributor to the official repository, please follow the recommendations in <https://github.com/named-data/.github/blob/main/CONTRIBUTING.md>.
|
||||
|
||||
* ***(Maintainer)*** Alexander Afanasyev <https://users.cs.fiu.edu/~afanasyev>
|
||||
* Chaoyi Bian <https://github.com/bcy>
|
||||
* Qiuhan Ding <https://irl.cs.ucla.edu/~qiuhanding>
|
||||
* Ashlesh Gawande <https://www.linkedin.com/in/agawande>
|
||||
* Nick Gordon <https://github.com/gorgonical>
|
||||
* Sonu Mishra <https://sites.google.com/site/sonukrmishra93>
|
||||
* Eric Newberry <https://ericnewberry.com>
|
||||
* Davide Pesavento <https://github.com/Pesa>
|
||||
* Junxiao Shi <https://cs.arizona.edu/~shijunxiao>
|
||||
* Yingdi Yu <https://irl.cs.ucla.edu/~yingdi>
|
||||
* ***(Former Maintainer)*** Zhenkai Zhu <https://irl.cs.ucla.edu/~zhenkai>
|
||||
|
||||
+354
-356
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,11 @@
|
||||
ChronoSync: synchronization library for distributed realtime applications for NDN
|
||||
=================================================================================
|
||||
# ChronoSync: synchronization library for distributed realtime applications for NDN
|
||||
|
||||
[](https://travis-ci.org/named-data/ChronoSync)
|
||||
[](https://github.com/named-data/ChronoSync/actions/workflows/ci.yml)
|
||||
[](https://github.com/named-data/ChronoSync/actions/workflows/docs.yml)
|
||||

|
||||

|
||||
|
||||
If you are new to the NDN community of software generally, read the
|
||||
[Contributor's Guide](https://github.com/named-data/NFD/blob/master/CONTRIBUTING.md).
|
||||
> DEPRECATION NOTICE: ChronoSync's design is outdated. We recommend using more recent sync protocols, such as [PSync](https://github.com/named-data/PSync) or [StateVectorSync](https://named-data.github.io/StateVectorSync/).
|
||||
|
||||
In supporting many distributed applications, such as group text messaging, file sharing,
|
||||
and joint editing, a basic requirement is the efficient and robust synchronization of
|
||||
@@ -19,39 +20,41 @@ be inferred from the digests and disseminated efficiently to all parties. With
|
||||
complete and up-to-date knowledge of the dataset changes, applications can decide whether
|
||||
or when to fetch which pieces of the data.
|
||||
|
||||
ChronoSync uses [ndn-cxx](https://github.com/named-data/ndn-cxx) library as NDN development
|
||||
library.
|
||||
ChronoSync uses the [ndn-cxx](https://github.com/named-data/ndn-cxx) library.
|
||||
|
||||
ChronoSync is an open source project licensed under GPL 3.0 (see `COPYING.md` for more
|
||||
detail). We highly welcome all contributions to the ChronoSync code base, provided that
|
||||
they can licensed under GPL 3.0+ or other compatible license.
|
||||
|
||||
Feedback
|
||||
--------
|
||||
|
||||
Please submit any bugs or issues to the **ChronoSync** issue tracker:
|
||||
|
||||
* https://redmine.named-data.net/projects/chronosync
|
||||
|
||||
Installation instructions
|
||||
-------------------------
|
||||
## Installation
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Required:
|
||||
|
||||
* [ndn-cxx and its dependencies](https://named-data.net/doc/ndn-cxx/)
|
||||
* [ndn-cxx and its dependencies](https://docs.named-data.net/ndn-cxx/current/INSTALL.html)
|
||||
|
||||
### Build
|
||||
|
||||
To build ChronoSync from the source:
|
||||
To build ChronoSync from source:
|
||||
|
||||
./waf configure
|
||||
./waf
|
||||
sudo ./waf install
|
||||
|
||||
To build on memory constrained platform, please use `./waf -j1` instead of `./waf`. The
|
||||
command will disable parallel compilation.
|
||||
To build on memory constrained systems, please use `./waf -j1` instead of `./waf`. This
|
||||
will disable parallel compilation.
|
||||
|
||||
If configured with tests: `./waf configure --with-tests`), the above commands will also
|
||||
generate unit tests in `./build/unit-tests`
|
||||
If configured with tests (`./waf configure --with-tests`), the above commands will also
|
||||
build a suite of unit tests that can be run with `./build/unit-tests`.
|
||||
|
||||
## Reporting bugs
|
||||
|
||||
Please submit any bug reports or feature requests to the
|
||||
[ChronoSync issue tracker](https://redmine.named-data.net/projects/chronosync/issues).
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions to ChronoSync are greatly appreciated and can be made through our
|
||||
[Gerrit code review site](https://gerrit.named-data.net/).
|
||||
If you are new to the NDN software community, please read our [Contributor's Guide](
|
||||
https://github.com/named-data/.github/blob/main/CONTRIBUTING.md) to get started.
|
||||
|
||||
## License
|
||||
|
||||
ChronoSync is free software distributed under the GNU General Public License version 3.
|
||||
See [`COPYING.md`](COPYING.md) for details.
|
||||
|
||||
+42
-8
@@ -1,5 +1,42 @@
|
||||
# Release Notes
|
||||
|
||||
## Version 0.5.5
|
||||
|
||||
- The minimum build requirements have been increased as follows:
|
||||
|
||||
- Either GCC >= 7.4.0 or Clang >= 6.0 is required on Linux
|
||||
- On macOS, Xcode 11.3 or later is recommended; older versions may still work but are
|
||||
not officially supported
|
||||
- Boost >= 1.65.1 and ndn-cxx >= 0.8.1 are required on all platforms
|
||||
- Sphinx 4.0 or later is required to build the documentation
|
||||
|
||||
- Switch to C++17
|
||||
|
||||
- Fix compilation against the latest version of ndn-cxx
|
||||
|
||||
- Stop using the `gold` linker on Linux; prefer instead linking with `lld` if installed
|
||||
|
||||
- Upgrade `waf` to version 2.0.24
|
||||
|
||||
## Version 0.5.4
|
||||
|
||||
- The build requirements have been increased to require Clang >= 4.0, Xcode >= 9.0,
|
||||
and Python >= 3.6. Meanwhile, it is *recommended* to use GCC >= 7.4.0 and
|
||||
Boost >= 1.65.1. This effectively drops official support for Ubuntu 16.04 when
|
||||
using distribution-provided packages; ChronoSync may still work on this platform,
|
||||
but we provide no official support for it.
|
||||
|
||||
- Exceptions are now thrown using `NDN_THROW` instead of `BOOST_THROW_EXCEPTION`
|
||||
|
||||
- The private header files `config.hpp`, `common.hpp`, `bzip2-helper.hpp`,
|
||||
`mi-tag.hpp`, and `tlv.hpp` have been moved to a `detail` subdirectory
|
||||
|
||||
- Fix compilation against the latest version of ndn-cxx
|
||||
|
||||
- Fix incompatibility with the C++20 `<version>` header
|
||||
|
||||
- Upgrade `waf` to version 2.0.21
|
||||
|
||||
## Version 0.5.3
|
||||
|
||||
- Schedule sync Interest when receiving a NACK with reason `NoRoute` (Issue #5012)
|
||||
@@ -28,7 +65,7 @@
|
||||
|
||||
## Version 0.5.0
|
||||
|
||||
- **Breaking change:** Use bzip2 compression of sync Data payload (Issue #4140)
|
||||
- *Breaking change:* Use bzip2 compression of sync Data payload (Issue #4140)
|
||||
|
||||
- Disallow Interest loopback on sync prefix (Issue #3979)
|
||||
|
||||
@@ -36,13 +73,10 @@
|
||||
|
||||
- Extend `Socket` and `Logic` API:
|
||||
|
||||
- Allow customization of sync Interest lifetime (Issue #4490)
|
||||
|
||||
- Limit the size of created sync Data and enable ability to
|
||||
customize the maximum packet size through environment variable
|
||||
(Issue #4140)
|
||||
|
||||
- Allow override of the session number
|
||||
- Allow customization of sync Interest lifetime (Issue #4490)
|
||||
- Limit the size of created sync Data and enable ability to customize
|
||||
the maximum packet size through environment variable (Issue #4140)
|
||||
- Allow override of the session number
|
||||
|
||||
- Disable use of Exclude filter (preparation for Exclude deprecation
|
||||
in NDN and implementation was only partially correct)
|
||||
|
||||
+52
-230
@@ -1,258 +1,80 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# NFD - Named Data Networking Forwarding Daemon documentation build configuration file, created by
|
||||
# sphinx-quickstart on Sun Apr 6 19:58:22 2014.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
# For the full list of built-in configuration values, see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
|
||||
import importlib.util
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
# -- Project information -----------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
project = 'ChronoSync: A Synchronization Protocol for NDN'
|
||||
copyright = 'Copyright © 2012-2023 Regents of the University of California.'
|
||||
author = 'Named Data Networking Project'
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
# The short X.Y version.
|
||||
#version = ''
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.todo',
|
||||
]
|
||||
|
||||
def addExtensionIfExists(extension):
|
||||
try:
|
||||
__import__(extension)
|
||||
extensions.append(extension)
|
||||
except ImportError:
|
||||
sys.stderr.write("Extension '%s' in not available. "
|
||||
"Some documentation may not build correctly.\n" % extension)
|
||||
sys.stderr.write("To install, use \n"
|
||||
" sudo pip install %s\n" % extension.replace('.', '-'))
|
||||
|
||||
if sys.version_info[0] >= 3:
|
||||
addExtensionIfExists('sphinxcontrib.doxylink')
|
||||
|
||||
# sphinxcontrib.googleanalytics is currently not working with the latest version of sphinx
|
||||
# if os.getenv('GOOGLE_ANALYTICS', None):
|
||||
# addExtensionIfExists('sphinxcontrib.googleanalytics')
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'ChronoSync: A Synchronization Protocol in NDN'
|
||||
copyright = u'2017, Named Data Networking Project'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
#release = ''
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = []
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
#keep_warnings = False
|
||||
today_fmt = '%Y-%m-%d'
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
# -- General configuration ---------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
||||
|
||||
needs_sphinx = '4.0'
|
||||
extensions = [
|
||||
'sphinx.ext.extlinks',
|
||||
'sphinx.ext.todo',
|
||||
]
|
||||
|
||||
def addExtensionIfExists(extension: str):
|
||||
try:
|
||||
if importlib.util.find_spec(extension) is None:
|
||||
raise ModuleNotFoundError(extension)
|
||||
except (ImportError, ValueError):
|
||||
sys.stderr.write(f'WARNING: Extension {extension!r} not found. '
|
||||
'Some documentation may not build correctly.\n')
|
||||
else:
|
||||
extensions.append(extension)
|
||||
|
||||
addExtensionIfExists('sphinxcontrib.doxylink')
|
||||
|
||||
templates_path = ['_templates']
|
||||
exclude_patterns = ['Thumbs.db', '.DS_Store', 'RELEASE_NOTES.rst']
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
# html_theme = 'default'
|
||||
html_theme = 'named_data_theme'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
html_theme_path = ['./']
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
html_theme_path = ['.']
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
# html_static_path = ['_static']
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
# directly to the root of the documentation.
|
||||
#html_extra_path = []
|
||||
html_copy_source = False
|
||||
html_show_sourcelink = False
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
html_file_suffix = ".html"
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'ChronoSync-docs'
|
||||
# Disable syntax highlighting of code blocks by default.
|
||||
highlight_language = 'none'
|
||||
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
('index', 'ChronoSync-docs.tex', u'A Synchronization Protocol in NDN',
|
||||
u'Named Data Networking Project', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
]
|
||||
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
man_show_urls = True
|
||||
|
||||
|
||||
# ---- Custom options --------
|
||||
# -- Misc options ------------------------------------------------------------
|
||||
|
||||
doxylink = {
|
||||
'ChronoSync' : ('ChronoSync.tag', 'doxygen/'),
|
||||
'ChronoSync': ('ChronoSync.tag', 'doxygen/'),
|
||||
}
|
||||
|
||||
if os.getenv('GOOGLE_ANALYTICS', None):
|
||||
googleanalytics_id = os.environ['GOOGLE_ANALYTICS']
|
||||
googleanalytics_enabled = True
|
||||
|
||||
exclude_patterns = ['RELEASE_NOTES.rst']
|
||||
extlinks = {
|
||||
'issue': ('https://redmine.named-data.net/issues/%s', 'issue #%s'),
|
||||
}
|
||||
|
||||
+16
-65
@@ -68,7 +68,7 @@ OUTPUT_DIRECTORY = docs/doxygen
|
||||
# performance problems for the file system.
|
||||
# The default value is: NO.
|
||||
|
||||
CREATE_SUBDIRS = YES
|
||||
CREATE_SUBDIRS = NO
|
||||
|
||||
# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
|
||||
# characters to appear in the names of generated files. If set to NO, non-ASCII
|
||||
@@ -140,7 +140,7 @@ INLINE_INHERITED_MEMB = YES
|
||||
# shortest path that makes the file name unique will be used
|
||||
# The default value is: YES.
|
||||
|
||||
FULL_PATH_NAMES = NO
|
||||
FULL_PATH_NAMES = YES
|
||||
|
||||
# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
|
||||
# Stripping is only done if one of the specified strings matches the left-hand
|
||||
@@ -161,7 +161,7 @@ STRIP_FROM_PATH =
|
||||
# specify the list of include paths that are normally passed to the compiler
|
||||
# using the -I flag.
|
||||
|
||||
STRIP_FROM_INC_PATH =
|
||||
STRIP_FROM_INC_PATH = ..
|
||||
|
||||
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
|
||||
# less readable) file names. This can be useful is your file systems doesn't
|
||||
@@ -230,12 +230,6 @@ TAB_SIZE = 4
|
||||
|
||||
ALIASES =
|
||||
|
||||
# This tag can be used to specify a number of word-keyword mappings (TCL only).
|
||||
# A mapping has the form "name=value". For example adding "class=itcl::class"
|
||||
# will allow you to use the command class in the itcl::class meaning.
|
||||
|
||||
TCL_SUBST =
|
||||
|
||||
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
|
||||
# only. Doxygen will then generate output that is more tailored for C. For
|
||||
# instance, some of the names that are used will be different. The list of all
|
||||
@@ -443,7 +437,7 @@ EXTRACT_PACKAGE = NO
|
||||
# included in the documentation.
|
||||
# The default value is: NO.
|
||||
|
||||
EXTRACT_STATIC = YES
|
||||
EXTRACT_STATIC = NO
|
||||
|
||||
# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
|
||||
# locally in source files will be included in the documentation. If set to NO,
|
||||
@@ -451,7 +445,7 @@ EXTRACT_STATIC = YES
|
||||
# for Java sources.
|
||||
# The default value is: YES.
|
||||
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
EXTRACT_LOCAL_CLASSES = NO
|
||||
|
||||
# This flag is only useful for Objective-C code. If set to YES, local methods,
|
||||
# which are defined in the implementation section but not in the interface are
|
||||
@@ -1047,13 +1041,6 @@ VERBATIM_HEADERS = YES
|
||||
|
||||
ALPHABETICAL_INDEX = YES
|
||||
|
||||
# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
|
||||
# which the alphabetical index list will be split.
|
||||
# Minimum value: 1, maximum value: 20, default value: 5.
|
||||
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
|
||||
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
|
||||
# In case all classes in a project start with a common prefix, all classes will
|
||||
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
|
||||
# can be used to specify a prefix (or a list of prefixes) that should be ignored
|
||||
@@ -1191,7 +1178,7 @@ HTML_COLORSTYLE_GAMMA = 91
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_TIMESTAMP = YES
|
||||
HTML_TIMESTAMP = NO
|
||||
|
||||
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
|
||||
# documentation will contain sections that can be hidden and shown after the
|
||||
@@ -1752,16 +1739,6 @@ LATEX_BATCHMODE = NO
|
||||
|
||||
LATEX_HIDE_INDICES = NO
|
||||
|
||||
# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
|
||||
# code with syntax highlighting in the LaTeX output.
|
||||
#
|
||||
# Note that which sources are shown also depends on other settings such as
|
||||
# SOURCE_BROWSER.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
LATEX_SOURCE_CODE = NO
|
||||
|
||||
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
|
||||
# bibliography, e.g. plainnat, or ieeetr. See
|
||||
# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
|
||||
@@ -1834,16 +1811,6 @@ RTF_STYLESHEET_FILE =
|
||||
|
||||
RTF_EXTENSIONS_FILE =
|
||||
|
||||
# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
|
||||
# with syntax highlighting in the RTF output.
|
||||
#
|
||||
# Note that which sources are shown also depends on other settings such as
|
||||
# SOURCE_BROWSER.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_RTF is set to YES.
|
||||
|
||||
RTF_SOURCE_CODE = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -1933,15 +1900,6 @@ GENERATE_DOCBOOK = NO
|
||||
|
||||
DOCBOOK_OUTPUT = docbook
|
||||
|
||||
# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
|
||||
# program listings (including syntax highlighting and cross-referencing
|
||||
# information) to the DOCBOOK output. Note that enabling this will significantly
|
||||
# increase the size of the DOCBOOK output.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
|
||||
|
||||
DOCBOOK_PROGRAMLISTING = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -2050,8 +2008,16 @@ INCLUDE_FILE_PATTERNS =
|
||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||
|
||||
PREDEFINED = DOXYGEN \
|
||||
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(x)= \
|
||||
NDN_LOG_INIT(x)= \
|
||||
NDN_LOG_MEMBER_DECL()= \
|
||||
NDN_LOG_MEMBER_DECL_SPECIALIZED(x)= \
|
||||
NDN_LOG_MEMBER_INIT(x,y)= \
|
||||
NDN_LOG_MEMBER_INIT_SPECIALIZED(x,y)= \
|
||||
CHRONOSYNC_PUBLIC_WITH_TESTS_ELSE_PROTECTED=protected \
|
||||
CHRONOSYNC_PUBLIC_WITH_TESTS_ELSE_PRIVATE=private \
|
||||
NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(x)=
|
||||
CHRONOSYNC_PROTECTED_WITH_TESTS_ELSE_PRIVATE=private \
|
||||
CHRONOSYNC_VIRTUAL_WITH_TESTS=
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
|
||||
# tag can be used to specify a list of macro names that should be expanded. The
|
||||
@@ -2118,12 +2084,6 @@ EXTERNAL_GROUPS = YES
|
||||
|
||||
EXTERNAL_PAGES = YES
|
||||
|
||||
# The PERL_PATH should be the absolute path and name of the perl script
|
||||
# interpreter (i.e. the result of 'which perl').
|
||||
# The default file (with absolute path) is: /usr/bin/perl.
|
||||
|
||||
PERL_PATH = /usr/bin/perl
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -2137,15 +2097,6 @@ PERL_PATH = /usr/bin/perl
|
||||
|
||||
CLASS_DIAGRAMS = YES
|
||||
|
||||
# You can define message sequence charts within doxygen comments using the \msc
|
||||
# command. Doxygen will then run the mscgen tool (see:
|
||||
# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
|
||||
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
|
||||
# the mscgen tool resides. If left empty the tool is assumed to be found in the
|
||||
# default search path.
|
||||
|
||||
MSCGEN_PATH =
|
||||
|
||||
# You can include diagrams made with dia in doxygen documentation. Doxygen will
|
||||
# then run dia to produce the diagram and insert it in the documentation. The
|
||||
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
|
||||
@@ -2166,7 +2117,7 @@ HIDE_UNDOC_RELATIONS = YES
|
||||
# set to NO
|
||||
# The default value is: YES.
|
||||
|
||||
HAVE_DOT = YES
|
||||
HAVE_DOT = @HAVE_DOT@
|
||||
|
||||
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
|
||||
# to run in parallel. When set to 0 doxygen will base this on the number of
|
||||
|
||||
+9
-8
@@ -1,26 +1,27 @@
|
||||
ChronoSync - A synchronization Protocol in NDN
|
||||
ChronoSync: A Synchronization Protocol for NDN
|
||||
==============================================
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:maxdepth: 3
|
||||
|
||||
DesignDoc
|
||||
design
|
||||
|
||||
* :doc:`DesignDoc`
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
**Additional documentation**
|
||||
|
||||
* `API documentation (doxygen) <doxygen/annotated.html>`_
|
||||
* :doc:`design`
|
||||
* `API documentation (doxygen) <doxygen/annotated.html>`__
|
||||
|
||||
Downloading
|
||||
-----------
|
||||
|
||||
* `Source code GitHub git repository <https://github.com/named-data/ChronoSync>`_.
|
||||
* `Source code git repository <https://github.com/named-data/ChronoSync>`__
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
ChronoSync is free software: you can redistribute it and/or modify it under the terms
|
||||
of the GNU General Public License as published by the Free Software Foundation, either
|
||||
version 3 of the License, or (at your option) any later version.
|
||||
version 3 of the License, or (at your option) any later version. See `COPYING.md
|
||||
<https://github.com/named-data/ChronoSync/blob/master/COPYING.md>`__ for details.
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<div class="row">
|
||||
<div class="three columns">
|
||||
<div id="logo">
|
||||
<a href="http://named-data.net" title="A Future Internet Architecture"><img src="http://named-data.net/wp-content/uploads/cropped-20130722_Logo2.png" alt="" /></a>
|
||||
<a href="https://named-data.net" title="A Future Internet Architecture"><img src="https://named-data.net/wp-content/uploads/cropped-20130722_Logo2.png" alt="" /></a>
|
||||
</div><!--logo end-->
|
||||
</div>
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
<h3>{{ _('Developer documentation') }}</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="doxygen/annotated.html">API documentation (doxygen)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="code-style.html">ndn-cxx Code Style and Coding Guidelines</a></li>
|
||||
</ul>
|
||||
{%- endblock %}
|
||||
|
||||
@@ -75,7 +74,7 @@
|
||||
<div class="row">
|
||||
<div class="twelve columns">
|
||||
|
||||
<div id="copyright">This research is partially supported by NSF (Award <a href="http://www.nsf.gov/awardsearch/showAward?AWD_ID=1040868" target="_blank>">CNS-1040868</a>)<br/><br/><a rel="license" href="http://creativecommons.org/licenses/by/3.0/deed.en_US" target="_blank">Creative Commons Attribution 3.0 Unported License</a> except where noted.</div>
|
||||
<div id="copyright">This research is partially supported by NSF (Award <a href="https://www.nsf.gov/awardsearch/showAward?AWD_ID=1040868" target="_blank>">CNS-1040868</a>)<br/><br/><a rel="license" href="https://creativecommons.org/licenses/by/3.0/deed.en_US" target="_blank">Creative Commons Attribution 3.0 Unported License</a> except where noted.</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -26,7 +26,7 @@ $mathjax
|
||||
<div class="row">
|
||||
<div class="three columns">
|
||||
<div id="logo">
|
||||
<a href="http://named-data.net" title="A Future Internet Architecture"><img src="http://named-data.net/wp-content/uploads/cropped-20130722_Logo2.png" alt="" /></a>
|
||||
<a href="https://named-data.net" title="A Future Internet Architecture"><img src="https://named-data.net/wp-content/uploads/cropped-20130722_Logo2.png" alt="" /></a>
|
||||
</div><!--logo end-->
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2018 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2022 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -19,15 +19,15 @@
|
||||
|
||||
#include "bzip2-helper.hpp"
|
||||
|
||||
#include <boost/iostreams/filtering_stream.hpp>
|
||||
#include <boost/iostreams/detail/iostream.hpp>
|
||||
#include <boost/iostreams/filter/bzip2.hpp>
|
||||
#include <boost/iostreams/copy.hpp>
|
||||
#include <boost/iostreams/device/array.hpp>
|
||||
#include <boost/iostreams/filtering_stream.hpp>
|
||||
#include <boost/iostreams/filter/bzip2.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
|
||||
#include <ndn-cxx/encoding/buffer-stream.hpp>
|
||||
|
||||
namespace chronosync {
|
||||
namespace bzip2 {
|
||||
namespace chronosync::bzip2 {
|
||||
|
||||
namespace bio = boost::iostreams;
|
||||
|
||||
@@ -38,7 +38,7 @@ compress(const char* buffer, size_t bufferSize)
|
||||
bio::filtering_stream<bio::output> out;
|
||||
out.push(bio::bzip2_compressor());
|
||||
out.push(os);
|
||||
bio::stream<bio::array_source> in(reinterpret_cast<const char*>(buffer), bufferSize);
|
||||
bio::stream<bio::array_source> in(buffer, bufferSize);
|
||||
bio::copy(in, out);
|
||||
return os.buf();
|
||||
}
|
||||
@@ -50,10 +50,9 @@ decompress(const char* buffer, size_t bufferSize)
|
||||
bio::filtering_stream<bio::output> out;
|
||||
out.push(bio::bzip2_decompressor());
|
||||
out.push(os);
|
||||
bio::stream<bio::array_source> in(reinterpret_cast<const char*>(buffer), bufferSize);
|
||||
bio::stream<bio::array_source> in(buffer, bufferSize);
|
||||
bio::copy(in, out);
|
||||
return os.buf();
|
||||
}
|
||||
|
||||
} // namespace bzip2
|
||||
} // namespace chronosync
|
||||
} // namespace chronosync::bzip2
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2018 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2022 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -17,13 +17,12 @@
|
||||
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CHRONOSYNC_BZIP2_HELPER_HPP
|
||||
#define CHRONOSYNC_BZIP2_HELPER_HPP
|
||||
#ifndef CHRONOSYNC_DETAIL_BZIP2_HELPER_HPP
|
||||
#define CHRONOSYNC_DETAIL_BZIP2_HELPER_HPP
|
||||
|
||||
#include <ndn-cxx/encoding/buffer.hpp>
|
||||
|
||||
namespace chronosync {
|
||||
namespace bzip2 {
|
||||
namespace chronosync::bzip2 {
|
||||
|
||||
/**
|
||||
* @brief Compress @p buffer of size @p bufferSize with bzip2
|
||||
@@ -37,7 +36,6 @@ compress(const char* buffer, size_t bufferSize);
|
||||
std::shared_ptr<ndn::Buffer>
|
||||
decompress(const char* buffer, size_t bufferSize);
|
||||
|
||||
} // namespace bzip2
|
||||
} // namespace chronosync
|
||||
} // namespace chronosync::bzip2
|
||||
|
||||
#endif // CHRONOSYNC_BZIP2_HELPER_HPP
|
||||
#endif // CHRONOSYNC_DETAIL_BZIP2_HELPER_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2018 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2022 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -20,12 +20,12 @@
|
||||
* @author Yingdi Yu <yingdi@cs.ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef CHRONOSYNC_COMMON_HPP
|
||||
#define CHRONOSYNC_COMMON_HPP
|
||||
#ifndef CHRONOSYNC_DETAIL_COMMON_HPP
|
||||
#define CHRONOSYNC_DETAIL_COMMON_HPP
|
||||
|
||||
#include "config.hpp"
|
||||
|
||||
#ifdef CHRONOSYNC_HAVE_TESTS
|
||||
#ifdef CHRONOSYNC_WITH_TESTS
|
||||
#define CHRONOSYNC_VIRTUAL_WITH_TESTS virtual
|
||||
#define CHRONOSYNC_PUBLIC_WITH_TESTS_ELSE_PROTECTED public
|
||||
#define CHRONOSYNC_PUBLIC_WITH_TESTS_ELSE_PRIVATE public
|
||||
@@ -38,41 +38,34 @@
|
||||
#endif
|
||||
|
||||
#include <cstddef>
|
||||
#include <list>
|
||||
#include <queue>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
|
||||
#include <ndn-cxx/data.hpp>
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/interest.hpp>
|
||||
#include <ndn-cxx/security/key-chain.hpp>
|
||||
#include <ndn-cxx/security/signing-helpers.hpp>
|
||||
#include <ndn-cxx/security/v2/validator.hpp>
|
||||
#include <ndn-cxx/security/validator.hpp>
|
||||
#include <ndn-cxx/security/validator-config.hpp>
|
||||
#include <ndn-cxx/util/scheduler.hpp>
|
||||
#include <ndn-cxx/util/time.hpp>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
namespace chronosync {
|
||||
|
||||
using std::size_t;
|
||||
|
||||
using boost::noncopyable;
|
||||
|
||||
using std::size_t;
|
||||
|
||||
using std::bind;
|
||||
using std::cref;
|
||||
using std::function;
|
||||
using std::make_shared;
|
||||
using std::make_tuple;
|
||||
using std::ref;
|
||||
using std::shared_ptr;
|
||||
|
||||
using ndn::Block;
|
||||
@@ -80,18 +73,14 @@ using ndn::ConstBufferPtr;
|
||||
using ndn::Data;
|
||||
using ndn::Interest;
|
||||
using ndn::Name;
|
||||
using ndn::security::v2::ValidationError;
|
||||
using ndn::security::v2::Validator;
|
||||
|
||||
namespace tlv {
|
||||
using namespace ndn::tlv;
|
||||
} // namespace tlv
|
||||
using ndn::security::Validator;
|
||||
using ndn::security::ValidationError;
|
||||
|
||||
namespace name = ndn::name;
|
||||
namespace time = ndn::time;
|
||||
namespace security = ndn::security;
|
||||
namespace encoding = ndn::encoding;
|
||||
namespace time = ndn::time;
|
||||
using namespace ndn::time_literals;
|
||||
|
||||
} // namespace chronosync
|
||||
|
||||
#endif // CHRONOSYNC_COMMON_HPP
|
||||
#endif // CHRONOSYNC_DETAIL_COMMON_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2014 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2021 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -22,8 +22,8 @@
|
||||
* @author Yingdi Yu <yingdi@cs.ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef CHRONOSYNC_MI_TAG_HPP
|
||||
#define CHRONOSYNC_MI_TAG_HPP
|
||||
#ifndef CHRONOSYNC_DETAIL_MI_TAG_HPP
|
||||
#define CHRONOSYNC_DETAIL_MI_TAG_HPP
|
||||
|
||||
namespace chronosync {
|
||||
|
||||
@@ -40,11 +40,6 @@ struct sequenced
|
||||
{
|
||||
};
|
||||
|
||||
struct timed
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
} // namespace chronosync
|
||||
|
||||
#endif // CHRONOSYNC_MI_TAG_HPP
|
||||
#endif // CHRONOSYNC_DETAIL_MI_TAG_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2014 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2022 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -19,11 +19,10 @@
|
||||
* @author Yingdi Yu <yingdi@cs.ucla.edu>
|
||||
*/
|
||||
|
||||
#ifndef CHRONOSYNC_TLV_HPP
|
||||
#define CHRONOSYNC_TLV_HPP
|
||||
#ifndef CHRONOSYNC_DETAIL_TLV_HPP
|
||||
#define CHRONOSYNC_DETAIL_TLV_HPP
|
||||
|
||||
namespace chronosync {
|
||||
namespace tlv {
|
||||
namespace chronosync::tlv {
|
||||
|
||||
/**
|
||||
* @brief Type value of sync reply related TLVs
|
||||
@@ -32,10 +31,9 @@ namespace tlv {
|
||||
enum {
|
||||
SyncReply = 128, // 0x80
|
||||
StateLeaf = 129, // 0x81
|
||||
SeqNo = 130 // 0x82
|
||||
SeqNo = 130, // 0x82
|
||||
};
|
||||
|
||||
} // namespace tlv
|
||||
} // namespace chronosync
|
||||
} // namespace chronosync::tlv
|
||||
|
||||
#endif // CHRONOSYNC_TLV_HPP
|
||||
#endif // CHRONOSYNC_DETAIL_TLV_HPP
|
||||
@@ -1,25 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2014 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
*
|
||||
* ChronoSync is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation, either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* ChronoSync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
|
||||
* @author Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
|
||||
* @author Yingdi Yu <yingdi@cs.ucla.edu>
|
||||
*/
|
||||
|
||||
#include "diff-state-container.hpp"
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2017 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2021 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -25,15 +25,14 @@
|
||||
#ifndef CHRONOSYNC_DIFF_STATE_CONTAINER_HPP
|
||||
#define CHRONOSYNC_DIFF_STATE_CONTAINER_HPP
|
||||
|
||||
#include "mi-tag.hpp"
|
||||
#include "detail/mi-tag.hpp"
|
||||
#include "diff-state.hpp"
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/tag.hpp>
|
||||
#include <boost/multi_index/hashed_index.hpp>
|
||||
#include <boost/multi_index/sequenced_index.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/mem_fun.hpp>
|
||||
#include <boost/multi_index/tag.hpp>
|
||||
|
||||
namespace chronosync {
|
||||
|
||||
@@ -72,9 +71,8 @@ struct DiffStateContainer : public mi::multi_index_container<
|
||||
DigestPtrHash,
|
||||
DigestPtrEqual
|
||||
>,
|
||||
|
||||
// sequenced index to access older/newer element (like in list)
|
||||
mi::sequenced<mi::tag<sequenced> >
|
||||
mi::sequenced<mi::tag<sequenced>>
|
||||
>
|
||||
>
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2019 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2021 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -25,15 +25,12 @@
|
||||
#ifndef CHRONOSYNC_INTEREST_CONTAINER_HPP
|
||||
#define CHRONOSYNC_INTEREST_CONTAINER_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
#include "mi-tag.hpp"
|
||||
#include "diff-state-container.hpp"
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/tag.hpp>
|
||||
#include <boost/multi_index/hashed_index.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/tag.hpp>
|
||||
|
||||
namespace chronosync {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2019 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2023 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
namespace chronosync {
|
||||
|
||||
InterestTable::InterestTable(boost::asio::io_service& io)
|
||||
InterestTable::InterestTable(boost::asio::io_context& io)
|
||||
: m_scheduler(io)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2017 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2023 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -27,10 +27,12 @@
|
||||
|
||||
#include "interest-container.hpp"
|
||||
|
||||
#include <boost/asio/io_context.hpp>
|
||||
|
||||
namespace chronosync {
|
||||
|
||||
/**
|
||||
* @brief A table to keep unsatisfied Sync Interest
|
||||
* @brief A table to keep unsatisfied Sync Interests.
|
||||
*/
|
||||
class InterestTable : noncopyable
|
||||
{
|
||||
@@ -38,18 +40,14 @@ public:
|
||||
class Error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
Error(const std::string& what)
|
||||
: std::runtime_error(what)
|
||||
{
|
||||
}
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
using iterator = InterestContainer::iterator;
|
||||
using const_iterator = InterestContainer::const_iterator;
|
||||
|
||||
explicit
|
||||
InterestTable(boost::asio::io_service& io);
|
||||
InterestTable(boost::asio::io_context& io);
|
||||
|
||||
~InterestTable();
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2014 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
*
|
||||
* ChronoSync is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation, either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* ChronoSync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
|
||||
* @author Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
|
||||
* @author Yingdi Yu <yingdi@cs.ucla.edu>
|
||||
*/
|
||||
|
||||
#include "leaf-container.hpp"
|
||||
// Simply check whether LeafContainer can compile
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2017 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2022 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -25,13 +25,14 @@
|
||||
#ifndef CHRONOSYNC_LEAF_CONTAINER_HPP
|
||||
#define CHRONOSYNC_LEAF_CONTAINER_HPP
|
||||
|
||||
#include "mi-tag.hpp"
|
||||
#include "detail/mi-tag.hpp"
|
||||
#include "leaf.hpp"
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/hashed_index.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/mem_fun.hpp>
|
||||
#include <boost/multi_index/tag.hpp>
|
||||
|
||||
#include <ndn-cxx/util/sha256.hpp>
|
||||
|
||||
@@ -41,14 +42,12 @@ namespace mi = boost::multi_index;
|
||||
|
||||
struct SessionNameHash
|
||||
{
|
||||
static_assert(ndn::util::Sha256::DIGEST_SIZE >= sizeof(std::size_t), "");
|
||||
|
||||
std::size_t
|
||||
operator()(const Name& prefix) const
|
||||
{
|
||||
ConstBufferPtr buffer =
|
||||
ndn::util::Sha256::computeDigest(prefix.wireEncode().wire(), prefix.wireEncode().size());
|
||||
|
||||
BOOST_ASSERT(buffer->size() > sizeof(std::size_t));
|
||||
|
||||
auto buffer = ndn::util::Sha256::computeDigest(prefix.wireEncode());
|
||||
return *reinterpret_cast<const std::size_t*>(buffer->data());
|
||||
}
|
||||
};
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2017 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2021 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -25,7 +25,7 @@
|
||||
#ifndef CHRONOSYNC_LEAF_HPP
|
||||
#define CHRONOSYNC_LEAF_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
#include "detail/common.hpp"
|
||||
|
||||
#include <ndn-cxx/util/sha256.hpp>
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2017 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
*
|
||||
* ChronoSync is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation, either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* ChronoSync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Zhenkai Zhu <http://irl.cs.ucla.edu/~zhenkai/>
|
||||
* @author Chaoyi Bian <bcy@pku.edu.cn>
|
||||
* @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
|
||||
*/
|
||||
|
||||
#ifndef CHRONOSYNC_LOGGER_HPP
|
||||
#define CHRONOSYNC_LOGGER_HPP
|
||||
|
||||
#include <ndn-cxx/util/logger.hpp>
|
||||
|
||||
#define INIT_LOGGER(name) NDN_LOG_INIT(sync.name)
|
||||
|
||||
#define _LOG_ERROR(x) NDN_LOG_ERROR(x)
|
||||
#define _LOG_WARN(x) NDN_LOG_WARN(x)
|
||||
#define _LOG_INFO(x) NDN_LOG_INFO(x)
|
||||
#define _LOG_DEBUG(x) NDN_LOG_DEBUG(x)
|
||||
#define _LOG_TRACE(x) NDN_LOG_TRACE(x)
|
||||
|
||||
#define _LOG_FUNCTION(x) NDN_LOG_TRACE(__FUNCTION__ << "(" << x << ")")
|
||||
#define _LOG_FUNCTION_NOARGS NDN_LOG_TRACE(__FUNCTION__ << "()")
|
||||
|
||||
#endif // CHRONOSYNC_LOGGER_HPP
|
||||
+125
-156
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2019 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2023 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -24,41 +24,28 @@
|
||||
*/
|
||||
|
||||
#include "logic.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "bzip2-helper.hpp"
|
||||
#include "detail/bzip2-helper.hpp"
|
||||
|
||||
#include <ndn-cxx/util/backports.hpp>
|
||||
#include <ndn-cxx/util/exception.hpp>
|
||||
#include <ndn-cxx/util/logger.hpp>
|
||||
#include <ndn-cxx/util/string-helper.hpp>
|
||||
|
||||
INIT_LOGGER(Logic);
|
||||
NDN_LOG_INIT(sync.Logic);
|
||||
|
||||
#define _LOG_DEBUG_ID(v) _LOG_DEBUG("Instance" << m_instanceId << ": " << v)
|
||||
#define CHRONO_LOG_DBG(v) NDN_LOG_DEBUG("Instance" << m_instanceId << ": " << v)
|
||||
|
||||
namespace chronosync {
|
||||
|
||||
const uint8_t EMPTY_DIGEST_VALUE[] = {
|
||||
const std::vector<uint8_t> EMPTY_DIGEST{
|
||||
0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
|
||||
0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
|
||||
0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
|
||||
0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55
|
||||
};
|
||||
|
||||
int Logic::s_instanceCounter = 0;
|
||||
|
||||
const ndn::Name Logic::DEFAULT_NAME;
|
||||
const ndn::Name Logic::EMPTY_NAME;
|
||||
const std::shared_ptr<Validator> Logic::DEFAULT_VALIDATOR;
|
||||
const time::steady_clock::Duration Logic::DEFAULT_RESET_TIMER = time::seconds(0);
|
||||
const time::steady_clock::Duration Logic::DEFAULT_CANCEL_RESET_TIMER = time::milliseconds(500);
|
||||
const time::milliseconds Logic::DEFAULT_RESET_INTEREST_LIFETIME(1000);
|
||||
const time::milliseconds Logic::DEFAULT_SYNC_INTEREST_LIFETIME(1000);
|
||||
const time::milliseconds Logic::DEFAULT_SYNC_REPLY_FRESHNESS(1000);
|
||||
const time::milliseconds Logic::DEFAULT_RECOVERY_INTEREST_LIFETIME(1000);
|
||||
|
||||
const ConstBufferPtr Logic::EMPTY_DIGEST(new ndn::Buffer(EMPTY_DIGEST_VALUE, 32));
|
||||
const ndn::name::Component Logic::RESET_COMPONENT("reset");
|
||||
const ndn::name::Component Logic::RECOVERY_COMPONENT("recovery");
|
||||
|
||||
const name::Component RESET_COMPONENT{"reset"};
|
||||
const name::Component RECOVERY_COMPONENT{"recovery"};
|
||||
const size_t NDNLP_EXPECTED_OVERHEAD = 20;
|
||||
|
||||
/**
|
||||
@@ -68,22 +55,22 @@ const size_t NDNLP_EXPECTED_OVERHEAD = 20;
|
||||
* The returned value can be customized using the environment variable `CHRONOSYNC_MAX_PACKET_SIZE`,
|
||||
* but the returned value will be at least 500 and no more than `ndn::MAX_NDN_PACKET_SIZE`.
|
||||
*/
|
||||
#ifndef CHRONOSYNC_HAVE_TESTS
|
||||
#ifndef CHRONOSYNC_WITH_TESTS
|
||||
static
|
||||
#endif // CHRONOSYNC_HAVE_TESTS
|
||||
#endif // CHRONOSYNC_WITH_TESTS
|
||||
size_t
|
||||
getMaxPacketLimit()
|
||||
{
|
||||
static size_t limit = 0;
|
||||
#ifndef CHRONOSYNC_HAVE_TESTS
|
||||
#ifndef CHRONOSYNC_WITH_TESTS
|
||||
if (limit != 0) {
|
||||
return limit;
|
||||
}
|
||||
#endif // CHRONOSYNC_HAVE_TESTS
|
||||
#endif // CHRONOSYNC_WITH_TESTS
|
||||
|
||||
if (getenv("CHRONOSYNC_MAX_PACKET_SIZE") != nullptr) {
|
||||
try {
|
||||
limit = ndn::clamp<size_t>(boost::lexical_cast<size_t>(getenv("CHRONOSYNC_MAX_PACKET_SIZE")),
|
||||
limit = std::clamp<size_t>(boost::lexical_cast<size_t>(getenv("CHRONOSYNC_MAX_PACKET_SIZE")),
|
||||
500, ndn::MAX_NDN_PACKET_SIZE);
|
||||
}
|
||||
catch (const boost::bad_lexical_cast&) {
|
||||
@@ -103,8 +90,8 @@ Logic::Logic(ndn::Face& face,
|
||||
const UpdateCallback& onUpdate,
|
||||
const Name& defaultSigningId,
|
||||
std::shared_ptr<Validator> validator,
|
||||
const time::steady_clock::Duration& resetTimer,
|
||||
const time::steady_clock::Duration& cancelResetTimer,
|
||||
const time::steady_clock::duration& resetTimer,
|
||||
const time::steady_clock::duration& cancelResetTimer,
|
||||
const time::milliseconds& resetInterestLifetime,
|
||||
const time::milliseconds& syncInterestLifetime,
|
||||
const time::milliseconds& syncReplyFreshness,
|
||||
@@ -114,11 +101,11 @@ Logic::Logic(ndn::Face& face,
|
||||
, m_syncPrefix(syncPrefix)
|
||||
, m_syncReset(Name(syncPrefix).append("reset"))
|
||||
, m_defaultUserPrefix(defaultUserPrefix)
|
||||
, m_interestTable(m_face.getIoService())
|
||||
, m_interestTable(m_face.getIoContext())
|
||||
, m_isInReset(false)
|
||||
, m_needPeriodReset(resetTimer > time::nanoseconds::zero())
|
||||
, m_onUpdate(onUpdate)
|
||||
, m_scheduler(m_face.getIoService())
|
||||
, m_scheduler(m_face.getIoContext())
|
||||
, m_rng(ndn::random::getRandomNumberEngine())
|
||||
, m_rangeUniformRandom(100, 500)
|
||||
, m_reexpressionJitter(100, 500)
|
||||
@@ -128,28 +115,28 @@ Logic::Logic(ndn::Face& face,
|
||||
, m_syncInterestLifetime(syncInterestLifetime)
|
||||
, m_syncReplyFreshness(syncReplyFreshness)
|
||||
, m_recoveryInterestLifetime(recoveryInterestLifetime)
|
||||
, m_validator(validator)
|
||||
, m_validator(std::move(validator))
|
||||
, m_instanceId(s_instanceCounter++)
|
||||
{
|
||||
_LOG_DEBUG_ID(">> Logic::Logic");
|
||||
CHRONO_LOG_DBG(">> Logic::Logic");
|
||||
addUserNode(m_defaultUserPrefix, defaultSigningId, session, false);
|
||||
|
||||
_LOG_DEBUG_ID("Listen to: " << m_syncPrefix);
|
||||
CHRONO_LOG_DBG("Listen to: " << m_syncPrefix);
|
||||
m_syncRegisteredPrefix = m_face.setInterestFilter(
|
||||
ndn::InterestFilter(m_syncPrefix).allowLoopback(false),
|
||||
bind(&Logic::onSyncInterest, this, _1, _2),
|
||||
bind(&Logic::onSyncRegisterFailed, this, _1, _2));
|
||||
|
||||
sendSyncInterest();
|
||||
_LOG_DEBUG_ID("<< Logic::Logic");
|
||||
CHRONO_LOG_DBG("<< Logic::Logic");
|
||||
}
|
||||
|
||||
Logic::~Logic()
|
||||
{
|
||||
_LOG_DEBUG_ID(">> Logic::~Logic");
|
||||
CHRONO_LOG_DBG(">> Logic::~Logic");
|
||||
m_interestTable.clear();
|
||||
m_scheduler.cancelAllEvents();
|
||||
_LOG_DEBUG_ID("<< Logic::~Logic");
|
||||
CHRONO_LOG_DBG("<< Logic::~Logic");
|
||||
}
|
||||
|
||||
void
|
||||
@@ -225,11 +212,12 @@ Logic::getSessionName(Name prefix)
|
||||
{
|
||||
if (prefix == EMPTY_NAME)
|
||||
prefix = m_defaultUserPrefix;
|
||||
|
||||
auto node = m_nodeList.find(prefix);
|
||||
if (node != m_nodeList.end())
|
||||
return node->second.sessionName;
|
||||
else
|
||||
BOOST_THROW_EXCEPTION(Error("Refer to non-existent node:" + prefix.toUri()));
|
||||
|
||||
NDN_THROW(Error("Nonexistent node: " + prefix.toUri()));
|
||||
}
|
||||
|
||||
const SeqNo&
|
||||
@@ -237,12 +225,12 @@ Logic::getSeqNo(Name prefix)
|
||||
{
|
||||
if (prefix == EMPTY_NAME)
|
||||
prefix = m_defaultUserPrefix;
|
||||
|
||||
auto node = m_nodeList.find(prefix);
|
||||
if (node != m_nodeList.end())
|
||||
return node->second.seqNo;
|
||||
else
|
||||
BOOST_THROW_EXCEPTION(Logic::Error("Refer to non-existent node:" + prefix.toUri()));
|
||||
|
||||
NDN_THROW(Error("Nonexistent node: " + prefix.toUri()));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -260,37 +248,30 @@ Logic::updateSeqNo(const SeqNo& seqNo, const Name& updatePrefix)
|
||||
auto it = m_nodeList.find(prefix);
|
||||
if (it != m_nodeList.end()) {
|
||||
NodeInfo& node = it->second;
|
||||
_LOG_DEBUG_ID(">> Logic::updateSeqNo");
|
||||
_LOG_DEBUG_ID("seqNo: " << seqNo << " m_seqNo: " << node.seqNo);
|
||||
CHRONO_LOG_DBG(">> Logic::updateSeqNo");
|
||||
CHRONO_LOG_DBG("seqNo: " << seqNo << " m_seqNo: " << node.seqNo);
|
||||
if (seqNo < node.seqNo || seqNo == 0)
|
||||
return;
|
||||
|
||||
node.seqNo = seqNo;
|
||||
_LOG_DEBUG_ID("updateSeqNo: m_seqNo " << node.seqNo);
|
||||
CHRONO_LOG_DBG("updateSeqNo: m_seqNo " << node.seqNo);
|
||||
|
||||
if (!m_isInReset) {
|
||||
_LOG_DEBUG_ID("updateSeqNo: not in Reset ");
|
||||
CHRONO_LOG_DBG("updateSeqNo: not in Reset");
|
||||
ConstBufferPtr previousRoot = m_state.getRootDigest();
|
||||
{
|
||||
std::string hash = ndn::toHex(previousRoot->data(), previousRoot->size(), false);
|
||||
_LOG_DEBUG_ID("Hash: " << hash);
|
||||
}
|
||||
printDigest(previousRoot);
|
||||
|
||||
bool isInserted = false;
|
||||
bool isUpdated = false;
|
||||
SeqNo oldSeq;
|
||||
std::tie(isInserted, isUpdated, oldSeq) = m_state.update(node.sessionName, node.seqNo);
|
||||
auto [isInserted, isUpdated, oldSeq] = m_state.update(node.sessionName, node.seqNo);
|
||||
CHRONO_LOG_DBG("Insert: " << std::boolalpha << isInserted);
|
||||
CHRONO_LOG_DBG("Updated: " << std::boolalpha << isUpdated);
|
||||
(void)oldSeq; // silence "unused variable" warning with gcc 7
|
||||
|
||||
_LOG_DEBUG_ID("Insert: " << std::boolalpha << isInserted);
|
||||
_LOG_DEBUG_ID("Updated: " << std::boolalpha << isUpdated);
|
||||
if (isInserted || isUpdated) {
|
||||
DiffStatePtr commit = make_shared<DiffState>();
|
||||
commit->update(node.sessionName, node.seqNo);
|
||||
commit->setRootDigest(m_state.getRootDigest());
|
||||
insertToDiffLog(commit, previousRoot);
|
||||
|
||||
satisfyPendingSyncInterests(prefix, commit);
|
||||
// formAndSendExcludeInterest(prefix, *commit, previousRoot);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -321,12 +302,12 @@ Logic::getSessionNames() const
|
||||
}
|
||||
|
||||
void
|
||||
Logic::onSyncInterest(const Name& prefix, const Interest& interest)
|
||||
Logic::onSyncInterest(const Name&, const Interest& interest)
|
||||
{
|
||||
_LOG_DEBUG_ID(">> Logic::onSyncInterest");
|
||||
CHRONO_LOG_DBG(">> Logic::onSyncInterest");
|
||||
Name name = interest.getName();
|
||||
|
||||
_LOG_DEBUG_ID("InterestName: " << name);
|
||||
CHRONO_LOG_DBG("InterestName: " << name);
|
||||
|
||||
if (name.size() >= 1 && RESET_COMPONENT == name.get(-1)) {
|
||||
processResetInterest(interest);
|
||||
@@ -338,20 +319,19 @@ Logic::onSyncInterest(const Name& prefix, const Interest& interest)
|
||||
processSyncInterest(interest);
|
||||
}
|
||||
|
||||
_LOG_DEBUG_ID("<< Logic::onSyncInterest");
|
||||
CHRONO_LOG_DBG("<< Logic::onSyncInterest");
|
||||
}
|
||||
|
||||
void
|
||||
Logic::onSyncRegisterFailed(const Name& prefix, const std::string& msg)
|
||||
{
|
||||
//Sync prefix registration failed
|
||||
_LOG_DEBUG_ID(">> Logic::onSyncRegisterFailed");
|
||||
CHRONO_LOG_DBG(">> Logic::onSyncRegisterFailed");
|
||||
}
|
||||
|
||||
void
|
||||
Logic::onSyncData(const Interest& interest, const Data& data)
|
||||
Logic::onSyncData(const Interest&, const Data& data)
|
||||
{
|
||||
_LOG_DEBUG_ID(">> Logic::onSyncData");
|
||||
CHRONO_LOG_DBG(">> Logic::onSyncData");
|
||||
if (m_validator != nullptr)
|
||||
m_validator->validate(data,
|
||||
bind(&Logic::onSyncDataValidated, this, _1),
|
||||
@@ -359,38 +339,38 @@ Logic::onSyncData(const Interest& interest, const Data& data)
|
||||
else
|
||||
onSyncDataValidated(data);
|
||||
|
||||
_LOG_DEBUG_ID("<< Logic::onSyncData");
|
||||
CHRONO_LOG_DBG("<< Logic::onSyncData");
|
||||
}
|
||||
|
||||
void
|
||||
Logic::onResetData(const Interest& interest, const Data& data)
|
||||
Logic::onResetData(const Interest&, const Data&)
|
||||
{
|
||||
// This should not happened, drop the received data.
|
||||
}
|
||||
|
||||
void
|
||||
Logic::onSyncNack(const Interest& interest, const ndn::lp::Nack& nack)
|
||||
Logic::onSyncNack(const Interest&, const ndn::lp::Nack& nack)
|
||||
{
|
||||
_LOG_DEBUG_ID(">> Logic::onSyncNack");
|
||||
CHRONO_LOG_DBG(">> Logic::onSyncNack");
|
||||
if (nack.getReason() == ndn::lp::NackReason::NO_ROUTE) {
|
||||
auto after = ndn::time::milliseconds(m_reexpressionJitter(m_rng));
|
||||
_LOG_DEBUG_ID("Schedule sync interest after: " << after);
|
||||
CHRONO_LOG_DBG("Schedule sync interest after: " << after);
|
||||
m_scheduler.schedule(after, [this] { sendSyncInterest(); });
|
||||
}
|
||||
_LOG_DEBUG_ID("<< Logic::onSyncNack");
|
||||
CHRONO_LOG_DBG("<< Logic::onSyncNack");
|
||||
}
|
||||
|
||||
void
|
||||
Logic::onSyncTimeout(const Interest& interest)
|
||||
{
|
||||
// It is OK. Others will handle the time out situation.
|
||||
_LOG_DEBUG_ID(">> Logic::onSyncTimeout");
|
||||
_LOG_DEBUG_ID("Interest: " << interest.getName());
|
||||
_LOG_DEBUG_ID("<< Logic::onSyncTimeout");
|
||||
CHRONO_LOG_DBG(">> Logic::onSyncTimeout");
|
||||
CHRONO_LOG_DBG("Interest: " << interest.getName());
|
||||
CHRONO_LOG_DBG("<< Logic::onSyncTimeout");
|
||||
}
|
||||
|
||||
void
|
||||
Logic::onSyncDataValidationFailed(const Data& data)
|
||||
Logic::onSyncDataValidationFailed(const Data&)
|
||||
{
|
||||
// SyncReply cannot be validated.
|
||||
}
|
||||
@@ -398,7 +378,7 @@ Logic::onSyncDataValidationFailed(const Data& data)
|
||||
void
|
||||
Logic::onSyncDataValidated(const Data& data)
|
||||
{
|
||||
Name name = data.getName();
|
||||
const auto& name = data.getName();
|
||||
ConstBufferPtr digest = make_shared<ndn::Buffer>(name.get(-1).value(), name.get(-1).value_size());
|
||||
|
||||
try {
|
||||
@@ -407,40 +387,39 @@ Logic::onSyncDataValidated(const Data& data)
|
||||
processSyncData(name, digest, Block(std::move(contentBuffer)));
|
||||
}
|
||||
catch (const std::ios_base::failure& error) {
|
||||
_LOG_WARN("Error decompressing content of " << data.getName() << " (" << error.what() << ")");
|
||||
NDN_LOG_WARN("Error decompressing content of " << name << " (" << error.what() << ")");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Logic::processSyncInterest(const Interest& interest, bool isTimedProcessing/*=false*/)
|
||||
{
|
||||
_LOG_DEBUG_ID(">> Logic::processSyncInterest");
|
||||
CHRONO_LOG_DBG(">> Logic::processSyncInterest");
|
||||
|
||||
Name name = interest.getName();
|
||||
const auto& name = interest.getName();
|
||||
ConstBufferPtr digest = make_shared<ndn::Buffer>(name.get(-1).value(), name.get(-1).value_size());
|
||||
|
||||
ConstBufferPtr rootDigest = m_state.getRootDigest();
|
||||
|
||||
// If the digest of the incoming interest is the same as root digest
|
||||
// Put the interest into InterestTable
|
||||
if (*rootDigest == *digest) {
|
||||
_LOG_DEBUG_ID("Oh, we are in the same state");
|
||||
CHRONO_LOG_DBG("Oh, we are in the same state");
|
||||
m_interestTable.insert(interest, digest, false);
|
||||
|
||||
if (!m_isInReset)
|
||||
return;
|
||||
|
||||
if (!isTimedProcessing) {
|
||||
_LOG_DEBUG_ID("Non timed processing in reset");
|
||||
CHRONO_LOG_DBG("Non timed processing in reset");
|
||||
// Still in reset, our own seq has not been put into state yet
|
||||
// Do not hurry, some others may be also resetting and may send their reply
|
||||
time::milliseconds after(m_rangeUniformRandom(m_rng));
|
||||
_LOG_DEBUG_ID("After: " << after);
|
||||
CHRONO_LOG_DBG("After: " << after);
|
||||
m_delayedInterestProcessingId = m_scheduler.schedule(after,
|
||||
[=] { processSyncInterest(interest, true); });
|
||||
}
|
||||
else {
|
||||
_LOG_DEBUG_ID("Timed processing in reset");
|
||||
CHRONO_LOG_DBG("Timed processing in reset");
|
||||
// Now we can get out of reset state by putting our own stuff into m_state.
|
||||
cancelReset();
|
||||
}
|
||||
@@ -449,22 +428,22 @@ Logic::processSyncInterest(const Interest& interest, bool isTimedProcessing/*=fa
|
||||
}
|
||||
|
||||
// If the digest of incoming interest is an "empty" digest
|
||||
if (*digest == *EMPTY_DIGEST) {
|
||||
_LOG_DEBUG_ID("Poor guy, he knows nothing");
|
||||
if (*digest == EMPTY_DIGEST) {
|
||||
CHRONO_LOG_DBG("Poor guy, he knows nothing");
|
||||
sendSyncData(m_defaultUserPrefix, name, m_state);
|
||||
return;
|
||||
}
|
||||
|
||||
DiffStateContainer::iterator stateIter = m_log.find(digest);
|
||||
auto stateIter = m_log.find(digest);
|
||||
// If the digest of incoming interest can be found from the log
|
||||
if (stateIter != m_log.end()) {
|
||||
_LOG_DEBUG_ID("It is ok, you are so close");
|
||||
CHRONO_LOG_DBG("It is ok, you are so close");
|
||||
sendSyncData(m_defaultUserPrefix, name, *(*stateIter)->diff());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isTimedProcessing) {
|
||||
_LOG_DEBUG_ID("Let's wait, just wait for a while");
|
||||
CHRONO_LOG_DBG("Let's wait, just wait for a while");
|
||||
// Do not hurry, some incoming SyncReplies may help us to recognize the digest
|
||||
m_interestTable.insert(interest, digest, true);
|
||||
|
||||
@@ -474,27 +453,25 @@ Logic::processSyncInterest(const Interest& interest, bool isTimedProcessing/*=fa
|
||||
}
|
||||
else {
|
||||
// OK, nobody is helping us, just tell the truth.
|
||||
_LOG_DEBUG_ID("OK, nobody is helping us, let us try to recover");
|
||||
CHRONO_LOG_DBG("OK, nobody is helping us, let us try to recover");
|
||||
m_interestTable.erase(digest);
|
||||
sendRecoveryInterest(digest);
|
||||
}
|
||||
|
||||
_LOG_DEBUG_ID("<< Logic::processSyncInterest");
|
||||
CHRONO_LOG_DBG("<< Logic::processSyncInterest");
|
||||
}
|
||||
|
||||
void
|
||||
Logic::processResetInterest(const Interest& interest)
|
||||
Logic::processResetInterest(const Interest&)
|
||||
{
|
||||
_LOG_DEBUG_ID(">> Logic::processResetInterest");
|
||||
CHRONO_LOG_DBG(">> Logic::processResetInterest");
|
||||
reset(true);
|
||||
}
|
||||
|
||||
void
|
||||
Logic::processSyncData(const Name& name,
|
||||
ConstBufferPtr digest,
|
||||
const Block& syncReplyBlock)
|
||||
Logic::processSyncData(const Name&, ConstBufferPtr digest, const Block& syncReply)
|
||||
{
|
||||
_LOG_DEBUG_ID(">> Logic::processSyncData");
|
||||
CHRONO_LOG_DBG(">> Logic::processSyncData");
|
||||
DiffStatePtr commit = make_shared<DiffState>();
|
||||
ConstBufferPtr previousRoot = m_state.getRootDigest();
|
||||
|
||||
@@ -502,25 +479,20 @@ Logic::processSyncData(const Name& name,
|
||||
m_interestTable.erase(digest); // Remove satisfied interest from PIT
|
||||
|
||||
State reply;
|
||||
reply.wireDecode(syncReplyBlock);
|
||||
reply.wireDecode(syncReply);
|
||||
|
||||
std::vector<MissingDataInfo> v;
|
||||
BOOST_FOREACH(ConstLeafPtr leaf, reply.getLeaves().get<ordered>()) {
|
||||
for (const auto& leaf : reply.getLeaves().get<ordered>()) {
|
||||
BOOST_ASSERT(leaf != nullptr);
|
||||
|
||||
const Name& info = leaf->getSessionName();
|
||||
SeqNo seq = leaf->getSeq();
|
||||
|
||||
bool isInserted = false;
|
||||
bool isUpdated = false;
|
||||
SeqNo oldSeq;
|
||||
std::tie(isInserted, isUpdated, oldSeq) = m_state.update(info, seq);
|
||||
auto [isInserted, isUpdated, oldSeq] = m_state.update(info, seq);
|
||||
if (isInserted || isUpdated) {
|
||||
commit->update(info, seq);
|
||||
|
||||
oldSeq++;
|
||||
MissingDataInfo mdi = {info, oldSeq, seq};
|
||||
v.push_back(mdi);
|
||||
v.push_back({info, oldSeq, seq});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -531,12 +503,11 @@ Logic::processSyncData(const Name& name,
|
||||
insertToDiffLog(commit, previousRoot);
|
||||
}
|
||||
else {
|
||||
_LOG_DEBUG_ID("What? nothing new");
|
||||
CHRONO_LOG_DBG("What? nothing new");
|
||||
}
|
||||
}
|
||||
catch (const State::Error&) {
|
||||
_LOG_DEBUG_ID("Something really fishy happened during state decoding");
|
||||
// Something really fishy happened during state decoding;
|
||||
CHRONO_LOG_DBG("Something really fishy happened during state decoding");
|
||||
commit.reset();
|
||||
return;
|
||||
}
|
||||
@@ -544,7 +515,7 @@ Logic::processSyncData(const Name& name,
|
||||
if (static_cast<bool>(commit) && !commit->getLeaves().empty()) {
|
||||
// state changed and it is safe to express a new interest
|
||||
auto after = time::milliseconds(m_reexpressionJitter(m_rng));
|
||||
_LOG_DEBUG_ID("Reschedule sync interest after: " << after);
|
||||
CHRONO_LOG_DBG("Reschedule sync interest after: " << after);
|
||||
m_reexpressingInterestId = m_scheduler.schedule(after, [this] { sendSyncInterest(); });
|
||||
}
|
||||
}
|
||||
@@ -552,9 +523,9 @@ Logic::processSyncData(const Name& name,
|
||||
void
|
||||
Logic::satisfyPendingSyncInterests(const Name& updatedPrefix, ConstDiffStatePtr commit)
|
||||
{
|
||||
_LOG_DEBUG_ID(">> Logic::satisfyPendingSyncInterests");
|
||||
CHRONO_LOG_DBG(">> Logic::satisfyPendingSyncInterests");
|
||||
try {
|
||||
_LOG_DEBUG_ID("InterestTable size: " << m_interestTable.size());
|
||||
CHRONO_LOG_DBG("InterestTable size: " << m_interestTable.size());
|
||||
auto it = m_interestTable.begin();
|
||||
while (it != m_interestTable.end()) {
|
||||
ConstUnsatisfiedInterestPtr request = *it;
|
||||
@@ -569,13 +540,13 @@ Logic::satisfyPendingSyncInterests(const Name& updatedPrefix, ConstDiffStatePtr
|
||||
catch (const InterestTable::Error&) {
|
||||
// ok. not really an error
|
||||
}
|
||||
_LOG_DEBUG_ID("<< Logic::satisfyPendingSyncInterests");
|
||||
CHRONO_LOG_DBG("<< Logic::satisfyPendingSyncInterests");
|
||||
}
|
||||
|
||||
void
|
||||
Logic::insertToDiffLog(DiffStatePtr commit, ConstBufferPtr previousRoot)
|
||||
{
|
||||
_LOG_DEBUG_ID(">> Logic::insertToDiffLog");
|
||||
CHRONO_LOG_DBG(">> Logic::insertToDiffLog");
|
||||
// Connect to the history
|
||||
if (!m_log.empty())
|
||||
(*m_log.find(previousRoot))->setNext(commit);
|
||||
@@ -583,17 +554,17 @@ Logic::insertToDiffLog(DiffStatePtr commit, ConstBufferPtr previousRoot)
|
||||
// Insert the commit
|
||||
m_log.erase(commit->getRootDigest());
|
||||
m_log.insert(commit);
|
||||
_LOG_DEBUG_ID("<< Logic::insertToDiffLog");
|
||||
CHRONO_LOG_DBG("<< Logic::insertToDiffLog");
|
||||
}
|
||||
|
||||
void
|
||||
Logic::sendResetInterest()
|
||||
{
|
||||
_LOG_DEBUG_ID(">> Logic::sendResetInterest");
|
||||
CHRONO_LOG_DBG(">> Logic::sendResetInterest");
|
||||
|
||||
if (m_needPeriodReset) {
|
||||
_LOG_DEBUG_ID("Need Period Reset");
|
||||
_LOG_DEBUG_ID("ResetTimer: " << m_resetTimer);
|
||||
CHRONO_LOG_DBG("Need Period Reset");
|
||||
CHRONO_LOG_DBG("ResetTimer: " << m_resetTimer);
|
||||
|
||||
m_resetInterestId = m_scheduler.schedule(m_resetTimer + time::milliseconds(m_reexpressionJitter(m_rng)),
|
||||
[this] { sendResetInterest(); });
|
||||
@@ -601,7 +572,6 @@ Logic::sendResetInterest()
|
||||
|
||||
Interest interest(m_syncReset);
|
||||
interest.setMustBeFresh(true);
|
||||
interest.setCanBePrefix(false); // no data is expected
|
||||
interest.setInterestLifetime(m_resetInterestLifetime);
|
||||
|
||||
// Assigning to m_pendingResetInterest cancels the previous reset Interest.
|
||||
@@ -610,17 +580,17 @@ Logic::sendResetInterest()
|
||||
bind(&Logic::onResetData, this, _1, _2),
|
||||
bind(&Logic::onSyncTimeout, this, _1), // Nack
|
||||
bind(&Logic::onSyncTimeout, this, _1));
|
||||
_LOG_DEBUG_ID("<< Logic::sendResetInterest");
|
||||
CHRONO_LOG_DBG("<< Logic::sendResetInterest");
|
||||
}
|
||||
|
||||
void
|
||||
Logic::sendSyncInterest()
|
||||
{
|
||||
_LOG_DEBUG_ID(">> Logic::sendSyncInterest");
|
||||
CHRONO_LOG_DBG(">> Logic::sendSyncInterest");
|
||||
|
||||
Name interestName;
|
||||
interestName.append(m_syncPrefix)
|
||||
.append(ndn::name::Component(*m_state.getRootDigest()));
|
||||
.append(name::Component(*m_state.getRootDigest()));
|
||||
|
||||
m_pendingSyncInterestName = interestName;
|
||||
|
||||
@@ -642,8 +612,8 @@ Logic::sendSyncInterest()
|
||||
bind(&Logic::onSyncNack, this, _1, _2),
|
||||
bind(&Logic::onSyncTimeout, this, _1));
|
||||
|
||||
_LOG_DEBUG_ID("Send interest: " << interest.getName());
|
||||
_LOG_DEBUG_ID("<< Logic::sendSyncInterest");
|
||||
CHRONO_LOG_DBG("Send interest: " << interest.getName());
|
||||
CHRONO_LOG_DBG("<< Logic::sendSyncInterest");
|
||||
}
|
||||
|
||||
void
|
||||
@@ -652,18 +622,18 @@ Logic::trimState(State& partialState, const State& state, size_t nExcludedStates
|
||||
partialState.reset();
|
||||
|
||||
std::vector<ConstLeafPtr> leaves;
|
||||
for (const ConstLeafPtr& leaf : state.getLeaves()) {
|
||||
for (const auto& leaf : state.getLeaves()) {
|
||||
leaves.push_back(leaf);
|
||||
}
|
||||
|
||||
std::shuffle(leaves.begin(), leaves.end(), m_rng);
|
||||
|
||||
size_t statesToEncode = leaves.size() - std::min(leaves.size() - 1, nExcludedStates);
|
||||
for (const auto& constLeafPtr : leaves) {
|
||||
for (const auto& leaf : leaves) {
|
||||
if (statesToEncode == 0) {
|
||||
break;
|
||||
}
|
||||
partialState.update(constLeafPtr->getSessionName(), constLeafPtr->getSeq());
|
||||
partialState.update(leaf->getSessionName(), leaf->getSeq());
|
||||
--statesToEncode;
|
||||
}
|
||||
}
|
||||
@@ -675,7 +645,7 @@ Logic::encodeSyncReply(const Name& nodePrefix, const Name& name, const State& st
|
||||
syncReply.setFreshnessPeriod(m_syncReplyFreshness);
|
||||
|
||||
auto finalizeReply = [this, &nodePrefix, &syncReply] (const State& state) {
|
||||
auto contentBuffer = bzip2::compress(reinterpret_cast<const char*>(state.wireEncode().wire()),
|
||||
auto contentBuffer = bzip2::compress(reinterpret_cast<const char*>(state.wireEncode().data()),
|
||||
state.wireEncode().size());
|
||||
syncReply.setContent(contentBuffer);
|
||||
|
||||
@@ -691,13 +661,14 @@ Logic::encodeSyncReply(const Name& nodePrefix, const Name& name, const State& st
|
||||
while (syncReply.wireEncode().size() > getMaxPacketLimit() - NDNLP_EXPECTED_OVERHEAD) {
|
||||
if (nExcludedStates == 1) {
|
||||
// To show this debug message only once
|
||||
_LOG_DEBUG("Sync reply size exceeded maximum packet limit (" << (getMaxPacketLimit() - NDNLP_EXPECTED_OVERHEAD) << ")");
|
||||
NDN_LOG_DEBUG("Sync reply size exceeded maximum packet limit ("
|
||||
<< (getMaxPacketLimit() - NDNLP_EXPECTED_OVERHEAD) << ")");
|
||||
}
|
||||
State partialState;
|
||||
trimState(partialState, state, nExcludedStates);
|
||||
finalizeReply(partialState);
|
||||
|
||||
BOOST_ASSERT(state.getLeaves().size() != 0);
|
||||
BOOST_ASSERT(!state.getLeaves().empty());
|
||||
nExcludedStates *= 2;
|
||||
}
|
||||
|
||||
@@ -707,7 +678,7 @@ Logic::encodeSyncReply(const Name& nodePrefix, const Name& name, const State& st
|
||||
void
|
||||
Logic::sendSyncData(const Name& nodePrefix, const Name& name, const State& state)
|
||||
{
|
||||
_LOG_DEBUG_ID(">> Logic::sendSyncData");
|
||||
CHRONO_LOG_DBG(">> Logic::sendSyncData");
|
||||
if (m_nodeList.find(nodePrefix) == m_nodeList.end())
|
||||
return;
|
||||
|
||||
@@ -720,17 +691,17 @@ Logic::sendSyncData(const Name& nodePrefix, const Name& name, const State& state
|
||||
|
||||
// re-schedule sending Sync interest
|
||||
time::milliseconds after(m_reexpressionJitter(m_rng));
|
||||
_LOG_DEBUG_ID("Satisfy our own interest");
|
||||
_LOG_DEBUG_ID("Reschedule sync interest after " << after);
|
||||
CHRONO_LOG_DBG("Satisfy our own interest");
|
||||
CHRONO_LOG_DBG("Reschedule sync interest after " << after);
|
||||
m_reexpressingInterestId = m_scheduler.schedule(after, [this] { sendSyncInterest(); });
|
||||
}
|
||||
_LOG_DEBUG_ID("<< Logic::sendSyncData");
|
||||
CHRONO_LOG_DBG("<< Logic::sendSyncData");
|
||||
}
|
||||
|
||||
void
|
||||
Logic::cancelReset()
|
||||
{
|
||||
_LOG_DEBUG_ID(">> Logic::cancelReset");
|
||||
CHRONO_LOG_DBG(">> Logic::cancelReset");
|
||||
if (!m_isInReset)
|
||||
return;
|
||||
|
||||
@@ -738,25 +709,24 @@ Logic::cancelReset()
|
||||
for (const auto& node : m_nodeList) {
|
||||
updateSeqNo(node.second.seqNo, node.first);
|
||||
}
|
||||
_LOG_DEBUG_ID("<< Logic::cancelReset");
|
||||
CHRONO_LOG_DBG("<< Logic::cancelReset");
|
||||
}
|
||||
|
||||
void
|
||||
Logic::printDigest(ConstBufferPtr digest)
|
||||
Logic::printDigest(const ConstBufferPtr& digest) const
|
||||
{
|
||||
std::string hash = ndn::toHex(digest->data(), digest->size(), false);
|
||||
_LOG_DEBUG_ID("Hash: " << hash);
|
||||
CHRONO_LOG_DBG("Hash: " << ndn::toHex(*digest, false));
|
||||
}
|
||||
|
||||
void
|
||||
Logic::sendRecoveryInterest(ConstBufferPtr digest)
|
||||
{
|
||||
_LOG_DEBUG_ID(">> Logic::sendRecoveryInterest");
|
||||
CHRONO_LOG_DBG(">> Logic::sendRecoveryInterest");
|
||||
|
||||
Name interestName;
|
||||
interestName.append(m_syncPrefix)
|
||||
.append(RECOVERY_COMPONENT)
|
||||
.append(ndn::name::Component(*digest));
|
||||
.append(name::Component(*digest));
|
||||
|
||||
Interest interest(interestName);
|
||||
interest.setMustBeFresh(true);
|
||||
@@ -767,46 +737,45 @@ Logic::sendRecoveryInterest(ConstBufferPtr digest)
|
||||
bind(&Logic::onRecoveryData, this, _1, _2),
|
||||
bind(&Logic::onRecoveryTimeout, this, _1), // Nack
|
||||
bind(&Logic::onRecoveryTimeout, this, _1));
|
||||
_LOG_DEBUG_ID("interest: " << interest.getName());
|
||||
_LOG_DEBUG_ID("<< Logic::sendRecoveryInterest");
|
||||
CHRONO_LOG_DBG("interest: " << interest.getName());
|
||||
CHRONO_LOG_DBG("<< Logic::sendRecoveryInterest");
|
||||
}
|
||||
|
||||
void
|
||||
Logic::processRecoveryInterest(const Interest& interest)
|
||||
{
|
||||
_LOG_DEBUG_ID(">> Logic::processRecoveryInterest");
|
||||
CHRONO_LOG_DBG(">> Logic::processRecoveryInterest");
|
||||
|
||||
Name name = interest.getName();
|
||||
const auto& name = interest.getName();
|
||||
ConstBufferPtr digest = make_shared<ndn::Buffer>(name.get(-1).value(), name.get(-1).value_size());
|
||||
|
||||
ConstBufferPtr rootDigest = m_state.getRootDigest();
|
||||
|
||||
DiffStateContainer::iterator stateIter = m_log.find(digest);
|
||||
|
||||
if (stateIter != m_log.end() || *digest == *EMPTY_DIGEST || *rootDigest == *digest) {
|
||||
_LOG_DEBUG_ID("I can help you recover");
|
||||
auto stateIter = m_log.find(digest);
|
||||
if (stateIter != m_log.end() || *digest == EMPTY_DIGEST || *rootDigest == *digest) {
|
||||
CHRONO_LOG_DBG("I can help you recover");
|
||||
sendSyncData(m_defaultUserPrefix, name, m_state);
|
||||
return;
|
||||
}
|
||||
_LOG_DEBUG_ID("<< Logic::processRecoveryInterest");
|
||||
|
||||
CHRONO_LOG_DBG("<< Logic::processRecoveryInterest");
|
||||
}
|
||||
|
||||
void
|
||||
Logic::onRecoveryData(const Interest& interest, const Data& data)
|
||||
{
|
||||
_LOG_DEBUG_ID(">> Logic::onRecoveryData");
|
||||
CHRONO_LOG_DBG(">> Logic::onRecoveryData");
|
||||
m_pendingRecoveryInterests.erase(interest.getName()[-1].toUri());
|
||||
onSyncDataValidated(data);
|
||||
_LOG_DEBUG_ID("<< Logic::onRecoveryData");
|
||||
CHRONO_LOG_DBG("<< Logic::onRecoveryData");
|
||||
}
|
||||
|
||||
void
|
||||
Logic::onRecoveryTimeout(const Interest& interest)
|
||||
{
|
||||
_LOG_DEBUG_ID(">> Logic::onRecoveryTimeout");
|
||||
CHRONO_LOG_DBG(">> Logic::onRecoveryTimeout");
|
||||
m_pendingRecoveryInterests.erase(interest.getName()[-1].toUri());
|
||||
_LOG_DEBUG_ID("Interest: " << interest.getName());
|
||||
_LOG_DEBUG_ID("<< Logic::onRecoveryTimeout");
|
||||
CHRONO_LOG_DBG("Interest: " << interest.getName());
|
||||
CHRONO_LOG_DBG("<< Logic::onRecoveryTimeout");
|
||||
}
|
||||
|
||||
} // namespace chronosync
|
||||
|
||||
+28
-75
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2019 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2022 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -31,13 +31,6 @@
|
||||
|
||||
#include <ndn-cxx/util/random.hpp>
|
||||
|
||||
#include <boost/archive/iterators/dataflow_exception.hpp>
|
||||
#include <boost/archive/iterators/transform_width.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace chronosync {
|
||||
@@ -77,7 +70,7 @@ public:
|
||||
* The parameter is a set of MissingDataInfo, of which each corresponds to
|
||||
* a session that has changed its state.
|
||||
*/
|
||||
using UpdateCallback = function<void(const std::vector<MissingDataInfo>&)>;
|
||||
using UpdateCallback = std::function<void(const std::vector<MissingDataInfo>&)>;
|
||||
|
||||
/**
|
||||
* @brief Logic of ChronoSync
|
||||
@@ -88,20 +81,18 @@ public:
|
||||
class Error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
Error(const std::string& what)
|
||||
: std::runtime_error(what)
|
||||
{
|
||||
}
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
public:
|
||||
static const time::steady_clock::Duration DEFAULT_RESET_TIMER;
|
||||
static const time::steady_clock::Duration DEFAULT_CANCEL_RESET_TIMER;
|
||||
static const time::milliseconds DEFAULT_RESET_INTEREST_LIFETIME;
|
||||
static const time::milliseconds DEFAULT_SYNC_INTEREST_LIFETIME;
|
||||
static const time::milliseconds DEFAULT_SYNC_REPLY_FRESHNESS;
|
||||
static const time::milliseconds DEFAULT_RECOVERY_INTEREST_LIFETIME;
|
||||
static inline const Name EMPTY_NAME;
|
||||
static inline const Name DEFAULT_NAME;
|
||||
static inline const std::shared_ptr<Validator> DEFAULT_VALIDATOR;
|
||||
static constexpr time::steady_clock::duration DEFAULT_RESET_TIMER = 0_ms;
|
||||
static constexpr time::steady_clock::duration DEFAULT_CANCEL_RESET_TIMER = 500_ms;
|
||||
static constexpr time::milliseconds DEFAULT_RESET_INTEREST_LIFETIME = 1_s;
|
||||
static constexpr time::milliseconds DEFAULT_SYNC_INTEREST_LIFETIME = 1_s;
|
||||
static constexpr time::milliseconds DEFAULT_SYNC_REPLY_FRESHNESS = 1_s;
|
||||
static constexpr time::milliseconds DEFAULT_RECOVERY_INTEREST_LIFETIME = 1_s;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
@@ -126,8 +117,8 @@ public:
|
||||
const UpdateCallback& onUpdate,
|
||||
const Name& defaultSigningId = DEFAULT_NAME,
|
||||
std::shared_ptr<Validator> validator = DEFAULT_VALIDATOR,
|
||||
const time::steady_clock::Duration& resetTimer = DEFAULT_RESET_TIMER,
|
||||
const time::steady_clock::Duration& cancelResetTimer = DEFAULT_CANCEL_RESET_TIMER,
|
||||
const time::steady_clock::duration& resetTimer = DEFAULT_RESET_TIMER,
|
||||
const time::steady_clock::duration& cancelResetTimer = DEFAULT_CANCEL_RESET_TIMER,
|
||||
const time::milliseconds& resetInterestLifetime = DEFAULT_RESET_INTEREST_LIFETIME,
|
||||
const time::milliseconds& syncInterestLifetime = DEFAULT_SYNC_INTEREST_LIFETIME,
|
||||
const time::milliseconds& syncReplyFreshness = DEFAULT_SYNC_REPLY_FRESHNESS,
|
||||
@@ -365,24 +356,21 @@ private:
|
||||
* This method extracts state update information from Sync Reply and applies
|
||||
* it to the Sync Tree and re-express Sync Interest.
|
||||
*
|
||||
* @param name The data name of the Sync Reply.
|
||||
* @param digest The digest in the data name.
|
||||
* @param syncReplyBlock The content of the Sync Reply.
|
||||
* @param name The data name of the Sync Reply.
|
||||
* @param digest The digest in the data name.
|
||||
* @param syncReply The content of the Sync Reply.
|
||||
*/
|
||||
void
|
||||
processSyncData(const Name& name,
|
||||
ConstBufferPtr digest,
|
||||
const Block& syncReplyBlock);
|
||||
processSyncData(const Name& name, ConstBufferPtr digest, const Block& syncReply);
|
||||
|
||||
/**
|
||||
* @brief Insert state diff into log
|
||||
*
|
||||
* @param diff The diff .
|
||||
* @param diff The diff.
|
||||
* @param previousRoot The root digest before state changes.
|
||||
*/
|
||||
void
|
||||
insertToDiffLog(DiffStatePtr diff,
|
||||
ConstBufferPtr previousRoot);
|
||||
insertToDiffLog(DiffStatePtr diff, ConstBufferPtr previousRoot);
|
||||
|
||||
/**
|
||||
* @brief Reply to all pending Sync Interests with a particular commit (or diff)
|
||||
@@ -414,7 +402,7 @@ private:
|
||||
cancelReset();
|
||||
|
||||
void
|
||||
printDigest(ConstBufferPtr digest);
|
||||
printDigest(const ConstBufferPtr& digest) const;
|
||||
|
||||
/**
|
||||
* @brief Helper method to send Recovery Interest
|
||||
@@ -457,43 +445,8 @@ private:
|
||||
void
|
||||
onRecoveryTimeout(const Interest& interest);
|
||||
|
||||
// /**
|
||||
// * @brief Helper method to send Exclude Interest
|
||||
// *
|
||||
// * @param interest The interest whose exclude filter will be augmented
|
||||
// * @param data The data whose implicit digest will be inserted into exclude filter
|
||||
// */
|
||||
// void
|
||||
// sendExcludeInterest(const Interest& interest, const Data& data);
|
||||
|
||||
// /**
|
||||
// * @brief Helper method to form the exclude Interest and calls sendExcludeInterest
|
||||
// *
|
||||
// * @param interest The interest whose exclude filter will be augmented
|
||||
// * @param nodePrefix The prefix of the sender node
|
||||
// * @param commit The commit whose contents will be used to obtain the implicit
|
||||
// digest to be excluded
|
||||
// * @param previousRoot The digest to be included in the interest
|
||||
// */
|
||||
// void
|
||||
// formAndSendExcludeInterest(const Name& nodePrefix,
|
||||
// const State& commit,
|
||||
// ConstBufferPtr previousRoot);
|
||||
|
||||
void
|
||||
cleanupPendingInterest(const ndn::PendingInterestId* pendingInterestId);
|
||||
|
||||
public:
|
||||
static const ndn::Name DEFAULT_NAME;
|
||||
static const ndn::Name EMPTY_NAME;
|
||||
static const std::shared_ptr<Validator> DEFAULT_VALIDATOR;
|
||||
|
||||
private:
|
||||
using NodeList = std::unordered_map<ndn::Name, NodeInfo>;
|
||||
|
||||
static const ConstBufferPtr EMPTY_DIGEST;
|
||||
static const ndn::name::Component RESET_COMPONENT;
|
||||
static const ndn::name::Component RECOVERY_COMPONENT;
|
||||
using NodeList = std::unordered_map<Name, NodeInfo>;
|
||||
|
||||
// Communication
|
||||
ndn::Face& m_face;
|
||||
@@ -528,9 +481,9 @@ private:
|
||||
std::uniform_int_distribution<> m_rangeUniformRandom;
|
||||
std::uniform_int_distribution<> m_reexpressionJitter;
|
||||
/// @brief Timer to send next reset 0 for no reset
|
||||
time::steady_clock::Duration m_resetTimer;
|
||||
time::steady_clock::duration m_resetTimer;
|
||||
/// @brief Timer to cancel reset state
|
||||
time::steady_clock::Duration m_cancelResetTimer;
|
||||
time::steady_clock::duration m_cancelResetTimer;
|
||||
/// @brief Lifetime of reset interest
|
||||
time::milliseconds m_resetInterestLifetime;
|
||||
/// @brief Lifetime of sync interest
|
||||
@@ -544,14 +497,14 @@ private:
|
||||
ndn::KeyChain m_keyChain;
|
||||
std::shared_ptr<Validator> m_validator;
|
||||
|
||||
int m_instanceId;
|
||||
static int s_instanceCounter;
|
||||
const int m_instanceId;
|
||||
static inline int s_instanceCounter = 0;
|
||||
};
|
||||
|
||||
#ifdef CHRONOSYNC_HAVE_TESTS
|
||||
#ifdef CHRONOSYNC_WITH_TESTS
|
||||
size_t
|
||||
getMaxPacketLimit();
|
||||
#endif // CHRONOSYNC_HAVE_TESTS
|
||||
#endif // CHRONOSYNC_WITH_TESTS
|
||||
|
||||
} // namespace chronosync
|
||||
|
||||
|
||||
+26
-28
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2019 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2022 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -23,16 +23,13 @@
|
||||
*/
|
||||
|
||||
#include "socket.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
INIT_LOGGER(Socket);
|
||||
#include <ndn-cxx/util/logger.hpp>
|
||||
|
||||
NDN_LOG_INIT(sync.Socket);
|
||||
|
||||
namespace chronosync {
|
||||
|
||||
const ndn::Name Socket::DEFAULT_NAME;
|
||||
const ndn::Name Socket::DEFAULT_PREFIX;
|
||||
const std::shared_ptr<Validator> Socket::DEFAULT_VALIDATOR;
|
||||
|
||||
Socket::Socket(const Name& syncPrefix,
|
||||
const Name& userPrefix,
|
||||
ndn::Face& face,
|
||||
@@ -48,14 +45,16 @@ Socket::Socket(const Name& syncPrefix,
|
||||
syncInterestLifetime, Logic::DEFAULT_SYNC_REPLY_FRESHNESS, Logic::DEFAULT_RECOVERY_INTEREST_LIFETIME,
|
||||
session)
|
||||
, m_signingId(signingId)
|
||||
, m_validator(validator)
|
||||
, m_validator(std::move(validator))
|
||||
{
|
||||
NDN_LOG_DEBUG(">> Socket::Socket");
|
||||
|
||||
if (m_userPrefix != DEFAULT_NAME)
|
||||
m_registeredPrefixList[m_userPrefix] =
|
||||
m_face.setInterestFilter(m_userPrefix,
|
||||
bind(&Socket::onInterest, this, _1, _2),
|
||||
[] (const Name& prefix, const std::string& msg) {});
|
||||
[this] (auto&&... args) { onInterest(std::forward<decltype(args)>(args)...); },
|
||||
[] (auto&&...) {});
|
||||
|
||||
NDN_LOG_DEBUG("<< Socket::Socket");
|
||||
}
|
||||
|
||||
@@ -83,8 +82,9 @@ Socket::addSyncNode(const Name& prefix, const Name& signingId, const name::Compo
|
||||
m_logic.addUserNode(prefix, signingId, session);
|
||||
m_registeredPrefixList[prefix] =
|
||||
m_face.setInterestFilter(prefix,
|
||||
bind(&Socket::onInterest, this, _1, _2),
|
||||
[] (const Name& prefix, const std::string& msg) {});
|
||||
[this] (auto&&... args) { onInterest(std::forward<decltype(args)>(args)...); },
|
||||
[] (auto&&...) {});
|
||||
|
||||
NDN_LOG_DEBUG("<< addSyncNode");
|
||||
}
|
||||
|
||||
@@ -108,21 +108,21 @@ void
|
||||
Socket::publishData(const uint8_t* buf, size_t len, const ndn::time::milliseconds& freshness,
|
||||
const Name& prefix)
|
||||
{
|
||||
publishData(ndn::encoding::makeBinaryBlock(ndn::tlv::Content, buf, len), freshness, prefix);
|
||||
publishData(ndn::makeBinaryBlock(ndn::tlv::Content, {buf, len}), freshness, prefix);
|
||||
}
|
||||
|
||||
void
|
||||
Socket::publishData(const uint8_t* buf, size_t len, const ndn::time::milliseconds& freshness,
|
||||
const uint64_t& seqNo, const Name& prefix)
|
||||
{
|
||||
publishData(ndn::encoding::makeBinaryBlock(ndn::tlv::Content, buf, len), freshness, seqNo, prefix);
|
||||
publishData(ndn::makeBinaryBlock(ndn::tlv::Content, {buf, len}), freshness, seqNo, prefix);
|
||||
}
|
||||
|
||||
void
|
||||
Socket::publishData(const Block& content, const ndn::time::milliseconds& freshness,
|
||||
const Name& prefix)
|
||||
{
|
||||
shared_ptr<Data> data = make_shared<Data>();
|
||||
auto data = std::make_shared<Data>();
|
||||
data->setContent(content);
|
||||
data->setFreshnessPeriod(freshness);
|
||||
|
||||
@@ -145,7 +145,7 @@ void
|
||||
Socket::publishData(const Block& content, const ndn::time::milliseconds& freshness,
|
||||
const uint64_t& seqNo, const Name& prefix)
|
||||
{
|
||||
shared_ptr<Data> data = make_shared<Data>();
|
||||
auto data = std::make_shared<Data>();
|
||||
data->setContent(content);
|
||||
data->setFreshnessPeriod(freshness);
|
||||
|
||||
@@ -174,10 +174,9 @@ Socket::fetchData(const Name& sessionName, const SeqNo& seqNo,
|
||||
|
||||
Interest interest(interestName);
|
||||
interest.setMustBeFresh(true);
|
||||
interest.setCanBePrefix(false);
|
||||
|
||||
DataValidationErrorCallback failureCallback =
|
||||
bind(&Socket::onDataValidationFailed, this, _1, _2);
|
||||
[this] (auto&&... args) { onDataValidationFailed(std::forward<decltype(args)>(args)...); };
|
||||
|
||||
m_face.expressInterest(interest,
|
||||
bind(&Socket::onData, this, _1, _2, dataCallback, failureCallback),
|
||||
@@ -194,37 +193,36 @@ Socket::fetchData(const Name& sessionName, const SeqNo& seqNo,
|
||||
const ndn::TimeoutCallback& onTimeout,
|
||||
int nRetries)
|
||||
{
|
||||
_LOG_DEBUG(">> Socket::fetchData");
|
||||
NDN_LOG_DEBUG(">> Socket::fetchData");
|
||||
Name interestName;
|
||||
interestName.append(sessionName).appendNumber(seqNo);
|
||||
|
||||
Interest interest(interestName);
|
||||
interest.setMustBeFresh(true);
|
||||
interest.setCanBePrefix(false);
|
||||
|
||||
m_face.expressInterest(interest,
|
||||
bind(&Socket::onData, this, _1, _2, dataCallback, failureCallback),
|
||||
bind(onTimeout, _1), // Nack
|
||||
onTimeout);
|
||||
|
||||
_LOG_DEBUG("<< Socket::fetchData");
|
||||
NDN_LOG_DEBUG("<< Socket::fetchData");
|
||||
}
|
||||
|
||||
void
|
||||
Socket::onInterest(const Name& prefix, const Interest& interest)
|
||||
Socket::onInterest(const Name&, const Interest& interest)
|
||||
{
|
||||
shared_ptr<const Data> data = m_ims.find(interest);
|
||||
auto data = m_ims.find(interest);
|
||||
if (data != nullptr) {
|
||||
m_face.put(*data);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Socket::onData(const Interest& interest, const Data& data,
|
||||
Socket::onData(const Interest&, const Data& data,
|
||||
const DataValidatedCallback& onValidated,
|
||||
const DataValidationErrorCallback& onFailed)
|
||||
{
|
||||
_LOG_DEBUG("Socket::onData");
|
||||
NDN_LOG_DEBUG("Socket::onData");
|
||||
|
||||
if (static_cast<bool>(m_validator))
|
||||
m_validator->validate(data, onValidated, onFailed);
|
||||
@@ -237,7 +235,8 @@ Socket::onDataTimeout(const Interest& interest, int nRetries,
|
||||
const DataValidatedCallback& onValidated,
|
||||
const DataValidationErrorCallback& onFailed)
|
||||
{
|
||||
_LOG_DEBUG("Socket::onDataTimeout");
|
||||
NDN_LOG_DEBUG("Socket::onDataTimeout");
|
||||
|
||||
if (nRetries <= 0)
|
||||
return;
|
||||
|
||||
@@ -253,8 +252,7 @@ Socket::onDataTimeout(const Interest& interest, int nRetries,
|
||||
}
|
||||
|
||||
void
|
||||
Socket::onDataValidationFailed(const Data& data,
|
||||
const ValidationError& error)
|
||||
Socket::onDataValidationFailed(const Data&, const ValidationError&)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
+8
-13
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2019 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2022 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -52,11 +52,7 @@ public:
|
||||
class Error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
Error(const std::string& what)
|
||||
: std::runtime_error(what)
|
||||
{
|
||||
}
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
Socket(const Name& syncPrefix,
|
||||
@@ -70,9 +66,8 @@ public:
|
||||
|
||||
~Socket();
|
||||
|
||||
using DataValidatedCallback = function<void(const Data&)>;
|
||||
|
||||
using DataValidationErrorCallback = function<void(const Data&, const ValidationError& error)> ;
|
||||
using DataValidatedCallback = std::function<void(const Data&)>;
|
||||
using DataValidationErrorCallback = std::function<void(const Data&, const ValidationError& error)> ;
|
||||
|
||||
/**
|
||||
* @brief Add a sync node under same logic
|
||||
@@ -232,12 +227,12 @@ private:
|
||||
const ValidationError& error);
|
||||
|
||||
public:
|
||||
static const ndn::Name DEFAULT_NAME;
|
||||
static const ndn::Name DEFAULT_PREFIX;
|
||||
static const std::shared_ptr<Validator> DEFAULT_VALIDATOR;
|
||||
static inline const Name DEFAULT_NAME;
|
||||
static inline const Name DEFAULT_PREFIX;
|
||||
static inline const std::shared_ptr<Validator> DEFAULT_VALIDATOR;
|
||||
|
||||
private:
|
||||
using RegisteredPrefixList = std::unordered_map<ndn::Name, ndn::RegisteredPrefixHandle>;
|
||||
using RegisteredPrefixList = std::unordered_map<Name, ndn::RegisteredPrefixHandle>;
|
||||
|
||||
Name m_userPrefix;
|
||||
ndn::Face& m_face;
|
||||
|
||||
+34
-46
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2017 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2022 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -23,38 +23,33 @@
|
||||
*/
|
||||
|
||||
#include "state.hpp"
|
||||
#include "detail/tlv.hpp"
|
||||
|
||||
#include <boost/range/adaptor/reversed.hpp>
|
||||
#include <ndn-cxx/util/exception.hpp>
|
||||
|
||||
namespace chronosync {
|
||||
|
||||
State::~State() = default;
|
||||
|
||||
/**
|
||||
* @brief Add or update leaf to the sync tree
|
||||
*
|
||||
* @param info session name of the leaf
|
||||
* @param seq sequence number of the leaf
|
||||
* @return 3-tuple (isInserted, isUpdated, oldSeqNo)
|
||||
*/
|
||||
std::tuple<bool, bool, SeqNo>
|
||||
State::update(const Name& info, const SeqNo& seq)
|
||||
{
|
||||
m_wire.reset();
|
||||
|
||||
LeafContainer::iterator leaf = m_leaves.find(info);
|
||||
|
||||
auto leaf = m_leaves.find(info);
|
||||
if (leaf == m_leaves.end()) {
|
||||
m_leaves.insert(make_shared<Leaf>(info, cref(seq)));
|
||||
return make_tuple(true, false, 0);
|
||||
m_leaves.insert(make_shared<Leaf>(info, seq));
|
||||
return {true, false, 0};
|
||||
}
|
||||
else {
|
||||
if ((*leaf)->getSeq() == seq || seq < (*leaf)->getSeq()) {
|
||||
return make_tuple(false, false, 0);
|
||||
return {false, false, 0};
|
||||
}
|
||||
|
||||
SeqNo old = (*leaf)->getSeq();
|
||||
m_leaves.modify(leaf,
|
||||
[=] (LeafPtr& leaf) { leaf->setSeq(seq); } );
|
||||
return make_tuple(false, true, old);
|
||||
m_leaves.modify(leaf, [seq] (LeafPtr& leaf) { leaf->setSeq(seq); } );
|
||||
return {false, true, old};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,16 +58,14 @@ State::getRootDigest() const
|
||||
{
|
||||
m_digest.reset();
|
||||
|
||||
BOOST_FOREACH (ConstLeafPtr leaf, m_leaves.get<ordered>())
|
||||
{
|
||||
BOOST_ASSERT(leaf != 0);
|
||||
m_digest.update(leaf->getDigest()->data(), leaf->getDigest()->size());
|
||||
}
|
||||
for (const auto& leaf : m_leaves.get<ordered>()) {
|
||||
BOOST_ASSERT(leaf != nullptr);
|
||||
m_digest.update(*leaf->getDigest());
|
||||
}
|
||||
|
||||
return m_digest.computeDigest();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
State::reset()
|
||||
{
|
||||
@@ -82,30 +75,27 @@ State::reset()
|
||||
State&
|
||||
State::operator+=(const State& state)
|
||||
{
|
||||
BOOST_FOREACH (ConstLeafPtr leaf, state.getLeaves())
|
||||
{
|
||||
BOOST_ASSERT(leaf != 0);
|
||||
update(leaf->getSessionName(), leaf->getSeq());
|
||||
}
|
||||
|
||||
for (const auto& leaf : state.getLeaves()) {
|
||||
BOOST_ASSERT(leaf != nullptr);
|
||||
update(leaf->getSessionName(), leaf->getSeq());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<encoding::Tag T>
|
||||
template<ndn::encoding::Tag T>
|
||||
size_t
|
||||
State::wireEncode(encoding::EncodingImpl<T>& block) const
|
||||
State::wireEncode(ndn::encoding::EncodingImpl<T>& block) const
|
||||
{
|
||||
size_t totalLength = 0;
|
||||
|
||||
BOOST_REVERSE_FOREACH (ConstLeafPtr leaf, m_leaves.get<ordered>())
|
||||
{
|
||||
size_t entryLength = 0;
|
||||
entryLength += prependNonNegativeIntegerBlock(block, tlv::SeqNo, leaf->getSeq());
|
||||
entryLength += leaf->getSessionName().wireEncode(block);
|
||||
entryLength += block.prependVarNumber(entryLength);
|
||||
entryLength += block.prependVarNumber(tlv::StateLeaf);
|
||||
totalLength += entryLength;
|
||||
}
|
||||
for (const auto& leaf : m_leaves.get<ordered>() | boost::adaptors::reversed) {
|
||||
size_t entryLength = 0;
|
||||
entryLength += prependNonNegativeIntegerBlock(block, tlv::SeqNo, leaf->getSeq());
|
||||
entryLength += leaf->getSessionName().wireEncode(block);
|
||||
entryLength += block.prependVarNumber(entryLength);
|
||||
entryLength += block.prependVarNumber(tlv::StateLeaf);
|
||||
totalLength += entryLength;
|
||||
}
|
||||
|
||||
totalLength += block.prependVarNumber(totalLength);
|
||||
totalLength += block.prependVarNumber(tlv::SyncReply);
|
||||
@@ -135,28 +125,26 @@ void
|
||||
State::wireDecode(const Block& wire)
|
||||
{
|
||||
if (!wire.hasWire())
|
||||
BOOST_THROW_EXCEPTION(Error("The supplied block does not contain wire format"));
|
||||
NDN_THROW(Error("The supplied block does not contain wire format"));
|
||||
|
||||
if (wire.type() != tlv::SyncReply)
|
||||
BOOST_THROW_EXCEPTION(Error("Unexpected TLV type when decoding SyncReply: " +
|
||||
boost::lexical_cast<std::string>(m_wire.type())));
|
||||
NDN_THROW(Error("Unexpected TLV type when decoding SyncReply: " + std::to_string(wire.type())));
|
||||
|
||||
wire.parse();
|
||||
m_wire = wire;
|
||||
|
||||
for (Block::element_const_iterator it = wire.elements_begin();
|
||||
it != wire.elements_end(); it++) {
|
||||
for (auto it = wire.elements_begin(); it != wire.elements_end(); it++) {
|
||||
if (it->type() == tlv::StateLeaf) {
|
||||
it->parse();
|
||||
|
||||
Block::element_const_iterator val = it->elements_begin();
|
||||
auto val = it->elements_begin();
|
||||
Name info(*val);
|
||||
val++;
|
||||
|
||||
if (val != it->elements_end())
|
||||
update(info, readNonNegativeInteger(*val));
|
||||
else
|
||||
BOOST_THROW_EXCEPTION(Error("No seqNo when decoding SyncReply"));
|
||||
NDN_THROW(Error("No SeqNo when decoding SyncReply"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-9
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2017 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2021 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -26,9 +26,9 @@
|
||||
#define CHRONOSYNC_STATE_HPP
|
||||
|
||||
#include "leaf-container.hpp"
|
||||
#include "tlv.hpp"
|
||||
|
||||
#include <ndn-cxx/util/sha256.hpp>
|
||||
#include <tuple>
|
||||
|
||||
namespace chronosync {
|
||||
|
||||
@@ -49,11 +49,7 @@ public:
|
||||
class Error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
Error(const std::string& what)
|
||||
: std::runtime_error(what)
|
||||
{
|
||||
}
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
virtual
|
||||
@@ -112,9 +108,9 @@ public:
|
||||
wireDecode(const Block& wire);
|
||||
|
||||
protected:
|
||||
template<encoding::Tag T>
|
||||
template<ndn::encoding::Tag T>
|
||||
size_t
|
||||
wireEncode(encoding::EncodingImpl<T>& block) const;
|
||||
wireEncode(ndn::encoding::EncodingImpl<T>& block) const;
|
||||
|
||||
protected:
|
||||
LeafContainer m_leaves;
|
||||
|
||||
@@ -1,214 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2015 Regents of the University of California.
|
||||
*
|
||||
* Based on work by Martin Ba (http://stackoverflow.com/a/26718189)
|
||||
*
|
||||
* This file is distributed under the Boost Software License, Version 1.0.
|
||||
* (See http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef NDN_TESTS_BOOST_MULTI_LOG_FORMATTER_HPP
|
||||
#define NDN_TESTS_BOOST_MULTI_LOG_FORMATTER_HPP
|
||||
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#if BOOST_VERSION >= 105900
|
||||
#include <boost/test/unit_test_parameters.hpp>
|
||||
#else
|
||||
#include <boost/test/detail/unit_test_parameters.hpp>
|
||||
#endif // BOOST_VERSION >= 105900
|
||||
|
||||
#include <boost/test/unit_test_log_formatter.hpp>
|
||||
#include <boost/test/output/compiler_log_formatter.hpp>
|
||||
#include <boost/test/output/xml_log_formatter.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace output {
|
||||
|
||||
/**
|
||||
* @brief Log formatter for Boost.Test that outputs the logging to multiple formatters
|
||||
*
|
||||
* The log formatter is designed to output to one or multiple formatters at the same time. For
|
||||
* example, one HRF formatter can output to the standard output, while XML formatter output to
|
||||
* the file.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* // Call in init_unit_test_suite: (this will override the --log_format parameter)
|
||||
* auto formatter = new boost::unit_test::output::multi_log_formatter; // same as already configured logger
|
||||
*
|
||||
* // Prepare and add additional logger(s)
|
||||
* formatter.add(std::make_shared<boost::unit_test::output::xml_log_formatter>(),
|
||||
* std::make_shared<std::ofstream>("out.xml"));
|
||||
*
|
||||
* boost::unit_test::unit_test_log.set_formatter(formatter);
|
||||
*
|
||||
* @note Calling `boost::unit_test::unit_test_log.set_stream(...)` will change the stream for
|
||||
* the original logger.
|
||||
*/
|
||||
class multi_log_formatter : public unit_test_log_formatter
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Create instance of the logger, based on the configured logger instance
|
||||
*/
|
||||
multi_log_formatter()
|
||||
{
|
||||
auto format =
|
||||
#if BOOST_VERSION > 105900
|
||||
runtime_config::get<output_format>(runtime_config::LOG_FORMAT);
|
||||
#else
|
||||
runtime_config::log_format();
|
||||
#endif // BOOST_VERSION > 105900
|
||||
|
||||
switch (format) {
|
||||
default:
|
||||
#if BOOST_VERSION >= 105900
|
||||
case OF_CLF:
|
||||
#else
|
||||
case CLF:
|
||||
#endif // BOOST_VERSION >= 105900
|
||||
m_loggers.push_back({std::make_shared<compiler_log_formatter>(), nullptr});
|
||||
break;
|
||||
#if BOOST_VERSION >= 105900
|
||||
case OF_XML:
|
||||
#else
|
||||
case XML:
|
||||
#endif // BOOST_VERSION >= 105900
|
||||
m_loggers.push_back({std::make_shared<xml_log_formatter>(), nullptr});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
add(std::shared_ptr<unit_test_log_formatter> formatter, std::shared_ptr<std::ostream> os)
|
||||
{
|
||||
m_loggers.push_back({formatter, os});
|
||||
}
|
||||
|
||||
// Formatter interface
|
||||
void
|
||||
log_start(std::ostream& os, counter_t test_cases_amount)
|
||||
{
|
||||
for (auto& l : m_loggers)
|
||||
l.logger->log_start(l.os == nullptr ? os : *l.os, test_cases_amount);
|
||||
}
|
||||
|
||||
void
|
||||
log_finish(std::ostream& os)
|
||||
{
|
||||
for (auto& l : m_loggers)
|
||||
l.logger->log_finish(l.os == nullptr ? os : *l.os);
|
||||
}
|
||||
|
||||
void
|
||||
log_build_info(std::ostream& os)
|
||||
{
|
||||
for (auto& l : m_loggers)
|
||||
l.logger->log_build_info(l.os == nullptr ? os : *l.os);
|
||||
}
|
||||
|
||||
void
|
||||
test_unit_start(std::ostream& os, const test_unit& tu)
|
||||
{
|
||||
for (auto& l : m_loggers)
|
||||
l.logger->test_unit_start(l.os == nullptr ? os : *l.os, tu);
|
||||
}
|
||||
|
||||
void
|
||||
test_unit_finish(std::ostream& os, const test_unit& tu, unsigned long elapsed)
|
||||
{
|
||||
for (auto& l : m_loggers)
|
||||
l.logger->test_unit_finish(l.os == nullptr ? os : *l.os, tu, elapsed);
|
||||
}
|
||||
|
||||
void
|
||||
test_unit_skipped(std::ostream& os, const test_unit& tu)
|
||||
{
|
||||
for (auto& l : m_loggers)
|
||||
l.logger->test_unit_skipped(l.os == nullptr ? os : *l.os, tu);
|
||||
}
|
||||
|
||||
#if BOOST_VERSION >= 105900
|
||||
void
|
||||
log_exception_start(std::ostream& os, const log_checkpoint_data& lcd, const execution_exception& ex)
|
||||
{
|
||||
for (auto& l : m_loggers)
|
||||
l.logger->log_exception_start(l.os == nullptr ? os : *l.os, lcd, ex);
|
||||
}
|
||||
|
||||
void
|
||||
log_exception_finish(std::ostream& os)
|
||||
{
|
||||
for (auto& l : m_loggers)
|
||||
l.logger->log_exception_finish(l.os == nullptr ? os : *l.os);
|
||||
}
|
||||
#else
|
||||
void
|
||||
log_exception(std::ostream& os, const log_checkpoint_data& lcd, const execution_exception& ex)
|
||||
{
|
||||
for (auto& l : m_loggers)
|
||||
l.logger->log_exception(l.os == nullptr ? os : *l.os, lcd, ex);
|
||||
}
|
||||
#endif // BOOST_VERSION >= 105900
|
||||
|
||||
void
|
||||
log_entry_start(std::ostream& os, const log_entry_data& entry_data, log_entry_types let)
|
||||
{
|
||||
for (auto& l : m_loggers)
|
||||
l.logger->log_entry_start(l.os == nullptr ? os : *l.os, entry_data, let);
|
||||
}
|
||||
|
||||
void
|
||||
log_entry_value(std::ostream& os, const_string value)
|
||||
{
|
||||
for (auto& l : m_loggers)
|
||||
l.logger->log_entry_value(l.os == nullptr ? os : *l.os, value);
|
||||
}
|
||||
|
||||
void
|
||||
log_entry_finish(std::ostream& os)
|
||||
{
|
||||
for (auto& l : m_loggers)
|
||||
l.logger->log_entry_finish(l.os == nullptr ? os : *l.os);
|
||||
}
|
||||
|
||||
#if BOOST_VERSION >= 105900
|
||||
void
|
||||
entry_context_start(std::ostream& os, log_level level)
|
||||
{
|
||||
for (auto& l : m_loggers)
|
||||
l.logger->entry_context_start(l.os == nullptr ? os : *l.os, level);
|
||||
}
|
||||
|
||||
void
|
||||
log_entry_context(std::ostream& os, const_string value)
|
||||
{
|
||||
for (auto& l : m_loggers)
|
||||
l.logger->log_entry_context(l.os == nullptr ? os : *l.os, value);
|
||||
}
|
||||
|
||||
void
|
||||
entry_context_finish(std::ostream& os)
|
||||
{
|
||||
for (auto& l : m_loggers)
|
||||
l.logger->entry_context_finish(l.os == nullptr ? os : *l.os);
|
||||
}
|
||||
#endif // BOOST_VERSION >= 105900
|
||||
|
||||
private:
|
||||
struct LoggerInfo
|
||||
{
|
||||
std::shared_ptr<unit_test_log_formatter> logger;
|
||||
std::shared_ptr<std::ostream> os;
|
||||
};
|
||||
std::vector<LoggerInfo> m_loggers;
|
||||
};
|
||||
|
||||
} // namespace output
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#endif // NDN_TESTS_BOOST_MULTI_LOG_FORMATTER_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2017 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2023 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -22,8 +22,7 @@
|
||||
#include <ndn-cxx/util/io.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace ndn {
|
||||
namespace tests {
|
||||
namespace ndn::tests {
|
||||
|
||||
IdentityManagementFixture::IdentityManagementFixture()
|
||||
: m_keyChain("pib-memory:", "tpm-memory:")
|
||||
@@ -54,7 +53,7 @@ IdentityManagementFixture::addIdentity(const Name& identity, const ndn::KeyParam
|
||||
bool
|
||||
IdentityManagementFixture::saveIdentityCertificate(const Name& identity, const std::string& filename, bool wantAdd)
|
||||
{
|
||||
ndn::security::v2::Certificate cert;
|
||||
ndn::security::Certificate cert;
|
||||
try {
|
||||
cert = m_keyChain.getPib().getIdentity(identity).getDefaultKey().getDefaultCertificate();
|
||||
}
|
||||
@@ -75,5 +74,4 @@ IdentityManagementFixture::saveIdentityCertificate(const Name& identity, const s
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace tests
|
||||
} // namespace ndn
|
||||
} // namespace ndn::tests
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2017 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2022 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -17,15 +17,14 @@
|
||||
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NDN_TESTS_IDENTITY_MANAGEMENT_FIXTURE_HPP
|
||||
#define NDN_TESTS_IDENTITY_MANAGEMENT_FIXTURE_HPP
|
||||
#ifndef CHRONOSYNC_TESTS_IDENTITY_MANAGEMENT_FIXTURE_HPP
|
||||
#define CHRONOSYNC_TESTS_IDENTITY_MANAGEMENT_FIXTURE_HPP
|
||||
|
||||
#include "common.hpp"
|
||||
#include "detail/common.hpp"
|
||||
|
||||
#include "unit-test-time-fixture.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace tests {
|
||||
namespace ndn::tests {
|
||||
|
||||
/** \brief a fixture that cleans up KeyChain identities and certificate files upon destruction
|
||||
*/
|
||||
@@ -69,7 +68,6 @@ class IdentityManagementTimeFixture : public UnitTestTimeFixture
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace tests
|
||||
} // namespace ndn
|
||||
} // namespace ndn::tests
|
||||
|
||||
#endif // NDN_TESTS_IDENTITY_MANAGEMENT_FIXTURE_HPP
|
||||
#endif // CHRONOSYNC_TESTS_IDENTITY_MANAGEMENT_FIXTURE_HPP
|
||||
|
||||
+8
-102
@@ -1,115 +1,21 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2019, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
* Washington University in St. Louis,
|
||||
* Beijing Institute of Technology,
|
||||
* The University of Memphis.
|
||||
* Copyright (c) 2012-2020 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN, originally developed as part of NFD (Named Data Networking
|
||||
* Forwarding Daemon). See AUTHORS.md for complete list of NFD authors and contributors.
|
||||
* applications for NDN.
|
||||
*
|
||||
* NFD is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
* ChronoSync is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation, either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* ChronoSync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_MODULE ChronoSync
|
||||
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#if BOOST_VERSION >= 106200
|
||||
// Boost.Test v3.3 (Boost 1.62) natively supports multi-logger output
|
||||
#include "tests/boost-test.hpp"
|
||||
#else
|
||||
#define BOOST_TEST_ALTERNATIVE_INIT_API
|
||||
#define BOOST_TEST_NO_MAIN
|
||||
#include "tests/boost-test.hpp"
|
||||
#include "tests/boost-multi-log-formatter.hpp"
|
||||
|
||||
#include <boost/program_options/options_description.hpp>
|
||||
#include <boost/program_options/variables_map.hpp>
|
||||
#include <boost/program_options/parsers.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
static bool
|
||||
init_tests()
|
||||
{
|
||||
init_unit_test();
|
||||
|
||||
namespace po = boost::program_options;
|
||||
namespace ut = boost::unit_test;
|
||||
|
||||
po::options_description extraOptions;
|
||||
std::string logger;
|
||||
std::string outputFile = "-";
|
||||
extraOptions.add_options()
|
||||
("log_format2", po::value<std::string>(&logger), "Type of second log formatter: HRF or XML")
|
||||
("log_sink2", po::value<std::string>(&outputFile)->default_value(outputFile), "Second log sink, - for stdout")
|
||||
;
|
||||
po::variables_map vm;
|
||||
try {
|
||||
po::store(po::command_line_parser(ut::framework::master_test_suite().argc,
|
||||
ut::framework::master_test_suite().argv)
|
||||
.options(extraOptions)
|
||||
.run(),
|
||||
vm);
|
||||
po::notify(vm);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "ERROR: " << e.what() << "\n"
|
||||
<< extraOptions << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (vm.count("log_format2") == 0) {
|
||||
// second logger is not configured
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<ut::unit_test_log_formatter> formatter;
|
||||
if (logger == "XML") {
|
||||
formatter = std::make_shared<ut::output::xml_log_formatter>();
|
||||
}
|
||||
else if (logger == "HRF") {
|
||||
formatter = std::make_shared<ut::output::compiler_log_formatter>();
|
||||
}
|
||||
else {
|
||||
std::cerr << "ERROR: only HRF or XML log formatter can be specified" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<std::ostream> output;
|
||||
if (outputFile == "-") {
|
||||
output = std::shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
|
||||
}
|
||||
else {
|
||||
output = std::make_shared<std::ofstream>(outputFile.c_str());
|
||||
}
|
||||
|
||||
auto multiFormatter = new ut::output::multi_log_formatter;
|
||||
multiFormatter->add(formatter, output);
|
||||
ut::unit_test_log.set_formatter(multiFormatter);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
return ::boost::unit_test::unit_test_main(&init_tests, argc, argv);
|
||||
}
|
||||
|
||||
#endif // BOOST_VERSION >= 106200
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2017 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2023 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -17,15 +17,14 @@
|
||||
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NDN_TESTS_UNIT_TESTS_UNIT_TEST_TIME_FIXTURE_HPP
|
||||
#define NDN_TESTS_UNIT_TESTS_UNIT_TEST_TIME_FIXTURE_HPP
|
||||
#ifndef CHRONOSYNC_TESTS_UNIT_TEST_TIME_FIXTURE_HPP
|
||||
#define CHRONOSYNC_TESTS_UNIT_TEST_TIME_FIXTURE_HPP
|
||||
|
||||
#include <ndn-cxx/util/time-unit-test-clock.hpp>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
|
||||
namespace ndn {
|
||||
namespace tests {
|
||||
namespace ndn::tests {
|
||||
|
||||
class UnitTestTimeFixture
|
||||
{
|
||||
@@ -43,14 +42,15 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
advanceClocks(const time::nanoseconds& tick, size_t nTicks = 1)
|
||||
advanceClocks(time::nanoseconds tick, size_t nTicks = 1)
|
||||
{
|
||||
for (size_t i = 0; i < nTicks; ++i) {
|
||||
steadyClock->advance(tick);
|
||||
systemClock->advance(tick);
|
||||
|
||||
if (io.stopped())
|
||||
io.reset();
|
||||
if (io.stopped()) {
|
||||
io.restart();
|
||||
}
|
||||
io.poll();
|
||||
}
|
||||
}
|
||||
@@ -58,10 +58,9 @@ public:
|
||||
public:
|
||||
shared_ptr<time::UnitTestSteadyClock> steadyClock;
|
||||
shared_ptr<time::UnitTestSystemClock> systemClock;
|
||||
boost::asio::io_service io;
|
||||
boost::asio::io_context io;
|
||||
};
|
||||
|
||||
} // namespace tests
|
||||
} // namespace ndn
|
||||
} // namespace ndn::tests
|
||||
|
||||
#endif // NDN_TESTS_UNIT_TESTS_UNIT_TEST_TIME_FIXTURE_HPP
|
||||
#endif // CHRONOSYNC_TESTS_UNIT_TEST_TIME_FIXTURE_HPP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2019 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2021 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -17,7 +17,7 @@
|
||||
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "bzip2-helper.hpp"
|
||||
#include "detail/bzip2-helper.hpp"
|
||||
|
||||
#include "tests/boost-test.hpp"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2018 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2023 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -19,12 +19,13 @@
|
||||
|
||||
#include "dummy-forwarder.hpp"
|
||||
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/post.hpp>
|
||||
|
||||
namespace ndn {
|
||||
namespace chronosync {
|
||||
|
||||
DummyForwarder::DummyForwarder(boost::asio::io_service& io, KeyChain& keyChain)
|
||||
DummyForwarder::DummyForwarder(boost::asio::io_context& io, KeyChain& keyChain)
|
||||
: m_io(io)
|
||||
, m_keyChain(keyChain)
|
||||
{
|
||||
@@ -33,25 +34,26 @@ DummyForwarder::DummyForwarder(boost::asio::io_service& io, KeyChain& keyChain)
|
||||
Face&
|
||||
DummyForwarder::addFace()
|
||||
{
|
||||
auto face = std::make_shared<util::DummyClientFace>(m_io, m_keyChain,
|
||||
util::DummyClientFace::Options{true, true});
|
||||
util::DummyClientFace* self = &*face; // to prevent memory leak
|
||||
auto face = std::make_shared<DummyClientFace>(m_io, m_keyChain, DummyClientFace::Options{true, true});
|
||||
DummyClientFace* self = &*face; // to prevent memory leak
|
||||
|
||||
face->onSendInterest.connect([this, self] (const Interest& interest) {
|
||||
Interest i(interest);
|
||||
for (auto& otherFace : m_faces) {
|
||||
if (self == &*otherFace) {
|
||||
continue;
|
||||
}
|
||||
m_io.post([=] { otherFace->receive(i); });
|
||||
boost::asio::post(m_io, [=] { otherFace->receive(i); });
|
||||
}
|
||||
});
|
||||
|
||||
face->onSendData.connect([this, self] (const Data& data) {
|
||||
Data d(data);
|
||||
for (auto& otherFace : m_faces) {
|
||||
if (self == &*otherFace) {
|
||||
continue;
|
||||
}
|
||||
m_io.post([=] { otherFace->receive(d); });
|
||||
boost::asio::post(m_io, [=] { otherFace->receive(d); });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -61,7 +63,7 @@ DummyForwarder::addFace()
|
||||
if (self == &*otherFace) {
|
||||
continue;
|
||||
}
|
||||
m_io.post([=] { otherFace->receive(n); });
|
||||
boost::asio::post(m_io, [=] { otherFace->receive(n); });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2018 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2023 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -17,11 +17,11 @@
|
||||
* ChronoSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <ndn-cxx/interest.hpp>
|
||||
#include <ndn-cxx/data.hpp>
|
||||
#include <ndn-cxx/interest.hpp>
|
||||
#include <ndn-cxx/lp/nack.hpp>
|
||||
#include <ndn-cxx/util/dummy-client-face.hpp>
|
||||
#include <ndn-cxx/security/key-chain.hpp>
|
||||
#include <ndn-cxx/util/dummy-client-face.hpp>
|
||||
|
||||
#ifndef NDN_CHRONOSYNC_UNIT_TESTS_DUMMY_FORWARDER_HPP
|
||||
#define NDN_CHRONOSYNC_UNIT_TESTS_DUMMY_FORWARDER_HPP
|
||||
@@ -38,7 +38,7 @@ namespace chronosync {
|
||||
class DummyForwarder
|
||||
{
|
||||
public:
|
||||
DummyForwarder(boost::asio::io_service& io, KeyChain& keyChain);
|
||||
DummyForwarder(boost::asio::io_context& io, KeyChain& keyChain);
|
||||
|
||||
Face&
|
||||
addFace();
|
||||
@@ -53,9 +53,9 @@ public:
|
||||
removeFaces();
|
||||
|
||||
private:
|
||||
boost::asio::io_service& m_io;
|
||||
boost::asio::io_context& m_io;
|
||||
KeyChain& m_keyChain;
|
||||
std::vector<shared_ptr<util::DummyClientFace>> m_faces;
|
||||
std::vector<std::shared_ptr<DummyClientFace>> m_faces;
|
||||
};
|
||||
|
||||
} // namespace chronosync
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2019 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2022 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -32,24 +32,24 @@ class InterestTableFixture : public ndn::tests::UnitTestTimeFixture
|
||||
public:
|
||||
InterestTableFixture()
|
||||
{
|
||||
uint8_t origin[4] = {0x01, 0x02, 0x03, 0x04};
|
||||
const uint8_t origin[] = {0x01, 0x02, 0x03, 0x04};
|
||||
Name prefix("/test/prefix");
|
||||
|
||||
Name interestName1;
|
||||
digest1 = ndn::util::Sha256::computeDigest(origin, 1);
|
||||
digest1 = ndn::util::Sha256::computeDigest({origin, 1});
|
||||
interestName1.append(prefix).append(name::Component(digest1));
|
||||
|
||||
interest1 = Interest(interestName1);
|
||||
interest1.setInterestLifetime(time::milliseconds(100));
|
||||
|
||||
Name interestName2;
|
||||
digest2 = ndn::util::Sha256::computeDigest(origin, 2);
|
||||
digest2 = ndn::util::Sha256::computeDigest({origin, 2});
|
||||
interestName2.append(prefix).append(name::Component(digest2));
|
||||
interest2 = Interest(interestName2);
|
||||
interest2.setInterestLifetime(time::milliseconds(100));
|
||||
|
||||
Name interestName3;
|
||||
digest3 = ndn::util::Sha256::computeDigest(origin, 3);
|
||||
digest3 = ndn::util::Sha256::computeDigest({origin, 3});
|
||||
interestName3.append(prefix).append(name::Component(digest3));
|
||||
interest3 = Interest(interestName3);
|
||||
interest3.setInterestLifetime(time::milliseconds(100));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2019 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2022 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -54,10 +54,7 @@ BOOST_AUTO_TEST_CASE(LeafDigest)
|
||||
Name userPrefix("/test/name");
|
||||
Leaf leaf(userPrefix, 1, 10);
|
||||
|
||||
BOOST_CHECK_NO_THROW(leaf.getDigest());
|
||||
|
||||
ndn::ConstBufferPtr digest = leaf.getDigest();
|
||||
BOOST_CHECK_EQUAL(result, ndn::toHex(digest->data(), digest->size(), false));
|
||||
BOOST_CHECK_EQUAL(result, ndn::toHex(*leaf.getDigest(), false));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Container)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2019 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2023 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "logic.hpp"
|
||||
#include "bzip2-helper.hpp"
|
||||
#include "detail/bzip2-helper.hpp"
|
||||
|
||||
#include "tests/boost-test.hpp"
|
||||
#include "tests/identity-management-fixture.hpp"
|
||||
@@ -29,17 +29,11 @@
|
||||
namespace chronosync {
|
||||
namespace test {
|
||||
|
||||
using ndn::chronosync::DummyForwarder;
|
||||
|
||||
class Handler
|
||||
{
|
||||
public:
|
||||
Handler(ndn::Face& face,
|
||||
const Name& syncPrefix,
|
||||
const Name& userPrefix)
|
||||
: logic(face,
|
||||
syncPrefix,
|
||||
userPrefix,
|
||||
Handler(ndn::Face& face, const Name& syncPrefix, const Name& userPrefix)
|
||||
: logic(face, syncPrefix, userPrefix,
|
||||
bind(&Handler::onUpdate, this, _1))
|
||||
{
|
||||
}
|
||||
@@ -87,7 +81,7 @@ public:
|
||||
Name syncPrefix;
|
||||
Name userPrefix[4];
|
||||
|
||||
DummyForwarder fw;
|
||||
ndn::chronosync::DummyForwarder fw;
|
||||
// std::unique_ptr<DummyClientFace> faces[4];
|
||||
shared_ptr<Handler> handler[4];
|
||||
|
||||
@@ -98,7 +92,7 @@ public:
|
||||
BOOST_FIXTURE_TEST_SUITE(LogicTests, LogicFixture)
|
||||
|
||||
static void
|
||||
onUpdate(const std::vector<MissingDataInfo>& v)
|
||||
onUpdate(const std::vector<MissingDataInfo>&)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -106,7 +100,7 @@ BOOST_AUTO_TEST_CASE(Constructor)
|
||||
{
|
||||
Name syncPrefix("/ndn/broadcast/sync");
|
||||
Name userPrefix("/user");
|
||||
ndn::util::DummyClientFace face(io, {true, true});
|
||||
ndn::DummyClientFace face(io, {true, true});
|
||||
BOOST_REQUIRE_NO_THROW(Logic(face, syncPrefix, userPrefix, bind(onUpdate, _1)));
|
||||
}
|
||||
|
||||
@@ -369,14 +363,14 @@ BOOST_AUTO_TEST_CASE(CancelOutstandingEvents)
|
||||
systemClock->advance(ndn::time::hours(1));
|
||||
|
||||
BOOST_CHECK_EQUAL(io.poll(), 0); // no delayed handlers are expected
|
||||
BOOST_CHECK_EQUAL(io.stopped(), true); // io_service expected to be stopped
|
||||
BOOST_CHECK_EQUAL(io.stopped(), true); // io_context expected to be stopped
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(TrimState, ndn::tests::IdentityManagementTimeFixture)
|
||||
{
|
||||
Name syncPrefix("/ndn/broadcast/sync");
|
||||
Name userPrefix("/user");
|
||||
ndn::util::DummyClientFace face;
|
||||
ndn::DummyClientFace face;
|
||||
Logic logic(face, syncPrefix, userPrefix, bind(onUpdate, _1));
|
||||
|
||||
State state;
|
||||
@@ -403,11 +397,11 @@ BOOST_FIXTURE_TEST_CASE(VeryLargeState, ndn::tests::IdentityManagementTimeFixtur
|
||||
addIdentity("/bla");
|
||||
Name syncPrefix("/ndn/broadcast/sync");
|
||||
Name userPrefix("/user");
|
||||
ndn::util::DummyClientFace face;
|
||||
ndn::DummyClientFace face;
|
||||
Logic logic(face, syncPrefix, userPrefix, bind(onUpdate, _1));
|
||||
|
||||
State state;
|
||||
for (size_t i = 0; i < 50000 && bzip2::compress(reinterpret_cast<const char*>(state.wireEncode().wire()),
|
||||
for (size_t i = 0; i < 50000 && bzip2::compress(reinterpret_cast<const char*>(state.wireEncode().data()),
|
||||
state.wireEncode().size())->size() < ndn::MAX_NDN_PACKET_SIZE;
|
||||
i += 10) {
|
||||
Name prefix("/to/trim");
|
||||
@@ -438,12 +432,12 @@ public:
|
||||
{
|
||||
unsetenv("CHRONOSYNC_MAX_PACKET_SIZE");
|
||||
if (oldSize) {
|
||||
setenv("CHRONOSYNC_MAX_PACKET_SIZE", oldSize->c_str(), 1);
|
||||
setenv("CHRONOSYNC_MAX_PACKET_SIZE", oldSize->data(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ndn::optional<std::string> oldSize;
|
||||
std::optional<std::string> oldSize;
|
||||
};
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(MaxPacketCustomization, MaxPacketCustomizationFixture)
|
||||
@@ -453,7 +447,7 @@ BOOST_FIXTURE_TEST_CASE(MaxPacketCustomization, MaxPacketCustomizationFixture)
|
||||
setenv("CHRONOSYNC_MAX_PACKET_SIZE", "1500", 1);
|
||||
BOOST_CHECK_EQUAL(getMaxPacketLimit(), 1500);
|
||||
|
||||
setenv("CHRONOSYNC_MAX_PACKET_SIZE", ndn::to_string(ndn::MAX_NDN_PACKET_SIZE * 100).c_str(), 1);
|
||||
setenv("CHRONOSYNC_MAX_PACKET_SIZE", std::to_string(ndn::MAX_NDN_PACKET_SIZE * 100).data(), 1);
|
||||
BOOST_CHECK_EQUAL(getMaxPacketLimit(), ndn::MAX_NDN_PACKET_SIZE);
|
||||
|
||||
setenv("CHRONOSYNC_MAX_PACKET_SIZE", "1", 1);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2019 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2023 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -27,18 +27,8 @@ namespace test {
|
||||
class Handler
|
||||
{
|
||||
public:
|
||||
Handler(ndn::Face& face,
|
||||
const Name& syncPrefix,
|
||||
const Name& userPrefix)
|
||||
: logic(face,
|
||||
syncPrefix,
|
||||
userPrefix,
|
||||
bind(&Handler::onUpdate, this, _1))
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
onUpdate(const std::vector<MissingDataInfo>& v)
|
||||
Handler(ndn::Face& face, const Name& syncPrefix, const Name& userPrefix)
|
||||
: logic(face, syncPrefix, userPrefix, [] (auto&&...) {})
|
||||
{
|
||||
}
|
||||
|
||||
@@ -76,13 +66,13 @@ public:
|
||||
userPrefix[1] = Name("/user1");
|
||||
userPrefix[2] = Name("/user2");
|
||||
|
||||
face = make_shared<ndn::Face>(ref(io));
|
||||
face = std::make_shared<ndn::Face>(io);
|
||||
}
|
||||
|
||||
Name syncPrefix;
|
||||
Name userPrefix[3];
|
||||
|
||||
boost::asio::io_service io;
|
||||
boost::asio::io_context io;
|
||||
shared_ptr<ndn::Face> face;
|
||||
ndn::Scheduler scheduler;
|
||||
shared_ptr<Handler> handler;
|
||||
@@ -92,7 +82,7 @@ BOOST_FIXTURE_TEST_SUITE(MultiUserTests, MultiUserFixture)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ThreeUserNode)
|
||||
{
|
||||
handler = make_shared<Handler>(ref(*face), syncPrefix, userPrefix[0]);
|
||||
handler = std::make_shared<Handler>(*face, syncPrefix, userPrefix[0]);
|
||||
handler->addUserNode(userPrefix[1]);
|
||||
handler->addUserNode(userPrefix[2]);
|
||||
handler->removeUserNode(userPrefix[0]);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2019 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2023 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -28,7 +28,6 @@ namespace chronosync {
|
||||
namespace test {
|
||||
|
||||
using std::string;
|
||||
using ndn::util::DummyClientFace;
|
||||
|
||||
/**
|
||||
* @brief Emulate an app that use the Socket class
|
||||
@@ -41,14 +40,14 @@ class SocketTestApp : noncopyable
|
||||
public:
|
||||
SocketTestApp(const Name& syncPrefix,
|
||||
const Name& userPrefix,
|
||||
DummyClientFace& face,
|
||||
ndn::DummyClientFace& face,
|
||||
bool isNum)
|
||||
: sum(0)
|
||||
, socket(syncPrefix,
|
||||
userPrefix,
|
||||
face,
|
||||
isNum ? bind(&SocketTestApp::fetchNumbers, this, _1) :
|
||||
bind(&SocketTestApp::fetchAll, this, _1),
|
||||
bind(&SocketTestApp::fetchAll, this, _1),
|
||||
Logic::DEFAULT_NAME,
|
||||
Logic::DEFAULT_VALIDATOR,
|
||||
Logic::DEFAULT_SYNC_INTEREST_LIFETIME,
|
||||
@@ -63,14 +62,14 @@ public:
|
||||
Name dataName(dataPacket.getName());
|
||||
string str2(reinterpret_cast<const char*>(dataPacket.getContent().value()),
|
||||
dataPacket.getContent().value_size());
|
||||
data.insert(make_pair(dataName, str2));
|
||||
data.emplace(dataName, str2);
|
||||
}
|
||||
|
||||
void
|
||||
set(Name name, const char* buf, int len)
|
||||
{
|
||||
string str2(buf, len);
|
||||
data.insert(make_pair(name, str2));
|
||||
data.emplace(name, str2);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -139,7 +138,7 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
std::map<ndn::Name, string> data;
|
||||
std::map<Name, string> data;
|
||||
uint32_t sum;
|
||||
Socket socket;
|
||||
};
|
||||
@@ -155,9 +154,9 @@ public:
|
||||
userPrefix[1] = Name("/user1");
|
||||
userPrefix[2] = Name("/user2");
|
||||
|
||||
faces[0].reset(new DummyClientFace(io, {true, true}));
|
||||
faces[1].reset(new DummyClientFace(io, {true, true}));
|
||||
faces[2].reset(new DummyClientFace(io, {true, true}));
|
||||
faces[0].reset(new ndn::DummyClientFace(io, {true, true}));
|
||||
faces[1].reset(new ndn::DummyClientFace(io, {true, true}));
|
||||
faces[2].reset(new ndn::DummyClientFace(io, {true, true}));
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
readInterestOffset[i] = 0;
|
||||
@@ -194,7 +193,7 @@ public:
|
||||
void
|
||||
createSocket(size_t idx, bool isNum)
|
||||
{
|
||||
app[idx] = make_shared<SocketTestApp>(syncPrefix, userPrefix[idx], ref(*faces[idx]), isNum);
|
||||
app[idx] = make_shared<SocketTestApp>(syncPrefix, userPrefix[idx], std::ref(*faces[idx]), isNum);
|
||||
sessionName[idx] = app[idx]->socket.getLogic().getSessionName();
|
||||
}
|
||||
|
||||
@@ -239,7 +238,7 @@ public:
|
||||
Name userPrefix[3];
|
||||
Name sessionName[3];
|
||||
|
||||
std::unique_ptr<DummyClientFace> faces[3];
|
||||
std::unique_ptr<ndn::DummyClientFace> faces[3];
|
||||
shared_ptr<SocketTestApp> app[3];
|
||||
|
||||
size_t readInterestOffset[3];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* Copyright (c) 2012-2019 University of California, Los Angeles
|
||||
* Copyright (c) 2012-2022 University of California, Los Angeles
|
||||
*
|
||||
* This file is part of ChronoSync, synchronization library for distributed realtime
|
||||
* applications for NDN.
|
||||
@@ -148,17 +148,16 @@ BOOST_AUTO_TEST_CASE(DecodeEncode)
|
||||
0x04
|
||||
};
|
||||
|
||||
Block block(wire, sizeof(wire));
|
||||
Block block(wire);
|
||||
State state;
|
||||
BOOST_REQUIRE_NO_THROW(state.wireDecode(block));
|
||||
|
||||
BOOST_CHECK_EQUAL(state.getLeaves().size(), 2);
|
||||
LeafContainer::index<ordered>::type::iterator it = state.getLeaves().get<ordered>().begin();
|
||||
auto it = state.getLeaves().get<ordered>().begin();
|
||||
BOOST_CHECK_EQUAL((*it)->getSeq(), 14);
|
||||
it++;
|
||||
BOOST_CHECK_EQUAL((*it)->getSeq(), 4);
|
||||
|
||||
|
||||
State state2;
|
||||
|
||||
Name info1("/test/name");
|
||||
@@ -169,15 +168,9 @@ BOOST_AUTO_TEST_CASE(DecodeEncode)
|
||||
info2.appendNumber(1);
|
||||
state2.update(info2, 4);
|
||||
|
||||
BOOST_REQUIRE_NO_THROW(state2.wireEncode());
|
||||
Block block2 = state2.wireEncode();
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(block.wire(),
|
||||
block.wire() + block.size(),
|
||||
block2.wire(),
|
||||
block2.wire() + block2.size());
|
||||
|
||||
BOOST_CHECK(*state.getRootDigest() == *state2.getRootDigest());
|
||||
BOOST_TEST(block == block2, boost::test_tools::per_element());
|
||||
BOOST_TEST(*state.getRootDigest() == *state2.getRootDigest(), boost::test_tools::per_element());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Combine)
|
||||
@@ -208,7 +201,7 @@ BOOST_AUTO_TEST_CASE(Combine)
|
||||
BOOST_CHECK_EQUAL(state1.getLeaves().size(), 2);
|
||||
BOOST_CHECK_EQUAL(state2.getLeaves().size(), 3);
|
||||
|
||||
LeafContainer::index<ordered>::type::iterator it = state2.getLeaves().get<ordered>().begin();
|
||||
auto it = state2.getLeaves().get<ordered>().begin();
|
||||
BOOST_CHECK_EQUAL((*it)->getSeq(), 4);
|
||||
it++;
|
||||
BOOST_CHECK_EQUAL((*it)->getSeq(), 15);
|
||||
|
||||
+7
-5
@@ -3,8 +3,10 @@
|
||||
top = '..'
|
||||
|
||||
def build(bld):
|
||||
bld.program(target='../unit-tests',
|
||||
name='unit-tests',
|
||||
source=bld.path.ant_glob('**/*.cpp'),
|
||||
use='ChronoSync',
|
||||
install_path=None)
|
||||
bld.program(
|
||||
target=f'{top}/unit-tests',
|
||||
name='unit-tests',
|
||||
source=bld.path.ant_glob('**/*.cpp'),
|
||||
use='BOOST_TESTS ChronoSync',
|
||||
includes=top,
|
||||
install_path=None)
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
from waflib import Context, Logs, Utils
|
||||
import os, subprocess
|
||||
import os
|
||||
import subprocess
|
||||
from waflib import Context, Logs
|
||||
|
||||
VERSION = '0.5.3'
|
||||
VERSION = '0.5.5'
|
||||
APPNAME = 'ChronoSync'
|
||||
GIT_TAG_PREFIX = ''
|
||||
|
||||
def options(opt):
|
||||
opt.load(['compiler_c', 'compiler_cxx', 'gnu_dirs'])
|
||||
opt.load(['default-compiler-flags', 'boost', 'doxygen', 'sphinx_build',
|
||||
'coverage', 'sanitizers'],
|
||||
opt.load(['compiler_cxx', 'gnu_dirs'])
|
||||
opt.load(['default-compiler-flags',
|
||||
'coverage', 'sanitizers', 'boost',
|
||||
'doxygen', 'sphinx_build'],
|
||||
tooldir=['.waf-tools'])
|
||||
|
||||
optgrp = opt.add_option_group('ChronoSync Options')
|
||||
@@ -18,20 +20,31 @@ def options(opt):
|
||||
help='Build unit tests')
|
||||
|
||||
def configure(conf):
|
||||
conf.load(['compiler_c', 'compiler_cxx', 'gnu_dirs',
|
||||
conf.load(['compiler_cxx', 'gnu_dirs',
|
||||
'default-compiler-flags', 'boost',
|
||||
'doxygen', 'sphinx_build'])
|
||||
|
||||
conf.env.WITH_TESTS = conf.options.with_tests
|
||||
|
||||
conf.check_cfg(package='libndn-cxx', args=['--cflags', '--libs'], uselib_store='NDN_CXX',
|
||||
pkg_config_path=os.environ.get('PKG_CONFIG_PATH', '%s/pkgconfig' % conf.env.LIBDIR))
|
||||
conf.find_program('dot', mandatory=False)
|
||||
|
||||
# Prefer pkgconf if it's installed, because it gives more correct results
|
||||
# on Fedora/CentOS/RHEL/etc. See https://bugzilla.redhat.com/show_bug.cgi?id=1953348
|
||||
# Store the result in env.PKGCONFIG, which is the variable used inside check_cfg()
|
||||
conf.find_program(['pkgconf', 'pkg-config'], var='PKGCONFIG')
|
||||
|
||||
pkg_config_path = os.environ.get('PKG_CONFIG_PATH', f'{conf.env.LIBDIR}/pkgconfig')
|
||||
conf.check_cfg(package='libndn-cxx', args=['libndn-cxx >= 0.8.1', '--cflags', '--libs'],
|
||||
uselib_store='NDN_CXX', pkg_config_path=pkg_config_path)
|
||||
|
||||
conf.check_boost(lib='iostreams', mt=True)
|
||||
if conf.env.BOOST_VERSION_NUMBER < 107100:
|
||||
conf.fatal('The minimum supported version of Boost is 1.71.0.\n'
|
||||
'Please upgrade your distribution or manually install a newer version of Boost.\n'
|
||||
'For more information, see https://redmine.named-data.net/projects/nfd/wiki/Boost')
|
||||
|
||||
boost_libs = ['system', 'iostreams']
|
||||
if conf.env.WITH_TESTS:
|
||||
boost_libs.append('unit_test_framework')
|
||||
|
||||
conf.check_boost(lib=boost_libs, mt=True)
|
||||
conf.check_boost(lib='filesystem unit_test_framework', mt=True, uselib_store='BOOST_TESTS')
|
||||
|
||||
conf.check_compiler_flags()
|
||||
|
||||
@@ -44,36 +57,33 @@ def configure(conf):
|
||||
# system has a different version of the ChronoSync library installed.
|
||||
conf.env.prepend_value('STLIBPATH', ['.'])
|
||||
|
||||
conf.define_cond('CHRONOSYNC_HAVE_TESTS', conf.env.WITH_TESTS)
|
||||
conf.define_cond('WITH_TESTS', conf.env.WITH_TESTS)
|
||||
# The config header will contain all defines that were added using conf.define()
|
||||
# or conf.define_cond(). Everything that was added directly to conf.env.DEFINES
|
||||
# will not appear in the config header, but will instead be passed directly to the
|
||||
# compiler on the command line.
|
||||
conf.write_config_header('config.hpp')
|
||||
conf.write_config_header('src/detail/config.hpp', define_prefix='CHRONOSYNC_')
|
||||
|
||||
def build(bld):
|
||||
bld.shlib(target='ChronoSync',
|
||||
vnum=VERSION,
|
||||
cnum=VERSION,
|
||||
source=bld.path.ant_glob('src/**/*.cpp'),
|
||||
use='NDN_CXX BOOST',
|
||||
includes='src .',
|
||||
export_includes='src .')
|
||||
bld.shlib(
|
||||
target='ChronoSync',
|
||||
vnum=VERSION,
|
||||
cnum=VERSION,
|
||||
source=bld.path.ant_glob('src/**/*.cpp'),
|
||||
use='BOOST NDN_CXX',
|
||||
includes='src/detail',
|
||||
export_includes='src src/detail')
|
||||
|
||||
if bld.env.WITH_TESTS:
|
||||
bld.recurse('tests')
|
||||
|
||||
bld.install_files(
|
||||
dest = '%s/ChronoSync' % bld.env.INCLUDEDIR,
|
||||
files = bld.path.ant_glob(['src/*.hpp', 'common.hpp']),
|
||||
cwd = bld.path.find_dir('src'),
|
||||
relative_trick = False)
|
||||
|
||||
bld.install_files(
|
||||
dest = '%s/ChronoSync' % bld.env.INCLUDEDIR,
|
||||
files = bld.path.get_bld().ant_glob(['src/*.hpp', 'common.hpp', 'config.hpp']),
|
||||
cwd = bld.path.get_bld().find_dir('src'),
|
||||
relative_trick = False)
|
||||
# Install header files
|
||||
srcdir = bld.path.find_dir('src')
|
||||
bld.install_files('${INCLUDEDIR}/ChronoSync',
|
||||
srcdir.ant_glob('**/*.hpp'),
|
||||
cwd=srcdir,
|
||||
relative_trick=True)
|
||||
bld.install_files('${INCLUDEDIR}/ChronoSync/detail', 'src/detail/config.hpp')
|
||||
|
||||
bld(features='subst',
|
||||
source='ChronoSync.pc.in',
|
||||
@@ -98,6 +108,7 @@ def doxygen(bld):
|
||||
target=['docs/doxygen.conf',
|
||||
'docs/named_data_theme/named_data_footer-with-analytics.html'],
|
||||
VERSION=VERSION,
|
||||
HAVE_DOT='YES' if bld.env.DOT else 'NO',
|
||||
HTML_FOOTER='../build/docs/named_data_theme/named_data_footer-with-analytics.html' \
|
||||
if os.getenv('GOOGLE_ANALYTICS', None) \
|
||||
else '../docs/named_data_theme/named_data_footer.html',
|
||||
@@ -131,19 +142,19 @@ def version(ctx):
|
||||
# first, try to get a version string from git
|
||||
gotVersionFromGit = False
|
||||
try:
|
||||
cmd = ['git', 'describe', '--always', '--match', '%s*' % GIT_TAG_PREFIX]
|
||||
out = subprocess.check_output(cmd, universal_newlines=True).strip()
|
||||
cmd = ['git', 'describe', '--always', '--match', f'{GIT_TAG_PREFIX}*']
|
||||
out = subprocess.run(cmd, capture_output=True, check=True, text=True).stdout.strip()
|
||||
if out:
|
||||
gotVersionFromGit = True
|
||||
if out.startswith(GIT_TAG_PREFIX):
|
||||
Context.g_module.VERSION = out.lstrip(GIT_TAG_PREFIX)
|
||||
else:
|
||||
# no tags matched
|
||||
Context.g_module.VERSION = '%s-commit-%s' % (VERSION_BASE, out)
|
||||
except (OSError, subprocess.CalledProcessError):
|
||||
Context.g_module.VERSION = f'{VERSION_BASE}-commit-{out}'
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
pass
|
||||
|
||||
versionFile = ctx.path.find_node('VERSION')
|
||||
versionFile = ctx.path.find_node('VERSION.info')
|
||||
if not gotVersionFromGit and versionFile is not None:
|
||||
try:
|
||||
Context.g_module.VERSION = versionFile.read()
|
||||
@@ -158,17 +169,19 @@ def version(ctx):
|
||||
# already up-to-date
|
||||
return
|
||||
except EnvironmentError as e:
|
||||
Logs.warn('%s exists but is not readable (%s)' % (versionFile, e.strerror))
|
||||
Logs.warn(f'{versionFile} exists but is not readable ({e.strerror})')
|
||||
else:
|
||||
versionFile = ctx.path.make_node('VERSION')
|
||||
versionFile = ctx.path.make_node('VERSION.info')
|
||||
|
||||
try:
|
||||
versionFile.write(Context.g_module.VERSION)
|
||||
except EnvironmentError as e:
|
||||
Logs.warn('%s is not writable (%s)' % (versionFile, e.strerror))
|
||||
Logs.warn(f'{versionFile} is not writable ({e.strerror})')
|
||||
|
||||
def dist(ctx):
|
||||
ctx.algo = 'tar.xz'
|
||||
version(ctx)
|
||||
|
||||
def distcheck(ctx):
|
||||
ctx.algo = 'tar.xz'
|
||||
version(ctx)
|
||||
|
||||
Reference in New Issue
Block a user