ICU-20202 Replace CodePointMatcherWarehouse with MemoryPool.

The shared templated helper class MemoryPool can be used to replace the
local helper class CodePointMatcherWarehouse, reducing the amount of
specialized code needed.
This commit is contained in:
Fredrik Roubert 2018-10-29 22:20:30 +01:00 committed by Fredrik Roubert
parent a96dc7faa5
commit 9de0383cfa
2 changed files with 4 additions and 80 deletions

View File

@ -125,51 +125,6 @@ AffixPatternMatcher AffixPatternMatcherBuilder::build() {
return AffixPatternMatcher(fMatchers, fMatchersLen, fPattern);
}
CodePointMatcherWarehouse::CodePointMatcherWarehouse()
: codePointCount(0), codePointNumBatches(0) {}
CodePointMatcherWarehouse::~CodePointMatcherWarehouse() {
// Delete the variable number of batches of code point matchers
for (int32_t i = 0; i < codePointNumBatches; i++) {
delete[] codePointsOverflow[i];
}
}
CodePointMatcherWarehouse::CodePointMatcherWarehouse(CodePointMatcherWarehouse&& src) U_NOEXCEPT
: codePoints(std::move(src.codePoints)),
codePointsOverflow(std::move(src.codePointsOverflow)),
codePointCount(src.codePointCount),
codePointNumBatches(src.codePointNumBatches) {}
CodePointMatcherWarehouse&
CodePointMatcherWarehouse::operator=(CodePointMatcherWarehouse&& src) U_NOEXCEPT {
codePoints = std::move(src.codePoints);
codePointsOverflow = std::move(src.codePointsOverflow);
codePointCount = src.codePointCount;
codePointNumBatches = src.codePointNumBatches;
return *this;
}
NumberParseMatcher& CodePointMatcherWarehouse::nextCodePointMatcher(UChar32 cp) {
if (codePointCount < CODE_POINT_STACK_CAPACITY) {
return codePoints[codePointCount++] = {cp};
}
int32_t totalCapacity = CODE_POINT_STACK_CAPACITY + codePointNumBatches * CODE_POINT_BATCH_SIZE;
if (codePointCount >= totalCapacity) {
// Need a new batch
auto* nextBatch = new CodePointMatcher[CODE_POINT_BATCH_SIZE];
if (codePointNumBatches >= codePointsOverflow.getCapacity()) {
// Need more room for storing pointers to batches
codePointsOverflow.resize(codePointNumBatches * 2, codePointNumBatches);
}
codePointsOverflow[codePointNumBatches++] = nextBatch;
}
return codePointsOverflow[codePointNumBatches - 1][(codePointCount++ - CODE_POINT_STACK_CAPACITY) %
CODE_POINT_BATCH_SIZE] = {cp};
}
AffixTokenMatcherWarehouse::AffixTokenMatcherWarehouse(const AffixTokenMatcherSetupData* setupData)
: fSetupData(setupData) {}
@ -198,7 +153,7 @@ IgnorablesMatcher& AffixTokenMatcherWarehouse::ignorables() {
}
NumberParseMatcher& AffixTokenMatcherWarehouse::nextCodePointMatcher(UChar32 cp) {
return fCodePoints.nextCodePointMatcher(cp);
return *fCodePoints.create(cp);
}

View File

@ -7,14 +7,14 @@
#ifndef __NUMPARSE_AFFIXES_H__
#define __NUMPARSE_AFFIXES_H__
#include "cmemory.h"
#include "numparse_types.h"
#include "numparse_symbols.h"
#include "numparse_currency.h"
#include "number_affixutils.h"
#include "number_currencysymbols.h"
#include <array>
U_NAMESPACE_BEGIN
namespace numparse {
namespace impl {
@ -60,37 +60,6 @@ template class U_I18N_API numparse::impl::CompactUnicodeString<4>;
namespace numparse {
namespace impl {
/**
* A warehouse to retain ownership of CodePointMatchers.
*/
// Exported as U_I18N_API for tests
class U_I18N_API CodePointMatcherWarehouse : public UMemory {
private:
static constexpr int32_t CODE_POINT_STACK_CAPACITY = 5; // Number of entries directly on the stack
static constexpr int32_t CODE_POINT_BATCH_SIZE = 10; // Number of entries per heap allocation
public:
CodePointMatcherWarehouse();
// A custom destructor is needed to free the memory from MaybeStackArray.
// A custom move constructor and move assignment seem to be needed because of the custom destructor.
~CodePointMatcherWarehouse();
CodePointMatcherWarehouse(CodePointMatcherWarehouse&& src) U_NOEXCEPT;
CodePointMatcherWarehouse& operator=(CodePointMatcherWarehouse&& src) U_NOEXCEPT;
NumberParseMatcher& nextCodePointMatcher(UChar32 cp);
private:
std::array<CodePointMatcher, CODE_POINT_STACK_CAPACITY> codePoints; // By value
MaybeStackArray<CodePointMatcher*, 3> codePointsOverflow; // On heap in "batches"
int32_t codePointCount; // Total for both the ones by value and on heap
int32_t codePointNumBatches; // Number of batches in codePointsOverflow
};
struct AffixTokenMatcherSetupData {
const CurrencySymbols& currencySymbols;
const DecimalFormatSymbols& dfs;
@ -143,7 +112,7 @@ class U_I18N_API AffixTokenMatcherWarehouse : public UMemory {
CombinedCurrencyMatcher fCurrency;
// Use a child class for code point matchers, since it requires non-default operators.
CodePointMatcherWarehouse fCodePoints;
MemoryPool<CodePointMatcher> fCodePoints;
friend class AffixPatternMatcherBuilder;
friend class AffixPatternMatcher;