diff --git a/internal/core/src/query/CMakeLists.txt b/internal/core/src/query/CMakeLists.txt index f1e403037bb247002add2d1ad290556dfa9311e8..32ae613002ebb40bb788e6704f5dc27130b5ca81 100644 --- a/internal/core/src/query/CMakeLists.txt +++ b/internal/core/src/query/CMakeLists.txt @@ -18,4 +18,4 @@ set(MILVUS_QUERY_SRCS SubQueryResult.cpp ) add_library(milvus_query ${MILVUS_QUERY_SRCS}) -target_link_libraries(milvus_query milvus_proto milvus_utils knowhere) +target_link_libraries(milvus_query milvus_proto milvus_utils knowhere boost_bitset_ext) diff --git a/internal/core/src/query/SearchOnGrowing.cpp b/internal/core/src/query/SearchOnGrowing.cpp index e043731931132afd15afa9cbc9d23a274d308263..24796c0a84ab3c7868913e4c72a3b9763933af05 100644 --- a/internal/core/src/query/SearchOnGrowing.cpp +++ b/internal/core/src/query/SearchOnGrowing.cpp @@ -20,20 +20,6 @@ #include "query/SearchOnIndex.h" namespace milvus::query { - -static faiss::ConcurrentBitsetPtr -create_bitmap_view(std::optional bitmaps_opt, int64_t chunk_id) { - if (!bitmaps_opt.has_value()) { - return nullptr; - } - auto& bitmaps = *bitmaps_opt.value(); - auto src_vec = ~bitmaps.at(chunk_id); - auto dst = std::make_shared(src_vec.size()); - auto iter = reinterpret_cast(dst->mutable_data()); - boost::to_block_range(src_vec, iter); - return dst; -} - Status FloatSearch(const segcore::SegmentGrowingImpl& segment, const query::QueryInfo& info, diff --git a/internal/core/src/query/SearchOnGrowing.h b/internal/core/src/query/SearchOnGrowing.h index 2f7869d8c3e6df51a21933f77e59176372929dde..a365d1eed71c32895a3cd88a684898c5321eb79e 100644 --- a/internal/core/src/query/SearchOnGrowing.h +++ b/internal/core/src/query/SearchOnGrowing.h @@ -17,8 +17,8 @@ #include "query/SubQueryResult.h" namespace milvus::query { -using BitmapChunk = boost::dynamic_bitset<>; -using BitmapSimple = std::deque; +using BitsetChunk = boost::dynamic_bitset<>; +using BitsetSimple = std::deque; void SearchOnGrowing(const segcore::SegmentGrowingImpl& segment, diff --git a/internal/core/src/query/SearchOnSealed.cpp b/internal/core/src/query/SearchOnSealed.cpp index b078b74552a3e619f3c31502d55fe7d0730ad52b..caf304d8d07a3b0e760e8bad2a5ed9fb0300f95f 100644 --- a/internal/core/src/query/SearchOnSealed.cpp +++ b/internal/core/src/query/SearchOnSealed.cpp @@ -17,32 +17,34 @@ #include #include "knowhere/index/vector_index/helpers/IndexParameter.h" #include "knowhere/index/vector_index/adapter/VectorAdapter.h" +#include namespace milvus::query { // negate bitset, and merge them into one aligned_vector -AssembleNegBitmap(const BitmapSimple& bitmap_simple) { +AssembleNegBitset(const BitsetSimple& bitset_simple) { int64_t N = 0; - for (auto& bitmap : bitmap_simple) { - N += bitmap.size(); + for (auto& bitset : bitset_simple) { + N += bitset.size(); } - aligned_vector result(upper_align(upper_div(N, 8), sizeof(BitmapChunk::block_type))); + aligned_vector result(upper_align(upper_div(N, 8), 64)); auto acc_byte_count = 0; - for (auto& bitmap_raw : bitmap_simple) { - auto bitmap = ~bitmap_raw; - auto size = bitmap.size(); + for (auto& bitset : bitset_simple) { + auto size = bitset.size(); Assert(size % 8 == 0); auto byte_count = size / 8; - - auto iter = reinterpret_cast(result.data() + acc_byte_count); - boost::to_block_range(bitmap, iter); - + auto src_ptr = boost_ext::get_data(bitset); + memcpy(result.data() + acc_byte_count, src_ptr, byte_count); acc_byte_count += byte_count; } + // revert the bitset + for (int64_t i = 0; i < result.size(); ++i) { + result[i] = ~result[i]; + } return result; } diff --git a/internal/core/src/query/SearchOnSealed.h b/internal/core/src/query/SearchOnSealed.h index 1d836c719a6f388b503149bc807aa28a2a03cb48..c3db872cc6973b60e1c75315df7ae1830504f378 100644 --- a/internal/core/src/query/SearchOnSealed.h +++ b/internal/core/src/query/SearchOnSealed.h @@ -18,7 +18,7 @@ namespace milvus::query { aligned_vector -AssembleNegBitmap(const BitmapSimple& bitmap_simple); +AssembleNegBitset(const BitsetSimple& bitmap_simple); void SearchOnSealed(const Schema& schema, diff --git a/internal/core/src/query/visitors/ExecPlanNodeVisitor.cpp b/internal/core/src/query/visitors/ExecPlanNodeVisitor.cpp index d558978ee311d22313c98d4a8c6d1326260d38fe..fe42de80b41af6aad76f126b899e4cde3fcdfc60 100644 --- a/internal/core/src/query/visitors/ExecPlanNodeVisitor.cpp +++ b/internal/core/src/query/visitors/ExecPlanNodeVisitor.cpp @@ -80,7 +80,7 @@ ExecPlanNodeVisitor::VectorVisitorImpl(VectorPlanNode& node) { if (node.predicate_.has_value()) { ExecExprVisitor::RetType expr_ret = ExecExprVisitor(*segment, row_count).call_child(*node.predicate_.value()); - bitset_holder = AssembleNegBitmap(expr_ret); + bitset_holder = AssembleNegBitset(expr_ret); view = BitsetView(bitset_holder.data(), bitset_holder.size() * 8); } diff --git a/internal/core/thirdparty/CMakeLists.txt b/internal/core/thirdparty/CMakeLists.txt index 7098c2e351ebede29503261bd77d85b8baf58eef..33dd8d4c6bb333edf1b00e547af399b73c4171fd 100644 --- a/internal/core/thirdparty/CMakeLists.txt +++ b/internal/core/thirdparty/CMakeLists.txt @@ -55,3 +55,4 @@ endif() add_subdirectory( protobuf ) add_subdirectory( fiu ) +add_subdirectory( boost_ext ) diff --git a/internal/core/thirdparty/boost_ext/CMakeLists.txt b/internal/core/thirdparty/boost_ext/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e28099e7c16c73bf3d60f460744d4fad0e39f665 --- /dev/null +++ b/internal/core/thirdparty/boost_ext/CMakeLists.txt @@ -0,0 +1,2 @@ +find_package(Boost REQUIRED) +add_library(boost_bitset_ext dynamic_bitset_ext.cpp) diff --git a/internal/core/thirdparty/boost_ext/LICENSE b/internal/core/thirdparty/boost_ext/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..022ef3ab859e5f7f481370784206fd812c9c9cbe --- /dev/null +++ b/internal/core/thirdparty/boost_ext/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 FluorineDog + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/internal/core/thirdparty/boost_ext/dynamic_bitset_ext.cpp b/internal/core/thirdparty/boost_ext/dynamic_bitset_ext.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bbe110c991ac7e8be6575878918f6c7a05c2588c --- /dev/null +++ b/internal/core/thirdparty/boost_ext/dynamic_bitset_ext.cpp @@ -0,0 +1,63 @@ +#include +#include "dynamic_bitset_ext.hpp" + +namespace { +struct PtrWrapper { + explicit PtrWrapper(char*& ptr) : ptr_(ptr) {} + char*& ptr_; +}; + +struct ConstPtrWrapper { + explicit ConstPtrWrapper(const char*& ptr) : ptr_(ptr) {} + const char*& ptr_; +}; + +using Block = unsigned long; +using Allocator = std::allocator; + +} // namespace + + +namespace boost { +// a language lawyer's way to steal original pointer from boost::dynamic_bitset +// salute to http://www.gotw.ca/gotw/076.htm +template<> +void +from_block_range(PtrWrapper result, + PtrWrapper resultB, + dynamic_bitset<>& bitset) { + (void)resultB; + result.ptr_ = reinterpret_cast(bitset.m_bits.data()); +} + +template<> +void +to_block_range(const dynamic_bitset<>& bitset, + ConstPtrWrapper result) { + result.ptr_ = reinterpret_cast(bitset.m_bits.data()); +} +} // namespace boost + + +namespace boost_ext { + +char* +get_data(boost::dynamic_bitset<>& bitset) { + char* ptr = nullptr; + PtrWrapper wrapper{ptr}; + boost::from_block_range(wrapper, wrapper, bitset); + assert(ptr); + return ptr; +} + +const char* +get_data(const boost::dynamic_bitset<>& bitset) { + const char* ptr = nullptr; + ConstPtrWrapper wrapper{ptr}; + boost::to_block_range(bitset, wrapper); + assert(ptr); + return ptr; +} + + +} // namespace boost_ext diff --git a/internal/core/thirdparty/boost_ext/dynamic_bitset_ext.hpp b/internal/core/thirdparty/boost_ext/dynamic_bitset_ext.hpp new file mode 100644 index 0000000000000000000000000000000000000000..aa93229f1b9730e9cc967a52e09cead7acc14748 --- /dev/null +++ b/internal/core/thirdparty/boost_ext/dynamic_bitset_ext.hpp @@ -0,0 +1,6 @@ +#include + +namespace boost_ext { +const char* get_data(const boost::dynamic_bitset<>& bitset); +char* get_data(boost::dynamic_bitset<>& bitset); +} // namespace boost_ext