Skip to content

Merge release 1.2.0 from fork #36

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ compile_commands.json
perf.data*
build

/cmake-build-debug/
31 changes: 29 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,33 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]
Nothing yet.
### Changed
- Nothing yet

## [1.2.0] - 2022-04-14
### Changed
- Bugfix: FilterSphere was not working correctly. [#27](https://github.com/tzaeschke/phtree-cpp/issues/27)
- Potentially **BREAKING CHANGE**: Refactored API of all methods that accept callbacks and filters to
accept universal/forwarding references.
Also changed filters and callback to not require `const` methods.
[#22](https://github.com/tzaeschke/phtree-cpp/issues/22)
- Clean up iterator implementations. [#19](https://github.com/tzaeschke/phtree-cpp/issues/19)
- Make PhTree and PhTreeMultimap movable (move-assign/copy). [#18](https://github.com/tzaeschke/phtree-cpp/issues/18)
- Potentially **BREAKING CHANGE** when using `IsNodeValid()` in provided filters:
Changed `bit_width_t` from `uin16_t` to `uint32_t`. This improves performance of 3D insert/emplace
on small datasets by up to 15%. To avoid warnings that meant that the API of `FilterAABB` and `FilterSphere`
had to be changed to accept `uint32_t` instead of `int`. This may break some implementations.
[#17](https://github.com/tzaeschke/phtree-cpp/pull/17)
- DIM>8 now uses custom b_plus_tree_map instead of std::map. This improves performance for all operations, e.g.
window queries on large datasets are up to 4x faster. Benchmarks results can be found in the issue.
[#14](https://github.com/tzaeschke/phtree-cpp/issues/14)
- postfix/infix field moved from Node to Entry. This avoids indirections and improves performance of most by ~10%.
operations by 5-15%. [#11](https://github.com/tzaeschke/phtree-cpp/issues/11)
- Entries now use 'union' to store children. [#9](https://github.com/tzaeschke/phtree-cpp/issues/9)
- Avoid unnecessary find() when removing a node. [#5](https://github.com/tzaeschke/phtree-cpp/issues/5)
- Avoid unnecessary key copy when inserting a node. [#4](https://github.com/tzaeschke/phtree-cpp/issues/4)
- for_each(callback, filter) was traversing too many nodes. [#2](https://github.com/tzaeschke/phtree-cpp/issues/2)
- Build improvements for bazel/cmake

## [1.1.1] - 2022-01-30
### Changed
Expand Down Expand Up @@ -70,7 +96,8 @@ Nothing yet.
- Nothing.


[Unreleased]: https://github.com/improbable-eng/phtree-cpp/compare/v1.1.1...HEAD
[Unreleased]: https://github.com/improbable-eng/phtree-cpp/compare/v1.2.0...HEAD
[1.2.0]: https://github.com/improbable-eng/phtree-cpp/compare/v1.2.0...v1.1.0
[1.1.1]: https://github.com/improbable-eng/phtree-cpp/compare/v1.1.0...v1.1.1
[1.1.0]: https://github.com/improbable-eng/phtree-cpp/compare/v1.0.0...v1.1.0
[1.0.1]: https://github.com/improbable-eng/phtree-cpp/compare/v1.0.0...v1.0.1
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.14)

# set the project name
project(PH_Tree_Main VERSION 1.1.1
project(PH_Tree_Main VERSION 1.2.0
DESCRIPTION "PH-Tree C++"
LANGUAGES CXX)

Expand Down
1 change: 1 addition & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@
identification within third-party archives.

Copyright 2020 Improbable Worlds Limited
Copyright 2022 Tilmann Zäschke

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
**Note: for updates please also check the [fork](https://github.com/tzaeschke/phtree-cpp) by the original PH-Tree developer.**
**This is a fork of [Improbable's PH-tree](https://github.com/improbable-eng/phtree-cpp)**.

# PH-Tree C++

Expand Down Expand Up @@ -128,9 +128,10 @@ tree.estimate_count(query);

#### Queries

* For-each over all elements: `tree.fore_each(callback);`
* For-each over all elements: `tree.for_each(callback);`
**Note that `for_each` tends to be 10%-20% faster than using an iterator.**
* Iterator over all elements: `auto iterator = tree.begin();`
* For-each with box shaped window queries: `tree.fore_each(PhBoxD(min, max), callback);`
* For-each with box shaped window queries: `tree.for_each(PhBoxD(min, max), callback);`
* Iterator for box shaped window queries: `auto q = tree.begin_query(PhBoxD(min, max));`
* Iterator for _k_ nearest neighbor queries: `auto q = tree.begin_knn_query(k, center_point, distance_function);`
* Custom query shapes, such as spheres: `tree.for_each(callback, FilterSphere(center, radius, tree.converter()));`
Expand Down Expand Up @@ -432,7 +433,7 @@ heavily on the actual dataset, usage patterns, hardware, ... .

There are numerous ways to improve performance. The following list gives an overview over the possibilities.

1) **Use `for_each` instead of iterators**. This should improve performance of queries by 5%-10%.
1) **Use `for_each` instead of iterators**. This should improve performance of queries by 10%-20%.

2) **Use `emplace_hint` if possible**. When updating the position of an entry, the naive way is to use `erase()`
/`emplace()`. With `emplace_hint`, insertion can avoid navigation to the target node if the insertion coordinate is
Expand Down
76 changes: 76 additions & 0 deletions TODO.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
Fix const-ness
==============
- operator[] should have a const overload
- find() should have a non-const overload
- test:

TEST(PhTreeTest, SmokeTestConstTree) {
// Test edge case: only one entry in tree
PhPoint<3> p{1, 2, 3};
TestTree<3, Id> tree1;
tree1.emplace(p, Id{1});
tree1.emplace(p, Id{2});
Id id3{3};
tree1.insert(p, id3);
Id id4{4};
tree1.insert(p, id4);
const auto& tree = tree1;
ASSERT_EQ(tree.size(), 1);
ASSERT_EQ(tree.find(p).second()._i, 1);
ASSERT_EQ(tree[p]._i, 1);

auto q_window = tree.begin_query({p, p});
ASSERT_EQ(1, q_window->_i);
++q_window;
ASSERT_EQ(q_window, tree.end());

auto q_extent = tree.begin();
ASSERT_EQ(1, q_extent->_i);
++q_extent;
ASSERT_EQ(q_extent, tree.end());

auto q_knn = tree.begin_knn_query(10, p, DistanceEuclidean<3>());
ASSERT_EQ(1, q_knn->_i);
++q_knn;
ASSERT_EQ(q_knn, tree.end());

ASSERT_EQ(1, tree1.erase(p));
ASSERT_EQ(0, tree.size());
ASSERT_EQ(0, tree1.erase(p));
ASSERT_EQ(0, tree.size());
ASSERT_TRUE(tree.empty());
}


b_plus_tree_map - binary search
===============
Use custom binary search:

// return BptEntry* ?!?!?
template <typename E>
[[nodiscard]] auto lower_bound(key_t key, std::vector<E>& data) noexcept {
return std::lower_bound(data.begin(), data.end(), key, [](E& left, const key_t key) {
return left.first < key;
});
// auto pos = __lower_bound(&*data_leaf_.begin(), &*data_leaf_.end(), key);
// return data_leaf_.begin() + pos;
}

template <typename TT>
inline auto __lower_bound(const TT* __first, const TT* __last, key_t __val) const noexcept {
const TT* const_first = __first;
auto __len = __last - __first;

while (__len > 0) {
auto __half = __len >> 1;
const TT* __middle = __first + __half;
if (__middle->first < __val) {
__first = __middle;
++__first;
__len = __len - __half - 1;
} else
__len = __half;
}
return __first - const_first;
}

14 changes: 7 additions & 7 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ http_archive(
load("@bazel_skylib//lib:versions.bzl", "versions")

versions.check(
minimum_bazel_version = "4.2.2",
minimum_bazel_version = "3.0.0",
maximum_bazel_version = "4.2.2",
)

Expand All @@ -34,17 +34,17 @@ http_archive(

http_archive(
name = "gbenchmark",
sha256 = "dccbdab796baa1043f04982147e67bb6e118fe610da2c65f88912d73987e700c",
strip_prefix = "benchmark-1.5.2",
url = "https://github.com/google/benchmark/archive/v1.5.2.tar.gz",
sha256 = "6132883bc8c9b0df5375b16ab520fac1a85dc9e4cf5be59480448ece74b278d4",
strip_prefix = "benchmark-1.6.1",
url = "https://github.com/google/benchmark/archive/v1.6.1.tar.gz",
)

http_archive(
name = "gtest",
build_file = "@third_party//gtest:BUILD",
sha256 = "9dc9157a9a1551ec7a7e43daea9a694a0bb5fb8bec81235d8a1e6ef64c716dcb",
strip_prefix = "googletest-release-1.10.0",
url = "https://github.com/google/googletest/archive/release-1.10.0.tar.gz",
sha256 = "b4870bf121ff7795ba20d20bcdd8627b8e088f2d1dab299a031c1034eddc93d5",
strip_prefix = "googletest-release-1.11.0",
url = "https://github.com/google/googletest/archive/release-1.11.0.tar.gz",
)

# Development environment tooling
Expand Down
13 changes: 13 additions & 0 deletions phtree/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,19 @@ cc_test(
],
)

cc_test(
name = "phtree_multimap_d_test_filter",
timeout = "long",
srcs = [
"phtree_multimap_d_test_filter.cc",
],
linkstatic = True,
deps = [
":phtree",
"//phtree/testing/gtest_main",
],
)

cc_test(
name = "phtree_d_test_custom_key",
timeout = "long",
Expand Down
60 changes: 60 additions & 0 deletions phtree/benchmark/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -304,3 +304,63 @@ cc_binary(
"@spdlog",
],
)

cc_binary(
name = "hd_insert_d_benchmark",
testonly = True,
srcs = [
"hd_insert_d_benchmark.cc",
],
linkstatic = True,
deps = [
"//phtree",
"//phtree/benchmark",
"@gbenchmark//:benchmark",
"@spdlog",
],
)

cc_binary(
name = "hd_erase_d_benchmark",
testonly = True,
srcs = [
"hd_erase_d_benchmark.cc",
],
linkstatic = True,
deps = [
"//phtree",
"//phtree/benchmark",
"@gbenchmark//:benchmark",
"@spdlog",
],
)

cc_binary(
name = "hd_query_d_benchmark",
testonly = True,
srcs = [
"hd_query_d_benchmark.cc",
],
linkstatic = True,
deps = [
"//phtree",
"//phtree/benchmark",
"@gbenchmark//:benchmark",
"@spdlog",
],
)

cc_binary(
name = "hd_knn_d_benchmark",
testonly = True,
srcs = [
"hd_knn_d_benchmark.cc",
],
linkstatic = True,
deps = [
"//phtree",
"//phtree/benchmark",
"@gbenchmark//:benchmark",
"@spdlog",
],
)
2 changes: 1 addition & 1 deletion phtree/benchmark/benchmark_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ auto CreateDuplicates =
};
} // namespace

enum TestGenerator { CUBE, CLUSTER };
enum TestGenerator { CUBE = 4, CLUSTER = 7 };

template <dimension_t DIM>
auto CreatePointDataMinMax = [](auto& points,
Expand Down
Loading