Merge pull request #776 from miloyip/issue728_threadsafe
Remove singletons in schema classes
This commit is contained in:
commit
fba9ebd9bc
@ -349,6 +349,7 @@ public:
|
|||||||
|
|
||||||
Schema(SchemaDocumentType* schemaDocument, const PointerType& p, const ValueType& value, const ValueType& document, AllocatorType* allocator) :
|
Schema(SchemaDocumentType* schemaDocument, const PointerType& p, const ValueType& value, const ValueType& document, AllocatorType* allocator) :
|
||||||
allocator_(allocator),
|
allocator_(allocator),
|
||||||
|
typeless_(schemaDocument->GetTypeless()),
|
||||||
enum_(),
|
enum_(),
|
||||||
enumCount_(),
|
enumCount_(),
|
||||||
not_(),
|
not_(),
|
||||||
@ -453,7 +454,7 @@ public:
|
|||||||
for (SizeType i = 0; i < propertyCount_; i++) {
|
for (SizeType i = 0; i < propertyCount_; i++) {
|
||||||
new (&properties_[i]) Property();
|
new (&properties_[i]) Property();
|
||||||
properties_[i].name = allProperties[i];
|
properties_[i].name = allProperties[i];
|
||||||
properties_[i].schema = GetTypeless();
|
properties_[i].schema = typeless_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -575,9 +576,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
~Schema() {
|
~Schema() {
|
||||||
if (allocator_) {
|
AllocatorType::Free(enum_);
|
||||||
allocator_->Free(enum_);
|
|
||||||
}
|
|
||||||
if (properties_) {
|
if (properties_) {
|
||||||
for (SizeType i = 0; i < propertyCount_; i++)
|
for (SizeType i = 0; i < propertyCount_; i++)
|
||||||
properties_[i].~Property();
|
properties_[i].~Property();
|
||||||
@ -592,7 +591,7 @@ public:
|
|||||||
#if RAPIDJSON_SCHEMA_HAS_REGEX
|
#if RAPIDJSON_SCHEMA_HAS_REGEX
|
||||||
if (pattern_) {
|
if (pattern_) {
|
||||||
pattern_->~RegexType();
|
pattern_->~RegexType();
|
||||||
allocator_->Free(pattern_);
|
AllocatorType::Free(pattern_);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -610,12 +609,12 @@ public:
|
|||||||
else if (additionalItemsSchema_)
|
else if (additionalItemsSchema_)
|
||||||
context.valueSchema = additionalItemsSchema_;
|
context.valueSchema = additionalItemsSchema_;
|
||||||
else if (additionalItems_)
|
else if (additionalItems_)
|
||||||
context.valueSchema = GetTypeless();
|
context.valueSchema = typeless_;
|
||||||
else
|
else
|
||||||
RAPIDJSON_INVALID_KEYWORD_RETURN(GetItemsString());
|
RAPIDJSON_INVALID_KEYWORD_RETURN(GetItemsString());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
context.valueSchema = GetTypeless();
|
context.valueSchema = typeless_;
|
||||||
|
|
||||||
context.arrayElementIndex++;
|
context.arrayElementIndex++;
|
||||||
}
|
}
|
||||||
@ -792,7 +791,7 @@ public:
|
|||||||
if (FindPropertyIndex(ValueType(str, len).Move(), &index)) {
|
if (FindPropertyIndex(ValueType(str, len).Move(), &index)) {
|
||||||
if (context.patternPropertiesSchemaCount > 0) {
|
if (context.patternPropertiesSchemaCount > 0) {
|
||||||
context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = properties_[index].schema;
|
context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = properties_[index].schema;
|
||||||
context.valueSchema = GetTypeless();
|
context.valueSchema = typeless_;
|
||||||
context.valuePatternValidatorType = Context::kPatternValidatorWithProperty;
|
context.valuePatternValidatorType = Context::kPatternValidatorWithProperty;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -807,7 +806,7 @@ public:
|
|||||||
if (additionalPropertiesSchema_) {
|
if (additionalPropertiesSchema_) {
|
||||||
if (additionalPropertiesSchema_ && context.patternPropertiesSchemaCount > 0) {
|
if (additionalPropertiesSchema_ && context.patternPropertiesSchemaCount > 0) {
|
||||||
context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = additionalPropertiesSchema_;
|
context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = additionalPropertiesSchema_;
|
||||||
context.valueSchema = GetTypeless();
|
context.valueSchema = typeless_;
|
||||||
context.valuePatternValidatorType = Context::kPatternValidatorWithAdditionalProperty;
|
context.valuePatternValidatorType = Context::kPatternValidatorWithAdditionalProperty;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -815,7 +814,7 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (additionalProperties_) {
|
else if (additionalProperties_) {
|
||||||
context.valueSchema = GetTypeless();
|
context.valueSchema = typeless_;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -949,11 +948,6 @@ private:
|
|||||||
SizeType count;
|
SizeType count;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SchemaType* GetTypeless() {
|
|
||||||
static SchemaType typeless(0, PointerType(), ValueType(kObjectType).Move(), ValueType(kObjectType).Move(), 0);
|
|
||||||
return &typeless;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename V1, typename V2>
|
template <typename V1, typename V2>
|
||||||
void AddUniqueElement(V1& a, const V2& v) {
|
void AddUniqueElement(V1& a, const V2& v) {
|
||||||
for (typename V1::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)
|
for (typename V1::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)
|
||||||
@ -1219,6 +1213,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
AllocatorType* allocator_;
|
AllocatorType* allocator_;
|
||||||
|
const SchemaType* typeless_;
|
||||||
uint64_t* enum_;
|
uint64_t* enum_;
|
||||||
SizeType enumCount_;
|
SizeType enumCount_;
|
||||||
SchemaArray allOf_;
|
SchemaArray allOf_;
|
||||||
@ -1344,12 +1339,16 @@ public:
|
|||||||
allocator_(allocator),
|
allocator_(allocator),
|
||||||
ownAllocator_(),
|
ownAllocator_(),
|
||||||
root_(),
|
root_(),
|
||||||
|
typeless_(),
|
||||||
schemaMap_(allocator, kInitialSchemaMapSize),
|
schemaMap_(allocator, kInitialSchemaMapSize),
|
||||||
schemaRef_(allocator, kInitialSchemaRefSize)
|
schemaRef_(allocator, kInitialSchemaRefSize)
|
||||||
{
|
{
|
||||||
if (!allocator_)
|
if (!allocator_)
|
||||||
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
|
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
|
||||||
|
|
||||||
|
typeless_ = static_cast<SchemaType*>(allocator_->Malloc(sizeof(SchemaType)));
|
||||||
|
new (typeless_) SchemaType(this, PointerType(), ValueType(kObjectType).Move(), ValueType(kObjectType).Move(), 0);
|
||||||
|
|
||||||
// Generate root schema, it will call CreateSchema() to create sub-schemas,
|
// Generate root schema, it will call CreateSchema() to create sub-schemas,
|
||||||
// And call AddRefSchema() if there are $ref.
|
// And call AddRefSchema() if there are $ref.
|
||||||
CreateSchemaRecursive(&root_, PointerType(), document, document);
|
CreateSchemaRecursive(&root_, PointerType(), document, document);
|
||||||
@ -1367,7 +1366,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (refEntry->schema)
|
else if (refEntry->schema)
|
||||||
*refEntry->schema = SchemaType::GetTypeless();
|
*refEntry->schema = typeless_;
|
||||||
|
|
||||||
refEntry->~SchemaRefEntry();
|
refEntry->~SchemaRefEntry();
|
||||||
}
|
}
|
||||||
@ -1384,12 +1383,14 @@ public:
|
|||||||
allocator_(rhs.allocator_),
|
allocator_(rhs.allocator_),
|
||||||
ownAllocator_(rhs.ownAllocator_),
|
ownAllocator_(rhs.ownAllocator_),
|
||||||
root_(rhs.root_),
|
root_(rhs.root_),
|
||||||
|
typeless_(rhs.typeless_),
|
||||||
schemaMap_(std::move(rhs.schemaMap_)),
|
schemaMap_(std::move(rhs.schemaMap_)),
|
||||||
schemaRef_(std::move(rhs.schemaRef_))
|
schemaRef_(std::move(rhs.schemaRef_))
|
||||||
{
|
{
|
||||||
rhs.remoteProvider_ = 0;
|
rhs.remoteProvider_ = 0;
|
||||||
rhs.allocator_ = 0;
|
rhs.allocator_ = 0;
|
||||||
rhs.ownAllocator_ = 0;
|
rhs.ownAllocator_ = 0;
|
||||||
|
rhs.typeless_ = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1398,6 +1399,11 @@ public:
|
|||||||
while (!schemaMap_.Empty())
|
while (!schemaMap_.Empty())
|
||||||
schemaMap_.template Pop<SchemaEntry>(1)->~SchemaEntry();
|
schemaMap_.template Pop<SchemaEntry>(1)->~SchemaEntry();
|
||||||
|
|
||||||
|
if (typeless_) {
|
||||||
|
typeless_->~SchemaType();
|
||||||
|
Allocator::Free(typeless_);
|
||||||
|
}
|
||||||
|
|
||||||
RAPIDJSON_DELETE(ownAllocator_);
|
RAPIDJSON_DELETE(ownAllocator_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1432,7 +1438,7 @@ private:
|
|||||||
|
|
||||||
void CreateSchemaRecursive(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) {
|
void CreateSchemaRecursive(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) {
|
||||||
if (schema)
|
if (schema)
|
||||||
*schema = SchemaType::GetTypeless();
|
*schema = typeless_;
|
||||||
|
|
||||||
if (v.GetType() == kObjectType) {
|
if (v.GetType() == kObjectType) {
|
||||||
const SchemaType* s = GetSchema(pointer);
|
const SchemaType* s = GetSchema(pointer);
|
||||||
@ -1519,6 +1525,8 @@ private:
|
|||||||
return PointerType();
|
return PointerType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SchemaType* GetTypeless() const { return typeless_; }
|
||||||
|
|
||||||
static const size_t kInitialSchemaMapSize = 64;
|
static const size_t kInitialSchemaMapSize = 64;
|
||||||
static const size_t kInitialSchemaRefSize = 64;
|
static const size_t kInitialSchemaRefSize = 64;
|
||||||
|
|
||||||
@ -1526,6 +1534,7 @@ private:
|
|||||||
Allocator *allocator_;
|
Allocator *allocator_;
|
||||||
Allocator *ownAllocator_;
|
Allocator *ownAllocator_;
|
||||||
const SchemaType* root_; //!< Root schema.
|
const SchemaType* root_; //!< Root schema.
|
||||||
|
SchemaType* typeless_;
|
||||||
internal::Stack<Allocator> schemaMap_; // Stores created Pointer -> Schemas
|
internal::Stack<Allocator> schemaMap_; // Stores created Pointer -> Schemas
|
||||||
internal::Stack<Allocator> schemaRef_; // Stores Pointer from $ref and schema which holds the $ref
|
internal::Stack<Allocator> schemaRef_; // Stores Pointer from $ref and schema which holds the $ref
|
||||||
};
|
};
|
||||||
@ -1579,11 +1588,11 @@ public:
|
|||||||
:
|
:
|
||||||
schemaDocument_(&schemaDocument),
|
schemaDocument_(&schemaDocument),
|
||||||
root_(schemaDocument.GetRoot()),
|
root_(schemaDocument.GetRoot()),
|
||||||
outputHandler_(GetNullHandler()),
|
|
||||||
stateAllocator_(allocator),
|
stateAllocator_(allocator),
|
||||||
ownStateAllocator_(0),
|
ownStateAllocator_(0),
|
||||||
schemaStack_(allocator, schemaStackCapacity),
|
schemaStack_(allocator, schemaStackCapacity),
|
||||||
documentStack_(allocator, documentStackCapacity),
|
documentStack_(allocator, documentStackCapacity),
|
||||||
|
outputHandler_(CreateNullHandler()),
|
||||||
valid_(true)
|
valid_(true)
|
||||||
#if RAPIDJSON_SCHEMA_VERBOSE
|
#if RAPIDJSON_SCHEMA_VERBOSE
|
||||||
, depth_(0)
|
, depth_(0)
|
||||||
@ -1607,11 +1616,12 @@ public:
|
|||||||
:
|
:
|
||||||
schemaDocument_(&schemaDocument),
|
schemaDocument_(&schemaDocument),
|
||||||
root_(schemaDocument.GetRoot()),
|
root_(schemaDocument.GetRoot()),
|
||||||
outputHandler_(outputHandler),
|
|
||||||
stateAllocator_(allocator),
|
stateAllocator_(allocator),
|
||||||
ownStateAllocator_(0),
|
ownStateAllocator_(0),
|
||||||
schemaStack_(allocator, schemaStackCapacity),
|
schemaStack_(allocator, schemaStackCapacity),
|
||||||
documentStack_(allocator, documentStackCapacity),
|
documentStack_(allocator, documentStackCapacity),
|
||||||
|
outputHandler_(outputHandler),
|
||||||
|
nullHandler_(0),
|
||||||
valid_(true)
|
valid_(true)
|
||||||
#if RAPIDJSON_SCHEMA_VERBOSE
|
#if RAPIDJSON_SCHEMA_VERBOSE
|
||||||
, depth_(0)
|
, depth_(0)
|
||||||
@ -1622,6 +1632,10 @@ public:
|
|||||||
//! Destructor.
|
//! Destructor.
|
||||||
~GenericSchemaValidator() {
|
~GenericSchemaValidator() {
|
||||||
Reset();
|
Reset();
|
||||||
|
if (nullHandler_) {
|
||||||
|
nullHandler_->~OutputHandler();
|
||||||
|
StateAllocator::Free(nullHandler_);
|
||||||
|
}
|
||||||
RAPIDJSON_DELETE(ownStateAllocator_);
|
RAPIDJSON_DELETE(ownStateAllocator_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1795,11 +1809,11 @@ private:
|
|||||||
:
|
:
|
||||||
schemaDocument_(&schemaDocument),
|
schemaDocument_(&schemaDocument),
|
||||||
root_(root),
|
root_(root),
|
||||||
outputHandler_(GetNullHandler()),
|
|
||||||
stateAllocator_(allocator),
|
stateAllocator_(allocator),
|
||||||
ownStateAllocator_(0),
|
ownStateAllocator_(0),
|
||||||
schemaStack_(allocator, schemaStackCapacity),
|
schemaStack_(allocator, schemaStackCapacity),
|
||||||
documentStack_(allocator, documentStackCapacity),
|
documentStack_(allocator, documentStackCapacity),
|
||||||
|
outputHandler_(CreateNullHandler()),
|
||||||
valid_(true)
|
valid_(true)
|
||||||
#if RAPIDJSON_SCHEMA_VERBOSE
|
#if RAPIDJSON_SCHEMA_VERBOSE
|
||||||
, depth_(depth)
|
, depth_(depth)
|
||||||
@ -1827,8 +1841,8 @@ private:
|
|||||||
const SchemaType** sa = CurrentContext().patternPropertiesSchemas;
|
const SchemaType** sa = CurrentContext().patternPropertiesSchemas;
|
||||||
typename Context::PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType;
|
typename Context::PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType;
|
||||||
bool valueUniqueness = CurrentContext().valueUniqueness;
|
bool valueUniqueness = CurrentContext().valueUniqueness;
|
||||||
if (CurrentContext().valueSchema)
|
RAPIDJSON_ASSERT(CurrentContext().valueSchema);
|
||||||
PushSchema(*CurrentContext().valueSchema);
|
PushSchema(*CurrentContext().valueSchema);
|
||||||
|
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
CurrentContext().objectPatternValidatorType = patternValidatorType;
|
CurrentContext().objectPatternValidatorType = patternValidatorType;
|
||||||
@ -1913,20 +1927,20 @@ private:
|
|||||||
Context& CurrentContext() { return *schemaStack_.template Top<Context>(); }
|
Context& CurrentContext() { return *schemaStack_.template Top<Context>(); }
|
||||||
const Context& CurrentContext() const { return *schemaStack_.template Top<Context>(); }
|
const Context& CurrentContext() const { return *schemaStack_.template Top<Context>(); }
|
||||||
|
|
||||||
static OutputHandler& GetNullHandler() {
|
OutputHandler& CreateNullHandler() {
|
||||||
static OutputHandler nullHandler;
|
return *(nullHandler_ = static_cast<OutputHandler*>(stateAllocator_->Malloc(sizeof(OutputHandler))));
|
||||||
return nullHandler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const size_t kDefaultSchemaStackCapacity = 1024;
|
static const size_t kDefaultSchemaStackCapacity = 1024;
|
||||||
static const size_t kDefaultDocumentStackCapacity = 256;
|
static const size_t kDefaultDocumentStackCapacity = 256;
|
||||||
const SchemaDocumentType* schemaDocument_;
|
const SchemaDocumentType* schemaDocument_;
|
||||||
const SchemaType& root_;
|
const SchemaType& root_;
|
||||||
OutputHandler& outputHandler_;
|
|
||||||
StateAllocator* stateAllocator_;
|
StateAllocator* stateAllocator_;
|
||||||
StateAllocator* ownStateAllocator_;
|
StateAllocator* ownStateAllocator_;
|
||||||
internal::Stack<StateAllocator> schemaStack_; //!< stack to store the current path of schema (BaseSchemaType *)
|
internal::Stack<StateAllocator> schemaStack_; //!< stack to store the current path of schema (BaseSchemaType *)
|
||||||
internal::Stack<StateAllocator> documentStack_; //!< stack to store the current path of validating document (Ch)
|
internal::Stack<StateAllocator> documentStack_; //!< stack to store the current path of validating document (Ch)
|
||||||
|
OutputHandler& outputHandler_;
|
||||||
|
OutputHandler* nullHandler_;
|
||||||
bool valid_;
|
bool valid_;
|
||||||
#if RAPIDJSON_SCHEMA_VERBOSE
|
#if RAPIDJSON_SCHEMA_VERBOSE
|
||||||
unsigned depth_;
|
unsigned depth_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user