00001
00002
00003
00004
00005
00006
00007
00008 namespace Json {
00009
00010
00011
00012
00013
00014
00015
00016
00017
00021 ValueInternalLink::ValueInternalLink()
00022 : previous_( 0 )
00023 , next_( 0 )
00024 {
00025 }
00026
00027 ValueInternalLink::~ValueInternalLink()
00028 {
00029 for ( int index =0; index < itemPerLink; ++index )
00030 {
00031 if ( !items_[index].isItemAvailable() )
00032 {
00033 if ( !items_[index].isMemberNameStatic() )
00034 free( keys_[index] );
00035 }
00036 else
00037 break;
00038 }
00039 }
00040
00041
00042
00043 ValueMapAllocator::~ValueMapAllocator()
00044 {
00045 }
00046
00047 #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
00048 class DefaultValueMapAllocator : public ValueMapAllocator
00049 {
00050 public:
00051 virtual ValueInternalMap *newMap()
00052 {
00053 return new ValueInternalMap();
00054 }
00055
00056 virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
00057 {
00058 return new ValueInternalMap( other );
00059 }
00060
00061 virtual void destructMap( ValueInternalMap *map )
00062 {
00063 delete map;
00064 }
00065
00066 virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
00067 {
00068 return new ValueInternalLink[size];
00069 }
00070
00071 virtual void releaseMapBuckets( ValueInternalLink *links )
00072 {
00073 delete [] links;
00074 }
00075
00076 virtual ValueInternalLink *allocateMapLink()
00077 {
00078 return new ValueInternalLink();
00079 }
00080
00081 virtual void releaseMapLink( ValueInternalLink *link )
00082 {
00083 delete link;
00084 }
00085 };
00086 #else
00088 class DefaultValueMapAllocator : public ValueMapAllocator
00089 {
00090 public:
00091 virtual ValueInternalMap *newMap()
00092 {
00093 ValueInternalMap *map = mapsAllocator_.allocate();
00094 new (map) ValueInternalMap();
00095 return map;
00096 }
00097
00098 virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
00099 {
00100 ValueInternalMap *map = mapsAllocator_.allocate();
00101 new (map) ValueInternalMap( other );
00102 return map;
00103 }
00104
00105 virtual void destructMap( ValueInternalMap *map )
00106 {
00107 if ( map )
00108 {
00109 map->~ValueInternalMap();
00110 mapsAllocator_.release( map );
00111 }
00112 }
00113
00114 virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
00115 {
00116 return new ValueInternalLink[size];
00117 }
00118
00119 virtual void releaseMapBuckets( ValueInternalLink *links )
00120 {
00121 delete [] links;
00122 }
00123
00124 virtual ValueInternalLink *allocateMapLink()
00125 {
00126 ValueInternalLink *link = linksAllocator_.allocate();
00127 memset( link, 0, sizeof(ValueInternalLink) );
00128 return link;
00129 }
00130
00131 virtual void releaseMapLink( ValueInternalLink *link )
00132 {
00133 link->~ValueInternalLink();
00134 linksAllocator_.release( link );
00135 }
00136 private:
00137 BatchAllocator<ValueInternalMap,1> mapsAllocator_;
00138 BatchAllocator<ValueInternalLink,1> linksAllocator_;
00139 };
00140 #endif
00141
00142 static ValueMapAllocator *&mapAllocator()
00143 {
00144 static DefaultValueMapAllocator defaultAllocator;
00145 static ValueMapAllocator *mapAllocator = &defaultAllocator;
00146 return mapAllocator;
00147 }
00148
00149 static struct DummyMapAllocatorInitializer {
00150 DummyMapAllocatorInitializer()
00151 {
00152 mapAllocator();
00153 }
00154 } dummyMapAllocatorInitializer;
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 ValueInternalMap::ValueInternalMap()
00169 : buckets_( 0 )
00170 , tailLink_( 0 )
00171 , bucketsSize_( 0 )
00172 , itemCount_( 0 )
00173 {
00174 }
00175
00176
00177 ValueInternalMap::ValueInternalMap( const ValueInternalMap &other )
00178 : buckets_( 0 )
00179 , tailLink_( 0 )
00180 , bucketsSize_( 0 )
00181 , itemCount_( 0 )
00182 {
00183 reserve( other.itemCount_ );
00184 IteratorState it;
00185 IteratorState itEnd;
00186 other.makeBeginIterator( it );
00187 other.makeEndIterator( itEnd );
00188 for ( ; !equals(it,itEnd); increment(it) )
00189 {
00190 bool isStatic;
00191 const char *memberName = key( it, isStatic );
00192 const Value &aValue = value( it );
00193 resolveReference(memberName, isStatic) = aValue;
00194 }
00195 }
00196
00197
00198 ValueInternalMap &
00199 ValueInternalMap::operator =( const ValueInternalMap &other )
00200 {
00201 ValueInternalMap dummy( other );
00202 swap( dummy );
00203 return *this;
00204 }
00205
00206
00207 ValueInternalMap::~ValueInternalMap()
00208 {
00209 if ( buckets_ )
00210 {
00211 for ( BucketIndex bucketIndex =0; bucketIndex < bucketsSize_; ++bucketIndex )
00212 {
00213 ValueInternalLink *link = buckets_[bucketIndex].next_;
00214 while ( link )
00215 {
00216 ValueInternalLink *linkToRelease = link;
00217 link = link->next_;
00218 mapAllocator()->releaseMapLink( linkToRelease );
00219 }
00220 }
00221 mapAllocator()->releaseMapBuckets( buckets_ );
00222 }
00223 }
00224
00225
00226 void
00227 ValueInternalMap::swap( ValueInternalMap &other )
00228 {
00229 ValueInternalLink *tempBuckets = buckets_;
00230 buckets_ = other.buckets_;
00231 other.buckets_ = tempBuckets;
00232 ValueInternalLink *tempTailLink = tailLink_;
00233 tailLink_ = other.tailLink_;
00234 other.tailLink_ = tempTailLink;
00235 BucketIndex tempBucketsSize = bucketsSize_;
00236 bucketsSize_ = other.bucketsSize_;
00237 other.bucketsSize_ = tempBucketsSize;
00238 BucketIndex tempItemCount = itemCount_;
00239 itemCount_ = other.itemCount_;
00240 other.itemCount_ = tempItemCount;
00241 }
00242
00243
00244 void
00245 ValueInternalMap::clear()
00246 {
00247 ValueInternalMap dummy;
00248 swap( dummy );
00249 }
00250
00251
00252 ValueInternalMap::BucketIndex
00253 ValueInternalMap::size() const
00254 {
00255 return itemCount_;
00256 }
00257
00258 bool
00259 ValueInternalMap::reserveDelta( BucketIndex growth )
00260 {
00261 return reserve( itemCount_ + growth );
00262 }
00263
00264 bool
00265 ValueInternalMap::reserve( BucketIndex newItemCount )
00266 {
00267 if ( !buckets_ && newItemCount > 0 )
00268 {
00269 buckets_ = mapAllocator()->allocateMapBuckets( 1 );
00270 bucketsSize_ = 1;
00271 tailLink_ = &buckets_[0];
00272 }
00273
00274 return true;
00275 }
00276
00277
00278 const Value *
00279 ValueInternalMap::find( const char *key ) const
00280 {
00281 if ( !bucketsSize_ )
00282 return 0;
00283 HashKey hashedKey = hash( key );
00284 BucketIndex bucketIndex = hashedKey % bucketsSize_;
00285 for ( const ValueInternalLink *current = &buckets_[bucketIndex];
00286 current != 0;
00287 current = current->next_ )
00288 {
00289 for ( BucketIndex index=0; index < ValueInternalLink::itemPerLink; ++index )
00290 {
00291 if ( current->items_[index].isItemAvailable() )
00292 return 0;
00293 if ( strcmp( key, current->keys_[index] ) == 0 )
00294 return ¤t->items_[index];
00295 }
00296 }
00297 return 0;
00298 }
00299
00300
00301 Value *
00302 ValueInternalMap::find( const char *key )
00303 {
00304 const ValueInternalMap *constThis = this;
00305 return const_cast<Value *>( constThis->find( key ) );
00306 }
00307
00308
00309 Value &
00310 ValueInternalMap::resolveReference( const char *key,
00311 bool isStatic )
00312 {
00313 HashKey hashedKey = hash( key );
00314 if ( bucketsSize_ )
00315 {
00316 BucketIndex bucketIndex = hashedKey % bucketsSize_;
00317 ValueInternalLink **previous = 0;
00318 BucketIndex index;
00319 for ( ValueInternalLink *current = &buckets_[bucketIndex];
00320 current != 0;
00321 previous = ¤t->next_, current = current->next_ )
00322 {
00323 for ( index=0; index < ValueInternalLink::itemPerLink; ++index )
00324 {
00325 if ( current->items_[index].isItemAvailable() )
00326 return setNewItem( key, isStatic, current, index );
00327 if ( strcmp( key, current->keys_[index] ) == 0 )
00328 return current->items_[index];
00329 }
00330 }
00331 }
00332
00333 reserveDelta( 1 );
00334 return unsafeAdd( key, isStatic, hashedKey );
00335 }
00336
00337
00338 void
00339 ValueInternalMap::remove( const char *key )
00340 {
00341 HashKey hashedKey = hash( key );
00342 if ( !bucketsSize_ )
00343 return;
00344 BucketIndex bucketIndex = hashedKey % bucketsSize_;
00345 for ( ValueInternalLink *link = &buckets_[bucketIndex];
00346 link != 0;
00347 link = link->next_ )
00348 {
00349 BucketIndex index;
00350 for ( index =0; index < ValueInternalLink::itemPerLink; ++index )
00351 {
00352 if ( link->items_[index].isItemAvailable() )
00353 return;
00354 if ( strcmp( key, link->keys_[index] ) == 0 )
00355 {
00356 doActualRemove( link, index, bucketIndex );
00357 return;
00358 }
00359 }
00360 }
00361 }
00362
00363 void
00364 ValueInternalMap::doActualRemove( ValueInternalLink *link,
00365 BucketIndex index,
00366 BucketIndex bucketIndex )
00367 {
00368
00369
00370
00371 ValueInternalLink *&lastLink = getLastLinkInBucket( index );
00372 BucketIndex lastItemIndex = 1;
00373 for ( ;
00374 lastItemIndex < ValueInternalLink::itemPerLink;
00375 ++lastItemIndex )
00376 {
00377 if ( lastLink->items_[lastItemIndex].isItemAvailable() )
00378 break;
00379 }
00380
00381 BucketIndex lastUsedIndex = lastItemIndex - 1;
00382 Value *valueToDelete = &link->items_[index];
00383 Value *valueToPreserve = &lastLink->items_[lastUsedIndex];
00384 if ( valueToDelete != valueToPreserve )
00385 valueToDelete->swap( *valueToPreserve );
00386 if ( lastUsedIndex == 0 )
00387 {
00388 ValueInternalLink *linkPreviousToLast = lastLink->previous_;
00389 if ( linkPreviousToLast != 0 )
00390 {
00391 mapAllocator()->releaseMapLink( lastLink );
00392 linkPreviousToLast->next_ = 0;
00393 lastLink = linkPreviousToLast;
00394 }
00395 }
00396 else
00397 {
00398 Value dummy;
00399 valueToPreserve->swap( dummy );
00400 valueToPreserve->setItemUsed( false );
00401 }
00402 --itemCount_;
00403 }
00404
00405
00406 ValueInternalLink *&
00407 ValueInternalMap::getLastLinkInBucket( BucketIndex bucketIndex )
00408 {
00409 if ( bucketIndex == bucketsSize_ - 1 )
00410 return tailLink_;
00411 ValueInternalLink *&previous = buckets_[bucketIndex+1].previous_;
00412 if ( !previous )
00413 previous = &buckets_[bucketIndex];
00414 return previous;
00415 }
00416
00417
00418 Value &
00419 ValueInternalMap::setNewItem( const char *key,
00420 bool isStatic,
00421 ValueInternalLink *link,
00422 BucketIndex index )
00423 {
00424 char *duplicatedKey = makeMemberName( key );
00425 ++itemCount_;
00426 link->keys_[index] = duplicatedKey;
00427 link->items_[index].setItemUsed();
00428 link->items_[index].setMemberNameIsStatic( isStatic );
00429 return link->items_[index];
00430 }
00431
00432
00433 Value &
00434 ValueInternalMap::unsafeAdd( const char *key,
00435 bool isStatic,
00436 HashKey hashedKey )
00437 {
00438 JSON_ASSERT_MESSAGE( bucketsSize_ > 0, "ValueInternalMap::unsafeAdd(): internal logic error." );
00439 BucketIndex bucketIndex = hashedKey % bucketsSize_;
00440 ValueInternalLink *&previousLink = getLastLinkInBucket( bucketIndex );
00441 ValueInternalLink *link = previousLink;
00442 BucketIndex index;
00443 for ( index =0; index < ValueInternalLink::itemPerLink; ++index )
00444 {
00445 if ( link->items_[index].isItemAvailable() )
00446 break;
00447 }
00448 if ( index == ValueInternalLink::itemPerLink )
00449 {
00450 ValueInternalLink *newLink = mapAllocator()->allocateMapLink();
00451 index = 0;
00452 link->next_ = newLink;
00453 previousLink = newLink;
00454 link = newLink;
00455 }
00456 return setNewItem( key, isStatic, link, index );
00457 }
00458
00459
00460 ValueInternalMap::HashKey
00461 ValueInternalMap::hash( const char *key ) const
00462 {
00463 HashKey hash = 0;
00464 while ( *key )
00465 hash += *key++ * 37;
00466 return hash;
00467 }
00468
00469
00470 int
00471 ValueInternalMap::compare( const ValueInternalMap &other ) const
00472 {
00473 int sizeDiff( itemCount_ - other.itemCount_ );
00474 if ( sizeDiff != 0 )
00475 return sizeDiff;
00476
00477 IteratorState it;
00478 IteratorState itEnd;
00479 makeBeginIterator( it );
00480 makeEndIterator( itEnd );
00481 for ( ; !equals(it,itEnd); increment(it) )
00482 {
00483 if ( !other.find( key( it ) ) )
00484 return 1;
00485 }
00486
00487
00488 makeBeginIterator( it );
00489 for ( ; !equals(it,itEnd); increment(it) )
00490 {
00491 const Value *otherValue = other.find( key( it ) );
00492 int valueDiff = value(it).compare( *otherValue );
00493 if ( valueDiff != 0 )
00494 return valueDiff;
00495 }
00496 return 0;
00497 }
00498
00499
00500 void
00501 ValueInternalMap::makeBeginIterator( IteratorState &it ) const
00502 {
00503 it.map_ = const_cast<ValueInternalMap *>( this );
00504 it.bucketIndex_ = 0;
00505 it.itemIndex_ = 0;
00506 it.link_ = buckets_;
00507 }
00508
00509
00510 void
00511 ValueInternalMap::makeEndIterator( IteratorState &it ) const
00512 {
00513 it.map_ = const_cast<ValueInternalMap *>( this );
00514 it.bucketIndex_ = bucketsSize_;
00515 it.itemIndex_ = 0;
00516 it.link_ = 0;
00517 }
00518
00519
00520 bool
00521 ValueInternalMap::equals( const IteratorState &x, const IteratorState &other )
00522 {
00523 return x.map_ == other.map_
00524 && x.bucketIndex_ == other.bucketIndex_
00525 && x.link_ == other.link_
00526 && x.itemIndex_ == other.itemIndex_;
00527 }
00528
00529
00530 void
00531 ValueInternalMap::incrementBucket( IteratorState &iterator )
00532 {
00533 ++iterator.bucketIndex_;
00534 JSON_ASSERT_MESSAGE( iterator.bucketIndex_ <= iterator.map_->bucketsSize_,
00535 "ValueInternalMap::increment(): attempting to iterate beyond end." );
00536 if ( iterator.bucketIndex_ == iterator.map_->bucketsSize_ )
00537 iterator.link_ = 0;
00538 else
00539 iterator.link_ = &(iterator.map_->buckets_[iterator.bucketIndex_]);
00540 iterator.itemIndex_ = 0;
00541 }
00542
00543
00544 void
00545 ValueInternalMap::increment( IteratorState &iterator )
00546 {
00547 JSON_ASSERT_MESSAGE( iterator.map_, "Attempting to iterator using invalid iterator." );
00548 ++iterator.itemIndex_;
00549 if ( iterator.itemIndex_ == ValueInternalLink::itemPerLink )
00550 {
00551 JSON_ASSERT_MESSAGE( iterator.link_ != 0,
00552 "ValueInternalMap::increment(): attempting to iterate beyond end." );
00553 iterator.link_ = iterator.link_->next_;
00554 if ( iterator.link_ == 0 )
00555 incrementBucket( iterator );
00556 }
00557 else if ( iterator.link_->items_[iterator.itemIndex_].isItemAvailable() )
00558 {
00559 incrementBucket( iterator );
00560 }
00561 }
00562
00563
00564 void
00565 ValueInternalMap::decrement( IteratorState &iterator )
00566 {
00567 if ( iterator.itemIndex_ == 0 )
00568 {
00569 JSON_ASSERT_MESSAGE( iterator.map_, "Attempting to iterate using invalid iterator." );
00570 if ( iterator.link_ == &iterator.map_->buckets_[iterator.bucketIndex_] )
00571 {
00572 JSON_ASSERT_MESSAGE( iterator.bucketIndex_ > 0, "Attempting to iterate beyond beginning." );
00573 --(iterator.bucketIndex_);
00574 }
00575 iterator.link_ = iterator.link_->previous_;
00576 iterator.itemIndex_ = ValueInternalLink::itemPerLink - 1;
00577 }
00578 }
00579
00580
00581 const char *
00582 ValueInternalMap::key( const IteratorState &iterator )
00583 {
00584 JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." );
00585 return iterator.link_->keys_[iterator.itemIndex_];
00586 }
00587
00588 const char *
00589 ValueInternalMap::key( const IteratorState &iterator, bool &isStatic )
00590 {
00591 JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." );
00592 isStatic = iterator.link_->items_[iterator.itemIndex_].isMemberNameStatic();
00593 return iterator.link_->keys_[iterator.itemIndex_];
00594 }
00595
00596
00597 Value &
00598 ValueInternalMap::value( const IteratorState &iterator )
00599 {
00600 JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." );
00601 return iterator.link_->items_[iterator.itemIndex_];
00602 }
00603
00604
00605 int
00606 ValueInternalMap::distance( const IteratorState &x, const IteratorState &y )
00607 {
00608 int offset = 0;
00609 IteratorState it = x;
00610 while ( !equals( it, y ) )
00611 increment( it );
00612 return offset;
00613 }
00614
00615 }