Add support for decimals to PatternEntry (#9577)

Summary:
Add support for doubles to ObjectLibrary::PatternEntry.  This support will allow patterns containing a non-integer number to be parsed correctly.

Added appropriate test cases to cover this new option.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/9577

Reviewed By: pdillinger

Differential Revision: D34269763

Pulled By: mrambacher

fbshipit-source-id: b5ce16cbd3665c2974ec0f3412ef2b403ef8b155
main
mrambacher 2 years ago committed by Facebook GitHub Bot
parent 48f6c2a049
commit c42d0cf862
  1. 2
      HISTORY.md
  2. 8
      include/rocksdb/utilities/object_registry.h
  3. 56
      utilities/object_registry.cc
  4. 63
      utilities/object_registry_test.cc

@ -64,7 +64,7 @@
* Remove deprecated overloads of API DB::GetApproximateSizes.
* Remove deprecated option DBOptions::new_table_reader_for_compaction_inputs.
* Add Transaction::SetReadTimestampForValidation() and Transaction::SetCommitTimestamp(). Default impl returns NotSupported().
* Add support for decimal patterns to ObjectLibrary::PatternEntry
### Behavior Changes
* Disallow the combination of DBOptions.use_direct_io_for_flush_and_compaction == true and DBOptions.writable_file_max_buffer_size == 0. This combination can cause WritableFileWriter::Append() to loop forever, and it does not make much sense in direct IO.
* `ReadOptions::total_order_seek` no longer affects `DB::Get()`. The original motivation for this interaction has been obsolete since RocksDB has been able to detect whether the current prefix extractor is compatible with that used to generate table files, probably RocksDB 5.14.0.

@ -75,7 +75,8 @@ class ObjectLibrary {
kMatchZeroOrMore, // [suffix].*
kMatchAtLeastOne, // [suffix].+
kMatchExact, // [suffix]
kMatchNumeric, // [suffix][0-9]+
kMatchInteger, // [suffix][0-9]+
kMatchDecimal, // [suffix][0-9]+[.][0-9]+
};
public:
@ -123,8 +124,9 @@ class ObjectLibrary {
// Adds a separator (exact match of separator with trailing numbers) to the
// entry
PatternEntry& AddNumber(const std::string& separator) {
separators_.emplace_back(separator, kMatchNumeric);
PatternEntry& AddNumber(const std::string& separator, bool is_int = true) {
separators_.emplace_back(separator,
(is_int) ? kMatchInteger : kMatchDecimal);
slength_ += separator.size() + 1;
return *this;
}

@ -15,6 +15,39 @@
namespace ROCKSDB_NAMESPACE {
#ifndef ROCKSDB_LITE
namespace {
bool MatchesInteger(const std::string &target, size_t start, size_t pos) {
// If it is numeric, everything up to the match must be a number
int digits = 0;
while (start < pos) {
if (!isdigit(target[start++])) {
return false;
} else {
digits++;
}
}
return (digits > 0);
}
bool MatchesDecimal(const std::string &target, size_t start, size_t pos) {
int digits = 0;
for (bool point = false; start < pos; start++) {
if (target[start] == '.') {
if (point) {
return false;
} else {
point = true;
}
} else if (!isdigit(target[start])) {
return false;
} else {
digits++;
}
}
return (digits > 0);
}
} // namespace
size_t ObjectLibrary::PatternEntry::MatchSeparatorAt(
size_t start, Quantifier mode, const std::string &target, size_t tlen,
const std::string &separator) const {
@ -36,12 +69,13 @@ size_t ObjectLibrary::PatternEntry::MatchSeparatorAt(
}
if (pos == std::string::npos) {
return pos;
} else if (mode == kMatchNumeric) {
// If it is numeric, everything up to the match must be a number
while (start < pos) {
if (!isdigit(target[start++])) {
return std::string::npos;
}
} else if (mode == kMatchInteger) {
if (!MatchesInteger(target, start, pos)) {
return std::string::npos;
}
} else if (mode == kMatchDecimal) {
if (!MatchesDecimal(target, start, pos)) {
return std::string::npos;
}
}
return pos + slen;
@ -84,12 +118,10 @@ bool ObjectLibrary::PatternEntry::MatchesTarget(const std::string &name,
return (start == tlen);
} else if (start > tlen || (start == tlen && mode != kMatchZeroOrMore)) {
return false;
} else if (mode == kMatchNumeric) {
while (start < tlen) {
if (!isdigit(target[start++])) {
return false;
}
}
} else if (mode == kMatchInteger) {
return MatchesInteger(target, start, tlen);
} else if (mode == kMatchDecimal) {
return MatchesDecimal(target, start, tlen);
}
}
return true;

@ -599,6 +599,69 @@ TEST_F(PatternEntryTest, TestNumericEntry) {
ASSERT_FALSE(entry.Matches("A:B"));
ASSERT_FALSE(entry.Matches("A:1B"));
ASSERT_FALSE(entry.Matches("A:B1"));
entry.AddSeparator(":", false);
ASSERT_FALSE(entry.Matches("A"));
ASSERT_FALSE(entry.Matches("AA"));
ASSERT_FALSE(entry.Matches("A:"));
ASSERT_FALSE(entry.Matches("AA:"));
ASSERT_TRUE(entry.Matches("A:1:"));
ASSERT_TRUE(entry.Matches("A:11:"));
ASSERT_FALSE(entry.Matches("A:1"));
ASSERT_FALSE(entry.Matches("A:B1:"));
ASSERT_FALSE(entry.Matches("A:1B:"));
ASSERT_FALSE(entry.Matches("A::"));
}
TEST_F(PatternEntryTest, TestDoubleEntry) {
ObjectLibrary::PatternEntry entry("A", false);
entry.AddNumber(":", false);
ASSERT_FALSE(entry.Matches("A"));
ASSERT_FALSE(entry.Matches("AA"));
ASSERT_FALSE(entry.Matches("A:"));
ASSERT_FALSE(entry.Matches("AA:"));
ASSERT_FALSE(entry.Matches("AA:1"));
ASSERT_FALSE(entry.Matches("AA:11"));
ASSERT_FALSE(entry.Matches("A:B"));
ASSERT_FALSE(entry.Matches("A:1B"));
ASSERT_FALSE(entry.Matches("A:B1"));
ASSERT_TRUE(entry.Matches("A:1"));
ASSERT_TRUE(entry.Matches("A:11"));
ASSERT_TRUE(entry.Matches("A:1.1"));
ASSERT_TRUE(entry.Matches("A:11.11"));
ASSERT_TRUE(entry.Matches("A:1."));
ASSERT_TRUE(entry.Matches("A:.1"));
ASSERT_TRUE(entry.Matches("A:0.1"));
ASSERT_TRUE(entry.Matches("A:1.0"));
ASSERT_TRUE(entry.Matches("A:1.0"));
ASSERT_FALSE(entry.Matches("A:1.0."));
ASSERT_FALSE(entry.Matches("A:1.0.2"));
ASSERT_FALSE(entry.Matches("A:.1.0"));
ASSERT_FALSE(entry.Matches("A:..10"));
ASSERT_FALSE(entry.Matches("A:10.."));
ASSERT_FALSE(entry.Matches("A:."));
entry.AddSeparator(":", false);
ASSERT_FALSE(entry.Matches("A:1"));
ASSERT_FALSE(entry.Matches("A:1.0"));
ASSERT_TRUE(entry.Matches("A:11:"));
ASSERT_TRUE(entry.Matches("A:1.1:"));
ASSERT_TRUE(entry.Matches("A:11.11:"));
ASSERT_TRUE(entry.Matches("A:1.:"));
ASSERT_TRUE(entry.Matches("A:.1:"));
ASSERT_TRUE(entry.Matches("A:0.1:"));
ASSERT_TRUE(entry.Matches("A:1.0:"));
ASSERT_TRUE(entry.Matches("A:1.0:"));
ASSERT_FALSE(entry.Matches("A:1.0.:"));
ASSERT_FALSE(entry.Matches("A:1.0.2:"));
ASSERT_FALSE(entry.Matches("A:.1.0:"));
ASSERT_FALSE(entry.Matches("A:..10:"));
ASSERT_FALSE(entry.Matches("A:10..:"));
ASSERT_FALSE(entry.Matches("A:.:"));
ASSERT_FALSE(entry.Matches("A::"));
}
TEST_F(PatternEntryTest, TestIndividualIdEntry) {

Loading…
Cancel
Save