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