Skip to content

Commit

Permalink
fix: SkipIndex cause segment fault
Browse files Browse the repository at this point in the history
Signed-off-by: chyezh <[email protected]>
  • Loading branch information
chyezh committed Sep 2, 2024
1 parent b2eb9fe commit e228eed
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 38 deletions.
4 changes: 2 additions & 2 deletions internal/core/src/index/SkipIndex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ SkipIndex::LoadString(milvus::FieldId field_id,
auto chunkMetrics = std::make_unique<FieldChunkMetrics>();
if (num_rows > 0) {
auto info = ProcessStringFieldMetrics(var_column);
chunkMetrics->min_ = Metrics(info.min_);
chunkMetrics->max_ = Metrics(info.max_);
chunkMetrics->min_ = Metrics(std::move(info.min_));
chunkMetrics->max_ = Metrics(std::move(info.max_));

Check warning on line 123 in internal/core/src/index/SkipIndex.cpp

View check run for this annotation

Codecov / codecov/patch

internal/core/src/index/SkipIndex.cpp#L122-L123

Added lines #L122 - L123 were not covered by tests
chunkMetrics->null_count_ = info.null_count_;
}

Expand Down
68 changes: 32 additions & 36 deletions internal/core/src/index/SkipIndex.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,37 @@

namespace milvus {

using Metrics = std::
variant<int8_t, int16_t, int32_t, int64_t, float, double, std::string_view>;
using Metrics =
std::variant<int8_t, int16_t, int32_t, int64_t, float, double, std::string>;

// MetricsDataType is used to avoid copy when get min/max value fro FieldChunkMetrics
template <typename T>
using MetricsDataType =
std::conditional_t<std::is_same_v<T, std::string>, std::string_view, T>;
std::conditional_t<std::is_same_v<T, std::string_view>, std::string, T>;

struct FieldChunkMetrics {
Metrics min_;
Metrics max_;
bool hasValue_;
int64_t null_count_;

FieldChunkMetrics() : hasValue_(false){};
FieldChunkMetrics() : hasValue_(false) {};

Check warning on line 36 in internal/core/src/index/SkipIndex.h

View check run for this annotation

Codecov / codecov/patch

internal/core/src/index/SkipIndex.h#L36

Added line #L36 was not covered by tests

template <typename T>
std::pair<T, T>
GetMinMax() const {
AssertInfo(hasValue_,
"GetMinMax should never be called when hasValue_ is false");
T lower_bound;
T upper_bound;
try {
lower_bound = std::get<MetricsDataType<T>>(min_);
upper_bound = std::get<MetricsDataType<T>>(max_);
} catch (const std::bad_variant_access& e) {
return {};
}
return {lower_bound, upper_bound};
}
};

class SkipIndex {
Expand Down Expand Up @@ -99,22 +116,6 @@ class SkipIndex {
static constexpr bool value = isAllowedType && !isDisabledType;
};

template <typename T>
std::pair<MetricsDataType<T>, MetricsDataType<T>>
GetMinMax(const FieldChunkMetrics& field_chunk_metrics) const {
MetricsDataType<T> lower_bound;
MetricsDataType<T> upper_bound;
try {
lower_bound =
std::get<MetricsDataType<T>>(field_chunk_metrics.min_);
upper_bound =
std::get<MetricsDataType<T>>(field_chunk_metrics.max_);
} catch (const std::bad_variant_access&) {
return {};
}
return {lower_bound, upper_bound};
}

template <typename T>
std::enable_if_t<SkipIndex::IsAllowedType<T>::value, bool>
MinMaxUnaryFilter(const FieldChunkMetrics& field_chunk_metrics,
Expand All @@ -123,13 +124,11 @@ class SkipIndex {
if (!field_chunk_metrics.hasValue_) {
return false;
}
std::pair<MetricsDataType<T>, MetricsDataType<T>> minMax =
GetMinMax<T>(field_chunk_metrics);
if (minMax.first == MetricsDataType<T>() ||
minMax.second == MetricsDataType<T>()) {
auto [lower_bound, upper_bound] = field_chunk_metrics.GetMinMax<T>();
if (lower_bound == T() || upper_bound == T()) {
return false;
}
return RangeShouldSkip<T>(val, minMax.first, minMax.second, op_type);
return RangeShouldSkip<T>(val, lower_bound, upper_bound, op_type);
}

template <typename T>
Expand All @@ -150,15 +149,11 @@ class SkipIndex {
if (!field_chunk_metrics.hasValue_) {
return false;
}
std::pair<MetricsDataType<T>, MetricsDataType<T>> minMax =
GetMinMax<T>(field_chunk_metrics);
if (minMax.first == MetricsDataType<T>() ||
minMax.second == MetricsDataType<T>()) {
auto [lower_bound, upper_bound] = field_chunk_metrics.GetMinMax<T>();
if (lower_bound == T() || upper_bound == T()) {
return false;
}
bool should_skip = false;
MetricsDataType<T> lower_bound = minMax.first;
MetricsDataType<T> upper_bound = minMax.second;
if (lower_inclusive && upper_inclusive) {
should_skip =
(lower_val > upper_bound) || (upper_val < lower_bound);
Expand Down Expand Up @@ -188,8 +183,8 @@ class SkipIndex {
template <typename T>
bool
RangeShouldSkip(const T& value,
const MetricsDataType<T> lower_bound,
const MetricsDataType<T> upper_bound,
const T& lower_bound,
const T& upper_bound,
OpType op_type) const {
bool should_skip = false;
switch (op_type) {
Expand Down Expand Up @@ -267,7 +262,7 @@ class SkipIndex {
return {minValue, maxValue, null_count};
}

metricInfo<std::string_view>
metricInfo<std::string>
ProcessStringFieldMetrics(
const milvus::VariableColumn<std::string>& var_column) {
int num_rows = var_column.NumRows();
Expand All @@ -281,7 +276,7 @@ class SkipIndex {
break;
}
if (start > num_rows - 1) {
return {std::string_view(), std::string_view(), num_rows};
return {std::string(), std::string(), num_rows};

Check warning on line 279 in internal/core/src/index/SkipIndex.h

View check run for this annotation

Codecov / codecov/patch

internal/core/src/index/SkipIndex.h#L279

Added line #L279 was not covered by tests
}
std::string_view min_string = var_column.RawAt(start);
std::string_view max_string = var_column.RawAt(start);
Expand All @@ -299,7 +294,8 @@ class SkipIndex {
max_string = val;
}
}
return {min_string, max_string, null_count};
// The field data may be released, so we need to copy the string to avoid invalid memory access.
return {std::string(min_string), std::string(max_string), null_count};

Check warning on line 298 in internal/core/src/index/SkipIndex.h

View check run for this annotation

Codecov / codecov/patch

internal/core/src/index/SkipIndex.h#L298

Added line #L298 was not covered by tests
}

private:
Expand Down

0 comments on commit e228eed

Please sign in to comment.