From 4788764844bfa8877050ff60c8d926fe43febfb8 Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Sun, 22 Feb 2015 16:38:05 -0600 Subject: [PATCH] drop JSON_VALUE_USE_INTERNAL_MAP, JSON_USE_SIMPLE_INTERNAL_ALLOCATOR And remove some old headers. These were not actually compiling anymore, and there were outstanding, known bugs, e.g. https://sourceforge.net/p/jsoncpp/bugs/27 --- amalgamate.py | 1 - doc/doxyfile.in | 3 +- doc/web_doxyfile.in | 3 +- include/json/config.h | 11 - include/json/forwards.h | 6 - include/json/value.h | 390 ----------------------- makefiles/vs71/lib_json.vcproj | 9 - src/lib_json/CMakeLists.txt | 1 - src/lib_json/json_batchallocator.h | 121 ------- src/lib_json/json_internalarray.inl | 360 --------------------- src/lib_json/json_internalmap.inl | 473 ---------------------------- src/lib_json/json_value.cpp | 189 ----------- src/lib_json/json_valueiterator.inl | 97 ------ 13 files changed, 2 insertions(+), 1662 deletions(-) delete mode 100644 src/lib_json/json_batchallocator.h delete mode 100644 src/lib_json/json_internalarray.inl delete mode 100644 src/lib_json/json_internalmap.inl diff --git a/amalgamate.py b/amalgamate.py index 51f33d3..f84936f 100644 --- a/amalgamate.py +++ b/amalgamate.py @@ -118,7 +118,6 @@ def amalgamate_source(source_top_dir=None, lib_json = "src/lib_json" source.add_file(os.path.join(lib_json, "json_tool.h")) source.add_file(os.path.join(lib_json, "json_reader.cpp")) - source.add_file(os.path.join(lib_json, "json_batchallocator.h")) source.add_file(os.path.join(lib_json, "json_valueiterator.inl")) source.add_file(os.path.join(lib_json, "json_value.cpp")) source.add_file(os.path.join(lib_json, "json_writer.cpp")) diff --git a/doc/doxyfile.in b/doc/doxyfile.in index bb30c35..57c61c2 100644 --- a/doc/doxyfile.in +++ b/doc/doxyfile.in @@ -1946,8 +1946,7 @@ INCLUDE_FILE_PATTERNS = *.h PREDEFINED = "_MSC_VER=1400" \ _CPPRTTI \ _WIN32 \ - JSONCPP_DOC_EXCLUDE_IMPLEMENTATION \ - JSON_VALUE_USE_INTERNAL_MAP + JSONCPP_DOC_EXCLUDE_IMPLEMENTATION # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The diff --git a/doc/web_doxyfile.in b/doc/web_doxyfile.in index 8df2d8b..07d6819 100644 --- a/doc/web_doxyfile.in +++ b/doc/web_doxyfile.in @@ -1946,8 +1946,7 @@ INCLUDE_FILE_PATTERNS = *.h PREDEFINED = "_MSC_VER=1400" \ _CPPRTTI \ _WIN32 \ - JSONCPP_DOC_EXCLUDE_IMPLEMENTATION \ - JSON_VALUE_USE_INTERNAL_MAP + JSONCPP_DOC_EXCLUDE_IMPLEMENTATION # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The diff --git a/include/json/config.h b/include/json/config.h index afd3a45..f14aaa8 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -15,17 +15,6 @@ /// std::map /// as Value container. //# define JSON_USE_CPPTL_SMALLMAP 1 -/// If defined, indicates that Json specific container should be used -/// (hash table & simple deque container with customizable allocator). -/// THIS FEATURE IS STILL EXPERIMENTAL! There is know bugs: See #3177332 -//# define JSON_VALUE_USE_INTERNAL_MAP 1 -/// Force usage of standard new/malloc based allocator instead of memory pool -/// based allocator. -/// The memory pools allocator used optimization (initializing Value and -/// ValueInternalLink -/// as if it was a POD) that may cause some validation tool to report errors. -/// Only has effects if JSON_VALUE_USE_INTERNAL_MAP is defined. -//# define JSON_USE_SIMPLE_INTERNAL_ALLOCATOR 1 // If non-zero, the library uses exceptions to report bad input instead of C // assertion macros. The default is to use exceptions. diff --git a/include/json/forwards.h b/include/json/forwards.h index 84a26cd..ccfe09a 100644 --- a/include/json/forwards.h +++ b/include/json/forwards.h @@ -31,12 +31,6 @@ class Value; class ValueIteratorBase; class ValueIterator; class ValueConstIterator; -#ifdef JSON_VALUE_USE_INTERNAL_MAP -class ValueMapAllocator; -class ValueInternalLink; -class ValueInternalArray; -class ValueInternalMap; -#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP } // namespace Json diff --git a/include/json/value.h b/include/json/value.h index 62a323b..f8fe824 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -115,10 +115,6 @@ private: */ class JSON_API Value { friend class ValueIteratorBase; -#ifdef JSON_VALUE_USE_INTERNAL_MAP - friend class ValueInternalLink; - friend class ValueInternalMap; -#endif public: typedef std::vector Members; typedef ValueIterator iterator; @@ -160,7 +156,6 @@ public: private: #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION -#ifndef JSON_VALUE_USE_INTERNAL_MAP class CZString { public: enum DuplicationPolicy { @@ -191,7 +186,6 @@ public: #else typedef CppTL::SmallMap ObjectValues; #endif // ifndef JSON_USE_CPPTL_SMALLMAP -#endif // ifndef JSON_VALUE_USE_INTERNAL_MAP #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION public: @@ -463,19 +457,6 @@ private: Value& resolveReference(const char* key, bool isStatic); -#ifdef JSON_VALUE_USE_INTERNAL_MAP - inline bool isItemAvailable() const { return itemIsUsed_ == 0; } - - inline void setItemUsed(bool isUsed = true) { itemIsUsed_ = isUsed ? 1 : 0; } - - inline bool isMemberNameStatic() const { return memberNameIsStatic_ == 0; } - - inline void setMemberNameIsStatic(bool isStatic) { - memberNameIsStatic_ = isStatic ? 1 : 0; - } -#endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP - -private: struct CommentInfo { CommentInfo(); ~CommentInfo(); @@ -500,19 +481,10 @@ private: double real_; bool bool_; char* string_; -#ifdef JSON_VALUE_USE_INTERNAL_MAP - ValueInternalArray* array_; - ValueInternalMap* map_; -#else ObjectValues* map_; -#endif } value_; ValueType type_ : 8; unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless. -#ifdef JSON_VALUE_USE_INTERNAL_MAP - unsigned int itemIsUsed_ : 1; // used by the ValueInternalMap container. - unsigned int memberNameIsStatic_ : 1; // used by the ValueInternalMap container. -#endif CommentInfo* comments_; // [start, limit) byte offsets in the source JSON text from which this Value @@ -584,345 +556,6 @@ private: Args args_; }; -#ifdef JSON_VALUE_USE_INTERNAL_MAP -/** \brief Allocator to customize Value internal map. - * Below is an example of a simple implementation (default implementation - actually - * use memory pool for speed). - * \code - class DefaultValueMapAllocator : public ValueMapAllocator - { - public: // overridden from ValueMapAllocator - virtual ValueInternalMap *newMap() - { - return new ValueInternalMap(); - } - - virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) - { - return new ValueInternalMap( other ); - } - - virtual void destructMap( ValueInternalMap *map ) - { - delete map; - } - - virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) - { - return new ValueInternalLink[size]; - } - - virtual void releaseMapBuckets( ValueInternalLink *links ) - { - delete [] links; - } - - virtual ValueInternalLink *allocateMapLink() - { - return new ValueInternalLink(); - } - - virtual void releaseMapLink( ValueInternalLink *link ) - { - delete link; - } - }; - * \endcode - */ -class JSON_API ValueMapAllocator { -public: - virtual ~ValueMapAllocator(); - virtual ValueInternalMap* newMap() = 0; - virtual ValueInternalMap* newMapCopy(const ValueInternalMap& other) = 0; - virtual void destructMap(ValueInternalMap* map) = 0; - virtual ValueInternalLink* allocateMapBuckets(unsigned int size) = 0; - virtual void releaseMapBuckets(ValueInternalLink* links) = 0; - virtual ValueInternalLink* allocateMapLink() = 0; - virtual void releaseMapLink(ValueInternalLink* link) = 0; -}; - -/** \brief ValueInternalMap hash-map bucket chain link (for internal use only). - * \internal previous_ & next_ allows for bidirectional traversal. - */ -class JSON_API ValueInternalLink { -public: - enum { - itemPerLink = 6 - }; // sizeof(ValueInternalLink) = 128 on 32 bits architecture. - enum InternalFlags { - flagAvailable = 0, - flagUsed = 1 - }; - - ValueInternalLink(); - - ~ValueInternalLink(); - - Value items_[itemPerLink]; - char* keys_[itemPerLink]; - ValueInternalLink* previous_; - ValueInternalLink* next_; -}; - -/** \brief A linked page based hash-table implementation used internally by - *Value. - * \internal ValueInternalMap is a tradional bucket based hash-table, with a - *linked - * list in each bucket to handle collision. There is an addional twist in that - * each node of the collision linked list is a page containing a fixed amount of - * value. This provides a better compromise between memory usage and speed. - * - * Each bucket is made up of a chained list of ValueInternalLink. The last - * link of a given bucket can be found in the 'previous_' field of the following - *bucket. - * The last link of the last bucket is stored in tailLink_ as it has no - *following bucket. - * Only the last link of a bucket may contains 'available' item. The last link - *always - * contains at least one element unless is it the bucket one very first link. - */ -class JSON_API ValueInternalMap { - friend class ValueIteratorBase; - friend class Value; - -public: - typedef unsigned int HashKey; - typedef unsigned int BucketIndex; - -#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION - struct IteratorState { - IteratorState() : map_(0), link_(0), itemIndex_(0), bucketIndex_(0) {} - ValueInternalMap* map_; - ValueInternalLink* link_; - BucketIndex itemIndex_; - BucketIndex bucketIndex_; - }; -#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION - - ValueInternalMap(); - ValueInternalMap(const ValueInternalMap& other); - ValueInternalMap& operator=(ValueInternalMap other); - ~ValueInternalMap(); - - void swap(ValueInternalMap& other); - - BucketIndex size() const; - - void clear(); - - bool reserveDelta(BucketIndex growth); - - bool reserve(BucketIndex newItemCount); - - const Value* find(const char* key) const; - - Value* find(const char* key); - - Value& resolveReference(const char* key, bool isStatic); - - void remove(const char* key); - - void doActualRemove(ValueInternalLink* link, - BucketIndex index, - BucketIndex bucketIndex); - - ValueInternalLink*& getLastLinkInBucket(BucketIndex bucketIndex); - - Value& setNewItem(const char* key, - bool isStatic, - ValueInternalLink* link, - BucketIndex index); - - Value& unsafeAdd(const char* key, bool isStatic, HashKey hashedKey); - - HashKey hash(const char* key) const; - - int compare(const ValueInternalMap& other) const; - -private: - void makeBeginIterator(IteratorState& it) const; - void makeEndIterator(IteratorState& it) const; - static bool equals(const IteratorState& x, const IteratorState& other); - static void increment(IteratorState& iterator); - static void incrementBucket(IteratorState& iterator); - static void decrement(IteratorState& iterator); - static const char* key(const IteratorState& iterator); - static const char* key(const IteratorState& iterator, bool& isStatic); - static Value& value(const IteratorState& iterator); - static int distance(const IteratorState& x, const IteratorState& y); - -private: - ValueInternalLink* buckets_; - ValueInternalLink* tailLink_; - BucketIndex bucketsSize_; - BucketIndex itemCount_; -}; - -/** \brief A simplified deque implementation used internally by Value. -* \internal -* It is based on a list of fixed "page", each page contains a fixed number of -*items. -* Instead of using a linked-list, a array of pointer is used for fast item -*look-up. -* Look-up for an element is as follow: -* - compute page index: pageIndex = itemIndex / itemsPerPage -* - look-up item in page: pages_[pageIndex][itemIndex % itemsPerPage] -* -* Insertion is amortized constant time (only the array containing the index of -*pointers -* need to be reallocated when items are appended). -*/ -class JSON_API ValueInternalArray { - friend class Value; - friend class ValueIteratorBase; - -public: - enum { - itemsPerPage = 8 - }; // should be a power of 2 for fast divide and modulo. - typedef Value::ArrayIndex ArrayIndex; - typedef unsigned int PageIndex; - -#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION - struct IteratorState // Must be a POD - { - IteratorState() : array_(0), currentPageIndex_(0), currentItemIndex_(0) {} - ValueInternalArray* array_; - Value** currentPageIndex_; - unsigned int currentItemIndex_; - }; -#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION - - ValueInternalArray(); - ValueInternalArray(const ValueInternalArray& other); - ValueInternalArray& operator=(ValueInternalArray other); - ~ValueInternalArray(); - void swap(ValueInternalArray& other); - - void clear(); - void resize(ArrayIndex newSize); - - Value& resolveReference(ArrayIndex index); - - Value* find(ArrayIndex index) const; - - ArrayIndex size() const; - - int compare(const ValueInternalArray& other) const; - -private: - static bool equals(const IteratorState& x, const IteratorState& other); - static void increment(IteratorState& iterator); - static void decrement(IteratorState& iterator); - static Value& dereference(const IteratorState& iterator); - static Value& unsafeDereference(const IteratorState& iterator); - static int distance(const IteratorState& x, const IteratorState& y); - static ArrayIndex indexOf(const IteratorState& iterator); - void makeBeginIterator(IteratorState& it) const; - void makeEndIterator(IteratorState& it) const; - void makeIterator(IteratorState& it, ArrayIndex index) const; - - void makeIndexValid(ArrayIndex index); - - Value** pages_; - ArrayIndex size_; - PageIndex pageCount_; -}; - -/** \brief Experimental: do not use. Allocator to customize Value internal -array. - * Below is an example of a simple implementation (actual implementation use - * memory pool). - \code -class DefaultValueArrayAllocator : public ValueArrayAllocator -{ -public: // overridden from ValueArrayAllocator -virtual ~DefaultValueArrayAllocator() -{ -} - -virtual ValueInternalArray *newArray() -{ - return new ValueInternalArray(); -} - -virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) -{ - return new ValueInternalArray( other ); -} - -virtual void destruct( ValueInternalArray *array ) -{ - delete array; -} - -virtual void reallocateArrayPageIndex( Value **&indexes, - ValueInternalArray::PageIndex -&indexCount, - ValueInternalArray::PageIndex -minNewIndexCount ) -{ - ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1; - if ( minNewIndexCount > newIndexCount ) - newIndexCount = minNewIndexCount; - void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount ); - if ( !newIndexes ) - throw std::bad_alloc(); - indexCount = newIndexCount; - indexes = static_cast( newIndexes ); -} -virtual void releaseArrayPageIndex( Value **indexes, - ValueInternalArray::PageIndex indexCount ) -{ - if ( indexes ) - free( indexes ); -} - -virtual Value *allocateArrayPage() -{ - return static_cast( malloc( sizeof(Value) * -ValueInternalArray::itemsPerPage ) ); -} - -virtual void releaseArrayPage( Value *value ) -{ - if ( value ) - free( value ); -} -}; - \endcode - */ -class JSON_API ValueArrayAllocator { -public: - virtual ~ValueArrayAllocator(); - virtual ValueInternalArray* newArray() = 0; - virtual ValueInternalArray* newArrayCopy(const ValueInternalArray& other) = 0; - virtual void destructArray(ValueInternalArray* array) = 0; - /** \brief Reallocate array page index. - * Reallocates an array of pointer on each page. - * \param indexes [input] pointer on the current index. May be \c NULL. - * [output] pointer on the new index of at least - * \a minNewIndexCount pages. - * \param indexCount [input] current number of pages in the index. - * [output] number of page the reallocated index can handle. - * \b MUST be >= \a minNewIndexCount. - * \param minNewIndexCount Minimum number of page the new index must be able - * to - * handle. - */ - virtual void - reallocateArrayPageIndex(Value**& indexes, - ValueInternalArray::PageIndex& indexCount, - ValueInternalArray::PageIndex minNewIndexCount) = 0; - virtual void - releaseArrayPageIndex(Value** indexes, - ValueInternalArray::PageIndex indexCount) = 0; - virtual Value* allocateArrayPage() = 0; - virtual void releaseArrayPage(Value* value) = 0; -}; -#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP - /** \brief base class for Value iterators. * */ @@ -934,12 +567,7 @@ public: typedef ValueIteratorBase SelfType; ValueIteratorBase(); -#ifndef JSON_VALUE_USE_INTERNAL_MAP explicit ValueIteratorBase(const Value::ObjectValues::iterator& current); -#else - ValueIteratorBase(const ValueInternalArray::IteratorState& state); - ValueIteratorBase(const ValueInternalMap::IteratorState& state); -#endif bool operator==(const SelfType& other) const { return isEqual(other); } @@ -974,17 +602,9 @@ protected: void copy(const SelfType& other); private: -#ifndef JSON_VALUE_USE_INTERNAL_MAP Value::ObjectValues::iterator current_; // Indicates that iterator is for a null value. bool isNull_; -#else - union { - ValueInternalArray::IteratorState array_; - ValueInternalMap::IteratorState map_; - } iterator_; - bool isArray_; -#endif }; /** \brief const iterator for object and array value. @@ -1006,12 +626,7 @@ public: private: /*! \internal Use by Value to create an iterator. */ -#ifndef JSON_VALUE_USE_INTERNAL_MAP explicit ValueConstIterator(const Value::ObjectValues::iterator& current); -#else - ValueConstIterator(const ValueInternalArray::IteratorState& state); - ValueConstIterator(const ValueInternalMap::IteratorState& state); -#endif public: SelfType& operator=(const ValueIteratorBase& other); @@ -1062,12 +677,7 @@ public: private: /*! \internal Use by Value to create an iterator. */ -#ifndef JSON_VALUE_USE_INTERNAL_MAP explicit ValueIterator(const Value::ObjectValues::iterator& current); -#else - ValueIterator(const ValueInternalArray::IteratorState& state); - ValueIterator(const ValueInternalMap::IteratorState& state); -#endif public: SelfType& operator=(const SelfType& other); diff --git a/makefiles/vs71/lib_json.vcproj b/makefiles/vs71/lib_json.vcproj index 2d7bf99..fe66d8a 100644 --- a/makefiles/vs71/lib_json.vcproj +++ b/makefiles/vs71/lib_json.vcproj @@ -178,15 +178,6 @@ - - - - - - diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index 856b164..18d127b 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -34,7 +34,6 @@ SOURCE_GROUP( "Public API" FILES ${PUBLIC_HEADERS} ) SET(jsoncpp_sources json_tool.h json_reader.cpp - json_batchallocator.h json_valueiterator.inl json_value.cpp json_writer.cpp diff --git a/src/lib_json/json_batchallocator.h b/src/lib_json/json_batchallocator.h deleted file mode 100644 index 2fbef7a..0000000 --- a/src/lib_json/json_batchallocator.h +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2007-2010 Baptiste Lepilleur -// Distributed under MIT license, or public domain if desired and -// recognized in your jurisdiction. -// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE - -#ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED -#define JSONCPP_BATCHALLOCATOR_H_INCLUDED - -#include -#include - -#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION - -namespace Json { - -/* Fast memory allocator. - * - * This memory allocator allocates memory for a batch of object (specified by - * the page size, the number of object in each page). - * - * It does not allow the destruction of a single object. All the allocated - * objects can be destroyed at once. The memory can be either released or reused - * for future allocation. - * - * The in-place new operator must be used to construct the object using the - * pointer returned by allocate. - */ -template -class BatchAllocator { -public: - BatchAllocator(unsigned int objectsPerPage = 255) - : freeHead_(0), objectsPerPage_(objectsPerPage) { - // printf( "Size: %d => %s\n", sizeof(AllocatedType), - // typeid(AllocatedType).name() ); - assert(sizeof(AllocatedType) * objectPerAllocation >= - sizeof(AllocatedType*)); // We must be able to store a slist in the - // object free space. - assert(objectsPerPage >= 16); - batches_ = allocateBatch(0); // allocated a dummy page - currentBatch_ = batches_; - } - - ~BatchAllocator() { - for (BatchInfo* batch = batches_; batch;) { - BatchInfo* nextBatch = batch->next_; - free(batch); - batch = nextBatch; - } - } - - /// allocate space for an array of objectPerAllocation object. - /// @warning it is the responsability of the caller to call objects - /// constructors. - AllocatedType* allocate() { - if (freeHead_) // returns node from free list. - { - AllocatedType* object = freeHead_; - freeHead_ = *(AllocatedType**)object; - return object; - } - if (currentBatch_->used_ == currentBatch_->end_) { - currentBatch_ = currentBatch_->next_; - while (currentBatch_ && currentBatch_->used_ == currentBatch_->end_) - currentBatch_ = currentBatch_->next_; - - if (!currentBatch_) // no free batch found, allocate a new one - { - currentBatch_ = allocateBatch(objectsPerPage_); - currentBatch_->next_ = batches_; // insert at the head of the list - batches_ = currentBatch_; - } - } - AllocatedType* allocated = currentBatch_->used_; - currentBatch_->used_ += objectPerAllocation; - return allocated; - } - - /// Release the object. - /// @warning it is the responsability of the caller to actually destruct the - /// object. - void release(AllocatedType* object) { - assert(object != 0); - *(AllocatedType**)object = freeHead_; - freeHead_ = object; - } - -private: - struct BatchInfo { - BatchInfo* next_; - AllocatedType* used_; - AllocatedType* end_; - AllocatedType buffer_[objectPerAllocation]; - }; - - // disabled copy constructor and assignement operator. - BatchAllocator(const BatchAllocator&); - void operator=(const BatchAllocator&); - - static BatchInfo* allocateBatch(unsigned int objectsPerPage) { - const unsigned int mallocSize = - sizeof(BatchInfo) - sizeof(AllocatedType) * objectPerAllocation + - sizeof(AllocatedType) * objectPerAllocation * objectsPerPage; - BatchInfo* batch = static_cast(malloc(mallocSize)); - batch->next_ = 0; - batch->used_ = batch->buffer_; - batch->end_ = batch->buffer_ + objectsPerPage; - return batch; - } - - BatchInfo* batches_; - BatchInfo* currentBatch_; - /// Head of a single linked list within the allocated space of freeed object - AllocatedType* freeHead_; - unsigned int objectsPerPage_; -}; - -} // namespace Json - -#endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION - -#endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED diff --git a/src/lib_json/json_internalarray.inl b/src/lib_json/json_internalarray.inl deleted file mode 100644 index 9ee15e9..0000000 --- a/src/lib_json/json_internalarray.inl +++ /dev/null @@ -1,360 +0,0 @@ -// Copyright 2007-2010 Baptiste Lepilleur -// Distributed under MIT license, or public domain if desired and -// recognized in your jurisdiction. -// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE - -// included by json_value.cpp - -namespace Json { - -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// class ValueInternalArray -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// - -ValueArrayAllocator::~ValueArrayAllocator() {} - -// ////////////////////////////////////////////////////////////////// -// class DefaultValueArrayAllocator -// ////////////////////////////////////////////////////////////////// -#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR -class DefaultValueArrayAllocator : public ValueArrayAllocator { -public: // overridden from ValueArrayAllocator - virtual ~DefaultValueArrayAllocator() {} - - virtual ValueInternalArray* newArray() { return new ValueInternalArray(); } - - virtual ValueInternalArray* newArrayCopy(const ValueInternalArray& other) { - return new ValueInternalArray(other); - } - - virtual void destructArray(ValueInternalArray* array) { delete array; } - - virtual void - reallocateArrayPageIndex(Value**& indexes, - ValueInternalArray::PageIndex& indexCount, - ValueInternalArray::PageIndex minNewIndexCount) { - ValueInternalArray::PageIndex newIndexCount = (indexCount * 3) / 2 + 1; - if (minNewIndexCount > newIndexCount) - newIndexCount = minNewIndexCount; - void* newIndexes = realloc(indexes, sizeof(Value*) * newIndexCount); - JSON_ASSERT_MESSAGE(newIndexes, "Couldn't realloc."); - indexCount = newIndexCount; - indexes = static_cast(newIndexes); - } - virtual void releaseArrayPageIndex(Value** indexes, - ValueInternalArray::PageIndex indexCount) { - if (indexes) - free(indexes); - } - - virtual Value* allocateArrayPage() { - return static_cast( - malloc(sizeof(Value) * ValueInternalArray::itemsPerPage)); - } - - virtual void releaseArrayPage(Value* value) { - if (value) - free(value); - } -}; - -#else // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR -/// @todo make this thread-safe (lock when accessign batch allocator) -class DefaultValueArrayAllocator : public ValueArrayAllocator { -public: // overridden from ValueArrayAllocator - virtual ~DefaultValueArrayAllocator() {} - - virtual ValueInternalArray* newArray() { - ValueInternalArray* array = arraysAllocator_.allocate(); - new (array) ValueInternalArray(); // placement new - return array; - } - - virtual ValueInternalArray* newArrayCopy(const ValueInternalArray& other) { - ValueInternalArray* array = arraysAllocator_.allocate(); - new (array) ValueInternalArray(other); // placement new - return array; - } - - virtual void destructArray(ValueInternalArray* array) { - if (array) { - array->~ValueInternalArray(); - arraysAllocator_.release(array); - } - } - - virtual void - reallocateArrayPageIndex(Value**& indexes, - ValueInternalArray::PageIndex& indexCount, - ValueInternalArray::PageIndex minNewIndexCount) { - ValueInternalArray::PageIndex newIndexCount = (indexCount * 3) / 2 + 1; - if (minNewIndexCount > newIndexCount) - newIndexCount = minNewIndexCount; - void* newIndexes = realloc(indexes, sizeof(Value*) * newIndexCount); - JSON_ASSERT_MESSAGE(newIndexes, "Couldn't realloc."); - indexCount = newIndexCount; - indexes = static_cast(newIndexes); - } - virtual void releaseArrayPageIndex(Value** indexes, - ValueInternalArray::PageIndex indexCount) { - if (indexes) - free(indexes); - } - - virtual Value* allocateArrayPage() { - return static_cast(pagesAllocator_.allocate()); - } - - virtual void releaseArrayPage(Value* value) { - if (value) - pagesAllocator_.release(value); - } - -private: - BatchAllocator arraysAllocator_; - BatchAllocator pagesAllocator_; -}; -#endif // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR - -static ValueArrayAllocator*& arrayAllocator() { - static DefaultValueArrayAllocator defaultAllocator; - static ValueArrayAllocator* arrayAllocator = &defaultAllocator; - return arrayAllocator; -} - -static struct DummyArrayAllocatorInitializer { - DummyArrayAllocatorInitializer() { - arrayAllocator(); // ensure arrayAllocator() statics are initialized before - // main(). - } -} dummyArrayAllocatorInitializer; - -// ////////////////////////////////////////////////////////////////// -// class ValueInternalArray -// ////////////////////////////////////////////////////////////////// -bool ValueInternalArray::equals(const IteratorState& x, - const IteratorState& other) { - return x.array_ == other.array_ && - x.currentItemIndex_ == other.currentItemIndex_ && - x.currentPageIndex_ == other.currentPageIndex_; -} - -void ValueInternalArray::increment(IteratorState& it) { - JSON_ASSERT_MESSAGE( - it.array_ && (it.currentPageIndex_ - it.array_->pages_) * itemsPerPage + - it.currentItemIndex_ != - it.array_->size_, - "ValueInternalArray::increment(): moving iterator beyond end"); - ++(it.currentItemIndex_); - if (it.currentItemIndex_ == itemsPerPage) { - it.currentItemIndex_ = 0; - ++(it.currentPageIndex_); - } -} - -void ValueInternalArray::decrement(IteratorState& it) { - JSON_ASSERT_MESSAGE( - it.array_ && it.currentPageIndex_ == it.array_->pages_ && - it.currentItemIndex_ == 0, - "ValueInternalArray::decrement(): moving iterator beyond end"); - if (it.currentItemIndex_ == 0) { - it.currentItemIndex_ = itemsPerPage - 1; - --(it.currentPageIndex_); - } else { - --(it.currentItemIndex_); - } -} - -Value& ValueInternalArray::unsafeDereference(const IteratorState& it) { - return (*(it.currentPageIndex_))[it.currentItemIndex_]; -} - -Value& ValueInternalArray::dereference(const IteratorState& it) { - JSON_ASSERT_MESSAGE( - it.array_ && (it.currentPageIndex_ - it.array_->pages_) * itemsPerPage + - it.currentItemIndex_ < - it.array_->size_, - "ValueInternalArray::dereference(): dereferencing invalid iterator"); - return unsafeDereference(it); -} - -void ValueInternalArray::makeBeginIterator(IteratorState& it) const { - it.array_ = const_cast(this); - it.currentItemIndex_ = 0; - it.currentPageIndex_ = pages_; -} - -void ValueInternalArray::makeIterator(IteratorState& it, - ArrayIndex index) const { - it.array_ = const_cast(this); - it.currentItemIndex_ = index % itemsPerPage; - it.currentPageIndex_ = pages_ + index / itemsPerPage; -} - -void ValueInternalArray::makeEndIterator(IteratorState& it) const { - makeIterator(it, size_); -} - -ValueInternalArray::ValueInternalArray() : pages_(0), size_(0), pageCount_(0) {} - -ValueInternalArray::ValueInternalArray(const ValueInternalArray& other) - : pages_(0), size_(other.size_), pageCount_(0) { - PageIndex minNewPages = other.size_ / itemsPerPage; - arrayAllocator()->reallocateArrayPageIndex(pages_, pageCount_, minNewPages); - JSON_ASSERT_MESSAGE(pageCount_ >= minNewPages, - "ValueInternalArray::reserve(): bad reallocation"); - IteratorState itOther; - other.makeBeginIterator(itOther); - Value* value; - for (ArrayIndex index = 0; index < size_; ++index, increment(itOther)) { - if (index % itemsPerPage == 0) { - PageIndex pageIndex = index / itemsPerPage; - value = arrayAllocator()->allocateArrayPage(); - pages_[pageIndex] = value; - } - new (value) Value(dereference(itOther)); - } -} - -ValueInternalArray& ValueInternalArray::operator=(ValueInternalArray other) { - swap(other); - return *this; -} - -ValueInternalArray::~ValueInternalArray() { - // destroy all constructed items - IteratorState it; - IteratorState itEnd; - makeBeginIterator(it); - makeEndIterator(itEnd); - for (; !equals(it, itEnd); increment(it)) { - Value* value = &dereference(it); - value->~Value(); - } - // release all pages - PageIndex lastPageIndex = size_ / itemsPerPage; - for (PageIndex pageIndex = 0; pageIndex < lastPageIndex; ++pageIndex) - arrayAllocator()->releaseArrayPage(pages_[pageIndex]); - // release pages index - arrayAllocator()->releaseArrayPageIndex(pages_, pageCount_); -} - -void ValueInternalArray::swap(ValueInternalArray& other) { - Value** tempPages = pages_; - pages_ = other.pages_; - other.pages_ = tempPages; - ArrayIndex tempSize = size_; - size_ = other.size_; - other.size_ = tempSize; - PageIndex tempPageCount = pageCount_; - pageCount_ = other.pageCount_; - other.pageCount_ = tempPageCount; -} - -void ValueInternalArray::clear() { - ValueInternalArray dummy; - swap(dummy); -} - -void ValueInternalArray::resize(ArrayIndex newSize) { - if (newSize == 0) - clear(); - else if (newSize < size_) { - IteratorState it; - IteratorState itEnd; - makeIterator(it, newSize); - makeIterator(itEnd, size_); - for (; !equals(it, itEnd); increment(it)) { - Value* value = &dereference(it); - value->~Value(); - } - PageIndex pageIndex = (newSize + itemsPerPage - 1) / itemsPerPage; - PageIndex lastPageIndex = size_ / itemsPerPage; - for (; pageIndex < lastPageIndex; ++pageIndex) - arrayAllocator()->releaseArrayPage(pages_[pageIndex]); - size_ = newSize; - } else if (newSize > size_) - resolveReference(newSize); -} - -void ValueInternalArray::makeIndexValid(ArrayIndex index) { - // Need to enlarge page index ? - if (index >= pageCount_ * itemsPerPage) { - PageIndex minNewPages = (index + 1) / itemsPerPage; - arrayAllocator()->reallocateArrayPageIndex(pages_, pageCount_, minNewPages); - JSON_ASSERT_MESSAGE(pageCount_ >= minNewPages, - "ValueInternalArray::reserve(): bad reallocation"); - } - - // Need to allocate new pages ? - ArrayIndex nextPageIndex = (size_ % itemsPerPage) != 0 - ? size_ - (size_ % itemsPerPage) + itemsPerPage - : size_; - if (nextPageIndex <= index) { - PageIndex pageIndex = nextPageIndex / itemsPerPage; - PageIndex pageToAllocate = (index - nextPageIndex) / itemsPerPage + 1; - for (; pageToAllocate-- > 0; ++pageIndex) - pages_[pageIndex] = arrayAllocator()->allocateArrayPage(); - } - - // Initialize all new entries - IteratorState it; - IteratorState itEnd; - makeIterator(it, size_); - size_ = index + 1; - makeIterator(itEnd, size_); - for (; !equals(it, itEnd); increment(it)) { - Value* value = &dereference(it); - new (value) Value(); // Construct a default value using placement new - } -} - -Value& ValueInternalArray::resolveReference(ArrayIndex index) { - if (index >= size_) - makeIndexValid(index); - return pages_[index / itemsPerPage][index % itemsPerPage]; -} - -Value* ValueInternalArray::find(ArrayIndex index) const { - if (index >= size_) - return 0; - return &(pages_[index / itemsPerPage][index % itemsPerPage]); -} - -ValueInternalArray::ArrayIndex ValueInternalArray::size() const { - return size_; -} - -int ValueInternalArray::distance(const IteratorState& x, - const IteratorState& y) { - return indexOf(y) - indexOf(x); -} - -ValueInternalArray::ArrayIndex -ValueInternalArray::indexOf(const IteratorState& iterator) { - if (!iterator.array_) - return ArrayIndex(-1); - return ArrayIndex((iterator.currentPageIndex_ - iterator.array_->pages_) * - itemsPerPage + - iterator.currentItemIndex_); -} - -int ValueInternalArray::compare(const ValueInternalArray& other) const { - int sizeDiff(size_ - other.size_); - if (sizeDiff != 0) - return sizeDiff; - - for (ArrayIndex index = 0; index < size_; ++index) { - int diff = pages_[index / itemsPerPage][index % itemsPerPage].compare( - other.pages_[index / itemsPerPage][index % itemsPerPage]); - if (diff != 0) - return diff; - } - return 0; -} - -} // namespace Json diff --git a/src/lib_json/json_internalmap.inl b/src/lib_json/json_internalmap.inl deleted file mode 100644 index ef3f330..0000000 --- a/src/lib_json/json_internalmap.inl +++ /dev/null @@ -1,473 +0,0 @@ -// Copyright 2007-2010 Baptiste Lepilleur -// Distributed under MIT license, or public domain if desired and -// recognized in your jurisdiction. -// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE - -// included by json_value.cpp - -namespace Json { - -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// class ValueInternalMap -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// - -/** \internal MUST be safely initialized using memset( this, 0, - * sizeof(ValueInternalLink) ); - * This optimization is used by the fast allocator. - */ -ValueInternalLink::ValueInternalLink() : previous_(0), next_(0) {} - -ValueInternalLink::~ValueInternalLink() { - for (int index = 0; index < itemPerLink; ++index) { - if (!items_[index].isItemAvailable()) { - if (!items_[index].isMemberNameStatic()) - free(keys_[index]); - } else - break; - } -} - -ValueMapAllocator::~ValueMapAllocator() {} - -#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR -class DefaultValueMapAllocator : public ValueMapAllocator { -public: // overridden from ValueMapAllocator - virtual ValueInternalMap* newMap() { return new ValueInternalMap(); } - - virtual ValueInternalMap* newMapCopy(const ValueInternalMap& other) { - return new ValueInternalMap(other); - } - - virtual void destructMap(ValueInternalMap* map) { delete map; } - - virtual ValueInternalLink* allocateMapBuckets(unsigned int size) { - return new ValueInternalLink[size]; - } - - virtual void releaseMapBuckets(ValueInternalLink* links) { delete[] links; } - - virtual ValueInternalLink* allocateMapLink() { - return new ValueInternalLink(); - } - - virtual void releaseMapLink(ValueInternalLink* link) { delete link; } -}; -#else -/// @todo make this thread-safe (lock when accessign batch allocator) -class DefaultValueMapAllocator : public ValueMapAllocator { -public: // overridden from ValueMapAllocator - virtual ValueInternalMap* newMap() { - ValueInternalMap* map = mapsAllocator_.allocate(); - new (map) ValueInternalMap(); // placement new - return map; - } - - virtual ValueInternalMap* newMapCopy(const ValueInternalMap& other) { - ValueInternalMap* map = mapsAllocator_.allocate(); - new (map) ValueInternalMap(other); // placement new - return map; - } - - virtual void destructMap(ValueInternalMap* map) { - if (map) { - map->~ValueInternalMap(); - mapsAllocator_.release(map); - } - } - - virtual ValueInternalLink* allocateMapBuckets(unsigned int size) { - return new ValueInternalLink[size]; - } - - virtual void releaseMapBuckets(ValueInternalLink* links) { delete[] links; } - - virtual ValueInternalLink* allocateMapLink() { - ValueInternalLink* link = linksAllocator_.allocate(); - memset(link, 0, sizeof(ValueInternalLink)); - return link; - } - - virtual void releaseMapLink(ValueInternalLink* link) { - link->~ValueInternalLink(); - linksAllocator_.release(link); - } - -private: - BatchAllocator mapsAllocator_; - BatchAllocator linksAllocator_; -}; -#endif - -static ValueMapAllocator*& mapAllocator() { - static DefaultValueMapAllocator defaultAllocator; - static ValueMapAllocator* mapAllocator = &defaultAllocator; - return mapAllocator; -} - -static struct DummyMapAllocatorInitializer { - DummyMapAllocatorInitializer() { - mapAllocator(); // ensure mapAllocator() statics are initialized before - // main(). - } -} dummyMapAllocatorInitializer; - -// h(K) = value * K >> w ; with w = 32 & K prime w.r.t. 2^32. - -/* -use linked list hash map. -buckets array is a container. -linked list element contains 6 key/values. (memory = (16+4) * 6 + 4 = 124) -value have extra state: valid, available, deleted -*/ - -ValueInternalMap::ValueInternalMap() - : buckets_(0), tailLink_(0), bucketsSize_(0), itemCount_(0) {} - -ValueInternalMap::ValueInternalMap(const ValueInternalMap& other) - : buckets_(0), tailLink_(0), bucketsSize_(0), itemCount_(0) { - reserve(other.itemCount_); - IteratorState it; - IteratorState itEnd; - other.makeBeginIterator(it); - other.makeEndIterator(itEnd); - for (; !equals(it, itEnd); increment(it)) { - bool isStatic; - const char* memberName = key(it, isStatic); - const Value& aValue = value(it); - resolveReference(memberName, isStatic) = aValue; - } -} - -ValueInternalMap& ValueInternalMap::operator=(ValueInternalMap other) { - swap(other); - return *this; -} - -ValueInternalMap::~ValueInternalMap() { - if (buckets_) { - for (BucketIndex bucketIndex = 0; bucketIndex < bucketsSize_; - ++bucketIndex) { - ValueInternalLink* link = buckets_[bucketIndex].next_; - while (link) { - ValueInternalLink* linkToRelease = link; - link = link->next_; - mapAllocator()->releaseMapLink(linkToRelease); - } - } - mapAllocator()->releaseMapBuckets(buckets_); - } -} - -void ValueInternalMap::swap(ValueInternalMap& other) { - ValueInternalLink* tempBuckets = buckets_; - buckets_ = other.buckets_; - other.buckets_ = tempBuckets; - ValueInternalLink* tempTailLink = tailLink_; - tailLink_ = other.tailLink_; - other.tailLink_ = tempTailLink; - BucketIndex tempBucketsSize = bucketsSize_; - bucketsSize_ = other.bucketsSize_; - other.bucketsSize_ = tempBucketsSize; - BucketIndex tempItemCount = itemCount_; - itemCount_ = other.itemCount_; - other.itemCount_ = tempItemCount; -} - -void ValueInternalMap::clear() { - ValueInternalMap dummy; - swap(dummy); -} - -ValueInternalMap::BucketIndex ValueInternalMap::size() const { - return itemCount_; -} - -bool ValueInternalMap::reserveDelta(BucketIndex growth) { - return reserve(itemCount_ + growth); -} - -bool ValueInternalMap::reserve(BucketIndex newItemCount) { - if (!buckets_ && newItemCount > 0) { - buckets_ = mapAllocator()->allocateMapBuckets(1); - bucketsSize_ = 1; - tailLink_ = &buckets_[0]; - } - // BucketIndex idealBucketCount = (newItemCount + - // ValueInternalLink::itemPerLink) / ValueInternalLink::itemPerLink; - return true; -} - -const Value* ValueInternalMap::find(const char* key) const { - if (!bucketsSize_) - return 0; - HashKey hashedKey = hash(key); - BucketIndex bucketIndex = hashedKey % bucketsSize_; - for (const ValueInternalLink* current = &buckets_[bucketIndex]; current != 0; - current = current->next_) { - for (BucketIndex index = 0; index < ValueInternalLink::itemPerLink; - ++index) { - if (current->items_[index].isItemAvailable()) - return 0; - if (strcmp(key, current->keys_[index]) == 0) - return ¤t->items_[index]; - } - } - return 0; -} - -Value* ValueInternalMap::find(const char* key) { - const ValueInternalMap* constThis = this; - return const_cast(constThis->find(key)); -} - -Value& ValueInternalMap::resolveReference(const char* key, bool isStatic) { - HashKey hashedKey = hash(key); - if (bucketsSize_) { - BucketIndex bucketIndex = hashedKey % bucketsSize_; - ValueInternalLink** previous = 0; - BucketIndex index; - for (ValueInternalLink* current = &buckets_[bucketIndex]; current != 0; - previous = ¤t->next_, current = current->next_) { - for (index = 0; index < ValueInternalLink::itemPerLink; ++index) { - if (current->items_[index].isItemAvailable()) - return setNewItem(key, isStatic, current, index); - if (strcmp(key, current->keys_[index]) == 0) - return current->items_[index]; - } - } - } - - reserveDelta(1); - return unsafeAdd(key, isStatic, hashedKey); -} - -void ValueInternalMap::remove(const char* key) { - HashKey hashedKey = hash(key); - if (!bucketsSize_) - return; - BucketIndex bucketIndex = hashedKey % bucketsSize_; - for (ValueInternalLink* link = &buckets_[bucketIndex]; link != 0; - link = link->next_) { - BucketIndex index; - for (index = 0; index < ValueInternalLink::itemPerLink; ++index) { - if (link->items_[index].isItemAvailable()) - return; - if (strcmp(key, link->keys_[index]) == 0) { - doActualRemove(link, index, bucketIndex); - return; - } - } - } -} - -void ValueInternalMap::doActualRemove(ValueInternalLink* link, - BucketIndex index, - BucketIndex bucketIndex) { - // find last item of the bucket and swap it with the 'removed' one. - // set removed items flags to 'available'. - // if last page only contains 'available' items, then desallocate it (it's - // empty) - ValueInternalLink*& lastLink = getLastLinkInBucket(index); - BucketIndex lastItemIndex = 1; // a link can never be empty, so start at 1 - for (; lastItemIndex < ValueInternalLink::itemPerLink; - ++lastItemIndex) // may be optimized with dicotomic search - { - if (lastLink->items_[lastItemIndex].isItemAvailable()) - break; - } - - BucketIndex lastUsedIndex = lastItemIndex - 1; - Value* valueToDelete = &link->items_[index]; - Value* valueToPreserve = &lastLink->items_[lastUsedIndex]; - if (valueToDelete != valueToPreserve) - valueToDelete->swap(*valueToPreserve); - if (lastUsedIndex == 0) // page is now empty - { // remove it from bucket linked list and delete it. - ValueInternalLink* linkPreviousToLast = lastLink->previous_; - if (linkPreviousToLast != 0) // can not deleted bucket link. - { - mapAllocator()->releaseMapLink(lastLink); - linkPreviousToLast->next_ = 0; - lastLink = linkPreviousToLast; - } - } else { - Value dummy; - valueToPreserve->swap(dummy); // restore deleted to default Value. - valueToPreserve->setItemUsed(false); - } - --itemCount_; -} - -ValueInternalLink*& -ValueInternalMap::getLastLinkInBucket(BucketIndex bucketIndex) { - if (bucketIndex == bucketsSize_ - 1) - return tailLink_; - ValueInternalLink*& previous = buckets_[bucketIndex + 1].previous_; - if (!previous) - previous = &buckets_[bucketIndex]; - return previous; -} - -Value& ValueInternalMap::setNewItem(const char* key, - bool isStatic, - ValueInternalLink* link, - BucketIndex index) { - char* duplicatedKey = makeMemberName(key); - ++itemCount_; - link->keys_[index] = duplicatedKey; - link->items_[index].setItemUsed(); - link->items_[index].setMemberNameIsStatic(isStatic); - return link->items_[index]; // items already default constructed. -} - -Value& -ValueInternalMap::unsafeAdd(const char* key, bool isStatic, HashKey hashedKey) { - JSON_ASSERT_MESSAGE(bucketsSize_ > 0, - "ValueInternalMap::unsafeAdd(): internal logic error."); - BucketIndex bucketIndex = hashedKey % bucketsSize_; - ValueInternalLink*& previousLink = getLastLinkInBucket(bucketIndex); - ValueInternalLink* link = previousLink; - BucketIndex index; - for (index = 0; index < ValueInternalLink::itemPerLink; ++index) { - if (link->items_[index].isItemAvailable()) - break; - } - if (index == ValueInternalLink::itemPerLink) // need to add a new page - { - ValueInternalLink* newLink = mapAllocator()->allocateMapLink(); - index = 0; - link->next_ = newLink; - previousLink = newLink; - link = newLink; - } - return setNewItem(key, isStatic, link, index); -} - -ValueInternalMap::HashKey ValueInternalMap::hash(const char* key) const { - HashKey hash = 0; - while (*key) - hash += *key++ * 37; - return hash; -} - -int ValueInternalMap::compare(const ValueInternalMap& other) const { - int sizeDiff(itemCount_ - other.itemCount_); - if (sizeDiff != 0) - return sizeDiff; - // Strict order guaranty is required. Compare all keys FIRST, then compare - // values. - IteratorState it; - IteratorState itEnd; - makeBeginIterator(it); - makeEndIterator(itEnd); - for (; !equals(it, itEnd); increment(it)) { - if (!other.find(key(it))) - return 1; - } - - // All keys are equals, let's compare values - makeBeginIterator(it); - for (; !equals(it, itEnd); increment(it)) { - const Value* otherValue = other.find(key(it)); - int valueDiff = value(it).compare(*otherValue); - if (valueDiff != 0) - return valueDiff; - } - return 0; -} - -void ValueInternalMap::makeBeginIterator(IteratorState& it) const { - it.map_ = const_cast(this); - it.bucketIndex_ = 0; - it.itemIndex_ = 0; - it.link_ = buckets_; -} - -void ValueInternalMap::makeEndIterator(IteratorState& it) const { - it.map_ = const_cast(this); - it.bucketIndex_ = bucketsSize_; - it.itemIndex_ = 0; - it.link_ = 0; -} - -bool ValueInternalMap::equals(const IteratorState& x, - const IteratorState& other) { - return x.map_ == other.map_ && x.bucketIndex_ == other.bucketIndex_ && - x.link_ == other.link_ && x.itemIndex_ == other.itemIndex_; -} - -void ValueInternalMap::incrementBucket(IteratorState& iterator) { - ++iterator.bucketIndex_; - JSON_ASSERT_MESSAGE( - iterator.bucketIndex_ <= iterator.map_->bucketsSize_, - "ValueInternalMap::increment(): attempting to iterate beyond end."); - if (iterator.bucketIndex_ == iterator.map_->bucketsSize_) - iterator.link_ = 0; - else - iterator.link_ = &(iterator.map_->buckets_[iterator.bucketIndex_]); - iterator.itemIndex_ = 0; -} - -void ValueInternalMap::increment(IteratorState& iterator) { - JSON_ASSERT_MESSAGE(iterator.map_, - "Attempting to iterator using invalid iterator."); - ++iterator.itemIndex_; - if (iterator.itemIndex_ == ValueInternalLink::itemPerLink) { - JSON_ASSERT_MESSAGE( - iterator.link_ != 0, - "ValueInternalMap::increment(): attempting to iterate beyond end."); - iterator.link_ = iterator.link_->next_; - if (iterator.link_ == 0) - incrementBucket(iterator); - } else if (iterator.link_->items_[iterator.itemIndex_].isItemAvailable()) { - incrementBucket(iterator); - } -} - -void ValueInternalMap::decrement(IteratorState& iterator) { - if (iterator.itemIndex_ == 0) { - JSON_ASSERT_MESSAGE(iterator.map_, - "Attempting to iterate using invalid iterator."); - if (iterator.link_ == &iterator.map_->buckets_[iterator.bucketIndex_]) { - JSON_ASSERT_MESSAGE(iterator.bucketIndex_ > 0, - "Attempting to iterate beyond beginning."); - --(iterator.bucketIndex_); - } - iterator.link_ = iterator.link_->previous_; - iterator.itemIndex_ = ValueInternalLink::itemPerLink - 1; - } -} - -const char* ValueInternalMap::key(const IteratorState& iterator) { - JSON_ASSERT_MESSAGE(iterator.link_, - "Attempting to iterate using invalid iterator."); - return iterator.link_->keys_[iterator.itemIndex_]; -} - -const char* ValueInternalMap::key(const IteratorState& iterator, - bool& isStatic) { - JSON_ASSERT_MESSAGE(iterator.link_, - "Attempting to iterate using invalid iterator."); - isStatic = iterator.link_->items_[iterator.itemIndex_].isMemberNameStatic(); - return iterator.link_->keys_[iterator.itemIndex_]; -} - -Value& ValueInternalMap::value(const IteratorState& iterator) { - JSON_ASSERT_MESSAGE(iterator.link_, - "Attempting to iterate using invalid iterator."); - return iterator.link_->items_[iterator.itemIndex_]; -} - -int ValueInternalMap::distance(const IteratorState& x, const IteratorState& y) { - int offset = 0; - IteratorState it = x; - while (!equals(it, y)) - increment(it); - return offset; -} - -} // namespace Json diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index f9139c7..427c33a 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -7,9 +7,6 @@ #include #include #include -#ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR -#include "json_batchallocator.h" -#endif // #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR #endif // if !defined(JSON_IS_AMALGAMATION) #include #include @@ -117,10 +114,6 @@ static inline void releaseStringValue(char* value) { free(value); } // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// #if !defined(JSON_IS_AMALGAMATION) -#ifdef JSON_VALUE_USE_INTERNAL_MAP -#include "json_internalarray.inl" -#include "json_internalmap.inl" -#endif // JSON_VALUE_USE_INTERNAL_MAP #include "json_valueiterator.inl" #endif // if !defined(JSON_IS_AMALGAMATION) @@ -162,7 +155,6 @@ void Value::CommentInfo::setComment(const char* text, size_t len) { // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// -#ifndef JSON_VALUE_USE_INTERNAL_MAP // Notes: index_ indicates if the string was allocated when // a string is stored. @@ -215,8 +207,6 @@ const char* Value::CZString::c_str() const { return cstr_; } bool Value::CZString::isStaticString() const { return index_ == noDuplication; } -#endif // ifndef JSON_VALUE_USE_INTERNAL_MAP - // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// @@ -244,19 +234,10 @@ Value::Value(ValueType type) { case stringValue: value_.string_ = 0; break; -#ifndef JSON_VALUE_USE_INTERNAL_MAP case arrayValue: case objectValue: value_.map_ = new ObjectValues(); break; -#else - case arrayValue: - value_.array_ = arrayAllocator()->newArray(); - break; - case objectValue: - value_.map_ = mapAllocator()->newMap(); - break; -#endif case booleanValue: value_.bool_ = false; break; @@ -326,10 +307,6 @@ Value::Value(bool value) { Value::Value(const Value& other) : type_(other.type_), allocated_(false) -#ifdef JSON_VALUE_USE_INTERNAL_MAP - , - itemIsUsed_(0) -#endif , comments_(0), start_(other.start_), limit_(other.limit_) { switch (type_) { @@ -349,19 +326,10 @@ Value::Value(const Value& other) allocated_ = false; } break; -#ifndef JSON_VALUE_USE_INTERNAL_MAP case arrayValue: case objectValue: value_.map_ = new ObjectValues(*other.value_.map_); break; -#else - case arrayValue: - value_.array_ = arrayAllocator()->newArrayCopy(*other.value_.array_); - break; - case objectValue: - value_.map_ = mapAllocator()->newMapCopy(*other.value_.map_); - break; -#endif default: JSON_ASSERT_UNREACHABLE; } @@ -388,19 +356,10 @@ Value::~Value() { if (allocated_) releaseStringValue(value_.string_); break; -#ifndef JSON_VALUE_USE_INTERNAL_MAP case arrayValue: case objectValue: delete value_.map_; break; -#else - case arrayValue: - arrayAllocator()->destructArray(value_.array_); - break; - case objectValue: - mapAllocator()->destructMap(value_.map_); - break; -#endif default: JSON_ASSERT_UNREACHABLE; } @@ -460,7 +419,6 @@ bool Value::operator<(const Value& other) const { return (value_.string_ == 0 && other.value_.string_) || (other.value_.string_ && value_.string_ && strcmp(value_.string_, other.value_.string_) < 0); -#ifndef JSON_VALUE_USE_INTERNAL_MAP case arrayValue: case objectValue: { int delta = int(value_.map_->size() - other.value_.map_->size()); @@ -468,12 +426,6 @@ bool Value::operator<(const Value& other) const { return delta < 0; return (*value_.map_) < (*other.value_.map_); } -#else - case arrayValue: - return value_.array_->compare(*(other.value_.array_)) < 0; - case objectValue: - return value_.map_->compare(*(other.value_.map_)) < 0; -#endif default: JSON_ASSERT_UNREACHABLE; } @@ -509,17 +461,10 @@ bool Value::operator==(const Value& other) const { return (value_.string_ == other.value_.string_) || (other.value_.string_ && value_.string_ && strcmp(value_.string_, other.value_.string_) == 0); -#ifndef JSON_VALUE_USE_INTERNAL_MAP case arrayValue: case objectValue: return value_.map_->size() == other.value_.map_->size() && (*value_.map_) == (*other.value_.map_); -#else - case arrayValue: - return value_.array_->compare(*(other.value_.array_)) == 0; - case objectValue: - return value_.map_->compare(*(other.value_.map_)) == 0; -#endif default: JSON_ASSERT_UNREACHABLE; } @@ -769,7 +714,6 @@ ArrayIndex Value::size() const { case booleanValue: case stringValue: return 0; -#ifndef JSON_VALUE_USE_INTERNAL_MAP case arrayValue: // size of the array is highest index + 1 if (!value_.map_->empty()) { ObjectValues::const_iterator itLast = value_.map_->end(); @@ -779,12 +723,6 @@ ArrayIndex Value::size() const { return 0; case objectValue: return ArrayIndex(value_.map_->size()); -#else - case arrayValue: - return Int(value_.array_->size()); - case objectValue: - return Int(value_.map_->size()); -#endif } JSON_ASSERT_UNREACHABLE; return 0; // unreachable; @@ -806,19 +744,10 @@ void Value::clear() { start_ = 0; limit_ = 0; switch (type_) { -#ifndef JSON_VALUE_USE_INTERNAL_MAP case arrayValue: case objectValue: value_.map_->clear(); break; -#else - case arrayValue: - value_.array_->clear(); - break; - case objectValue: - value_.map_->clear(); - break; -#endif default: break; } @@ -829,7 +758,6 @@ void Value::resize(ArrayIndex newSize) { "in Json::Value::resize(): requires arrayValue"); if (type_ == nullValue) *this = Value(arrayValue); -#ifndef JSON_VALUE_USE_INTERNAL_MAP ArrayIndex oldSize = size(); if (newSize == 0) clear(); @@ -841,9 +769,6 @@ void Value::resize(ArrayIndex newSize) { } assert(size() == newSize); } -#else - value_.array_->resize(newSize); -#endif } Value& Value::operator[](ArrayIndex index) { @@ -852,7 +777,6 @@ Value& Value::operator[](ArrayIndex index) { "in Json::Value::operator[](ArrayIndex): requires arrayValue"); if (type_ == nullValue) *this = Value(arrayValue); -#ifndef JSON_VALUE_USE_INTERNAL_MAP CZString key(index); ObjectValues::iterator it = value_.map_->lower_bound(key); if (it != value_.map_->end() && (*it).first == key) @@ -861,9 +785,6 @@ Value& Value::operator[](ArrayIndex index) { ObjectValues::value_type defaultValue(key, null); it = value_.map_->insert(it, defaultValue); return (*it).second; -#else - return value_.array_->resolveReference(index); -#endif } Value& Value::operator[](int index) { @@ -879,16 +800,11 @@ const Value& Value::operator[](ArrayIndex index) const { "in Json::Value::operator[](ArrayIndex)const: requires arrayValue"); if (type_ == nullValue) return null; -#ifndef JSON_VALUE_USE_INTERNAL_MAP CZString key(index); ObjectValues::const_iterator it = value_.map_->find(key); if (it == value_.map_->end()) return null; return (*it).second; -#else - Value* value = value_.array_->find(index); - return value ? *value : null; -#endif } const Value& Value::operator[](int index) const { @@ -905,9 +821,6 @@ Value& Value::operator[](const char* key) { void Value::initBasic(ValueType type, bool allocated) { type_ = type; allocated_ = allocated; -#ifdef JSON_VALUE_USE_INTERNAL_MAP - itemIsUsed_ = 0; -#endif comments_ = 0; start_ = 0; limit_ = 0; @@ -919,7 +832,6 @@ Value& Value::resolveReference(const char* key, bool isStatic) { "in Json::Value::resolveReference(): requires objectValue"); if (type_ == nullValue) *this = Value(objectValue); -#ifndef JSON_VALUE_USE_INTERNAL_MAP CZString actualKey( key, isStatic ? CZString::noDuplication : CZString::duplicateOnCopy); ObjectValues::iterator it = value_.map_->lower_bound(actualKey); @@ -930,9 +842,6 @@ Value& Value::resolveReference(const char* key, bool isStatic) { it = value_.map_->insert(it, defaultValue); Value& value = (*it).second; return value; -#else - return value_.map_->resolveReference(key, isStatic); -#endif } Value Value::get(ArrayIndex index, const Value& defaultValue) const { @@ -948,16 +857,11 @@ const Value& Value::operator[](const char* key) const { "in Json::Value::operator[](char const*)const: requires objectValue"); if (type_ == nullValue) return null; -#ifndef JSON_VALUE_USE_INTERNAL_MAP CZString actualKey(key, CZString::noDuplication); ObjectValues::const_iterator it = value_.map_->find(actualKey); if (it == value_.map_->end()) return null; return (*it).second; -#else - const Value* value = value_.map_->find(key); - return value ? *value : null; -#endif } Value& Value::operator[](const std::string& key) { @@ -998,7 +902,6 @@ bool Value::removeMember(const char* key, Value* removed) { if (type_ != objectValue) { return false; } -#ifndef JSON_VALUE_USE_INTERNAL_MAP CZString actualKey(key, CZString::noDuplication); ObjectValues::iterator it = value_.map_->find(actualKey); if (it == value_.map_->end()) @@ -1006,16 +909,6 @@ bool Value::removeMember(const char* key, Value* removed) { *removed = it->second; value_.map_->erase(it); return true; -#else - Value* value = value_.map_->find(key); - if (value) { - *removed = *value; - value_.map_.remove(key); - return true; - } else { - return false; - } -#endif } Value Value::removeMember(const char* key) { @@ -1037,10 +930,6 @@ bool Value::removeIndex(ArrayIndex index, Value* removed) { if (type_ != arrayValue) { return false; } -#ifdef JSON_VALUE_USE_INTERNAL_MAP - JSON_FAIL_MESSAGE("removeIndex is not implemented for ValueInternalArray."); - return false; -#else CZString key(index); ObjectValues::iterator it = value_.map_->find(key); if (it == value_.map_->end()) { @@ -1058,7 +947,6 @@ bool Value::removeIndex(ArrayIndex index, Value* removed) { ObjectValues::iterator itLast = value_.map_->find(keyLast); value_.map_->erase(itLast); return true; -#endif } #ifdef JSON_USE_CPPTL @@ -1091,19 +979,10 @@ Value::Members Value::getMemberNames() const { return Value::Members(); Members members; members.reserve(value_.map_->size()); -#ifndef JSON_VALUE_USE_INTERNAL_MAP ObjectValues::const_iterator it = value_.map_->begin(); ObjectValues::const_iterator itEnd = value_.map_->end(); for (; it != itEnd; ++it) members.push_back(std::string((*it).first.c_str())); -#else - ValueInternalMap::IteratorState it; - ValueInternalMap::IteratorState itEnd; - value_.map_->makeBeginIterator(it); - value_.map_->makeEndIterator(itEnd); - for (; !ValueInternalMap::equals(it, itEnd); ValueInternalMap::increment(it)) - members.push_back(std::string(ValueInternalMap::key(it))); -#endif return members; } // @@ -1272,28 +1151,11 @@ std::string Value::toStyledString() const { Value::const_iterator Value::begin() const { switch (type_) { -#ifdef JSON_VALUE_USE_INTERNAL_MAP - case arrayValue: - if (value_.array_) { - ValueInternalArray::IteratorState it; - value_.array_->makeBeginIterator(it); - return const_iterator(it); - } - break; - case objectValue: - if (value_.map_) { - ValueInternalMap::IteratorState it; - value_.map_->makeBeginIterator(it); - return const_iterator(it); - } - break; -#else case arrayValue: case objectValue: if (value_.map_) return const_iterator(value_.map_->begin()); break; -#endif default: break; } @@ -1302,28 +1164,11 @@ Value::const_iterator Value::begin() const { Value::const_iterator Value::end() const { switch (type_) { -#ifdef JSON_VALUE_USE_INTERNAL_MAP - case arrayValue: - if (value_.array_) { - ValueInternalArray::IteratorState it; - value_.array_->makeEndIterator(it); - return const_iterator(it); - } - break; - case objectValue: - if (value_.map_) { - ValueInternalMap::IteratorState it; - value_.map_->makeEndIterator(it); - return const_iterator(it); - } - break; -#else case arrayValue: case objectValue: if (value_.map_) return const_iterator(value_.map_->end()); break; -#endif default: break; } @@ -1332,28 +1177,11 @@ Value::const_iterator Value::end() const { Value::iterator Value::begin() { switch (type_) { -#ifdef JSON_VALUE_USE_INTERNAL_MAP - case arrayValue: - if (value_.array_) { - ValueInternalArray::IteratorState it; - value_.array_->makeBeginIterator(it); - return iterator(it); - } - break; - case objectValue: - if (value_.map_) { - ValueInternalMap::IteratorState it; - value_.map_->makeBeginIterator(it); - return iterator(it); - } - break; -#else case arrayValue: case objectValue: if (value_.map_) return iterator(value_.map_->begin()); break; -#endif default: break; } @@ -1362,28 +1190,11 @@ Value::iterator Value::begin() { Value::iterator Value::end() { switch (type_) { -#ifdef JSON_VALUE_USE_INTERNAL_MAP - case arrayValue: - if (value_.array_) { - ValueInternalArray::IteratorState it; - value_.array_->makeEndIterator(it); - return iterator(it); - } - break; - case objectValue: - if (value_.map_) { - ValueInternalMap::IteratorState it; - value_.map_->makeEndIterator(it); - return iterator(it); - } - break; -#else case arrayValue: case objectValue: if (value_.map_) return iterator(value_.map_->end()); break; -#endif default: break; } diff --git a/src/lib_json/json_valueiterator.inl b/src/lib_json/json_valueiterator.inl index b52c146..3cb9e06 100644 --- a/src/lib_json/json_valueiterator.inl +++ b/src/lib_json/json_valueiterator.inl @@ -16,66 +16,27 @@ namespace Json { // ////////////////////////////////////////////////////////////////// ValueIteratorBase::ValueIteratorBase() -#ifndef JSON_VALUE_USE_INTERNAL_MAP : current_(), isNull_(true) { } -#else - : isArray_(true), isNull_(true) { - iterator_.array_ = ValueInternalArray::IteratorState(); -} -#endif -#ifndef JSON_VALUE_USE_INTERNAL_MAP ValueIteratorBase::ValueIteratorBase( const Value::ObjectValues::iterator& current) : current_(current), isNull_(false) {} -#else -ValueIteratorBase::ValueIteratorBase( - const ValueInternalArray::IteratorState& state) - : isArray_(true) { - iterator_.array_ = state; -} - -ValueIteratorBase::ValueIteratorBase( - const ValueInternalMap::IteratorState& state) - : isArray_(false) { - iterator_.map_ = state; -} -#endif Value& ValueIteratorBase::deref() const { -#ifndef JSON_VALUE_USE_INTERNAL_MAP return current_->second; -#else - if (isArray_) - return ValueInternalArray::dereference(iterator_.array_); - return ValueInternalMap::value(iterator_.map_); -#endif } void ValueIteratorBase::increment() { -#ifndef JSON_VALUE_USE_INTERNAL_MAP ++current_; -#else - if (isArray_) - ValueInternalArray::increment(iterator_.array_); - ValueInternalMap::increment(iterator_.map_); -#endif } void ValueIteratorBase::decrement() { -#ifndef JSON_VALUE_USE_INTERNAL_MAP --current_; -#else - if (isArray_) - ValueInternalArray::decrement(iterator_.array_); - ValueInternalMap::decrement(iterator_.map_); -#endif } ValueIteratorBase::difference_type ValueIteratorBase::computeDistance(const SelfType& other) const { -#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifdef JSON_USE_CPPTL_SMALLMAP return other.current_ - current_; #else @@ -100,40 +61,21 @@ ValueIteratorBase::computeDistance(const SelfType& other) const { } return myDistance; #endif -#else - if (isArray_) - return ValueInternalArray::distance(iterator_.array_, - other.iterator_.array_); - return ValueInternalMap::distance(iterator_.map_, other.iterator_.map_); -#endif } bool ValueIteratorBase::isEqual(const SelfType& other) const { -#ifndef JSON_VALUE_USE_INTERNAL_MAP if (isNull_) { return other.isNull_; } return current_ == other.current_; -#else - if (isArray_) - return ValueInternalArray::equals(iterator_.array_, other.iterator_.array_); - return ValueInternalMap::equals(iterator_.map_, other.iterator_.map_); -#endif } void ValueIteratorBase::copy(const SelfType& other) { -#ifndef JSON_VALUE_USE_INTERNAL_MAP current_ = other.current_; isNull_ = other.isNull_; -#else - if (isArray_) - iterator_.array_ = other.iterator_.array_; - iterator_.map_ = other.iterator_.map_; -#endif } Value ValueIteratorBase::key() const { -#ifndef JSON_VALUE_USE_INTERNAL_MAP const Value::CZString czstring = (*current_).first; if (czstring.c_str()) { if (czstring.isStaticString()) @@ -141,39 +83,18 @@ Value ValueIteratorBase::key() const { return Value(czstring.c_str()); } return Value(czstring.index()); -#else - if (isArray_) - return Value(ValueInternalArray::indexOf(iterator_.array_)); - bool isStatic; - const char* memberName = ValueInternalMap::key(iterator_.map_, isStatic); - if (isStatic) - return Value(StaticString(memberName)); - return Value(memberName); -#endif } UInt ValueIteratorBase::index() const { -#ifndef JSON_VALUE_USE_INTERNAL_MAP const Value::CZString czstring = (*current_).first; if (!czstring.c_str()) return czstring.index(); return Value::UInt(-1); -#else - if (isArray_) - return Value::UInt(ValueInternalArray::indexOf(iterator_.array_)); - return Value::UInt(-1); -#endif } const char* ValueIteratorBase::memberName() const { -#ifndef JSON_VALUE_USE_INTERNAL_MAP const char* name = (*current_).first.c_str(); return name ? name : ""; -#else - if (!isArray_) - return ValueInternalMap::key(iterator_.map_); - return ""; -#endif } // ////////////////////////////////////////////////////////////////// @@ -186,19 +107,9 @@ const char* ValueIteratorBase::memberName() const { ValueConstIterator::ValueConstIterator() {} -#ifndef JSON_VALUE_USE_INTERNAL_MAP ValueConstIterator::ValueConstIterator( const Value::ObjectValues::iterator& current) : ValueIteratorBase(current) {} -#else -ValueConstIterator::ValueConstIterator( - const ValueInternalArray::IteratorState& state) - : ValueIteratorBase(state) {} - -ValueConstIterator::ValueConstIterator( - const ValueInternalMap::IteratorState& state) - : ValueIteratorBase(state) {} -#endif ValueConstIterator& ValueConstIterator:: operator=(const ValueIteratorBase& other) { @@ -216,16 +127,8 @@ operator=(const ValueIteratorBase& other) { ValueIterator::ValueIterator() {} -#ifndef JSON_VALUE_USE_INTERNAL_MAP ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current) : ValueIteratorBase(current) {} -#else -ValueIterator::ValueIterator(const ValueInternalArray::IteratorState& state) - : ValueIteratorBase(state) {} - -ValueIterator::ValueIterator(const ValueInternalMap::IteratorState& state) - : ValueIteratorBase(state) {} -#endif ValueIterator::ValueIterator(const ValueConstIterator& other) : ValueIteratorBase(other) {}