15 ValueInternalLink::ValueInternalLink()
25 if ( !
items_[index].isItemAvailable() )
27 if ( !
items_[index].isMemberNameStatic() )
41 #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
50 virtual ValueInternalMap *newMapCopy(
const ValueInternalMap &other )
52 return new ValueInternalMap( other );
55 virtual void destructMap( ValueInternalMap *map )
60 virtual ValueInternalLink *allocateMapBuckets(
unsigned int size )
62 return new ValueInternalLink[size];
65 virtual void releaseMapBuckets( ValueInternalLink *links )
70 virtual ValueInternalLink *allocateMapLink()
72 return new ValueInternalLink();
75 virtual void releaseMapLink( ValueInternalLink *link )
82 class DefaultValueMapAllocator :
public ValueMapAllocator
85 virtual ValueInternalMap *newMap()
87 ValueInternalMap *map = mapsAllocator_.allocate();
88 new (map) ValueInternalMap();
92 virtual ValueInternalMap *newMapCopy(
const ValueInternalMap &other )
94 ValueInternalMap *map = mapsAllocator_.allocate();
95 new (map) ValueInternalMap( other );
99 virtual void destructMap( ValueInternalMap *map )
103 map->~ValueInternalMap();
104 mapsAllocator_.release( map );
108 virtual ValueInternalLink *allocateMapBuckets(
unsigned int size )
110 return new ValueInternalLink[size];
113 virtual void releaseMapBuckets( ValueInternalLink *links )
118 virtual ValueInternalLink *allocateMapLink()
120 ValueInternalLink *link = linksAllocator_.allocate();
121 memset( link, 0,
sizeof(ValueInternalLink) );
125 virtual void releaseMapLink( ValueInternalLink *link )
127 link->~ValueInternalLink();
128 linksAllocator_.release( link );
131 BatchAllocator<ValueInternalMap,1> mapsAllocator_;
132 BatchAllocator<ValueInternalLink,1> linksAllocator_;
138 static DefaultValueMapAllocator defaultAllocator;
139 static ValueMapAllocator *
mapAllocator = &defaultAllocator;
143 static struct DummyMapAllocatorInitializer {
144 DummyMapAllocatorInitializer()
180 other.makeBeginIterator( it );
181 other.makeEndIterator( itEnd );
182 for ( ; !equals(it,itEnd); increment(it) )
185 const char *memberName = key( it, isStatic );
186 const Value &aValue = value( it );
205 for (
BucketIndex bucketIndex =0; bucketIndex < bucketsSize_; ++bucketIndex )
224 buckets_ = other.buckets_;
225 other.buckets_ = tempBuckets;
227 tailLink_ = other.tailLink_;
228 other.tailLink_ = tempTailLink;
230 bucketsSize_ = other.bucketsSize_;
231 other.bucketsSize_ = tempBucketsSize;
233 itemCount_ = other.itemCount_;
234 other.itemCount_ = tempItemCount;
255 return reserve( itemCount_ + growth );
261 if ( !buckets_ && newItemCount > 0 )
265 tailLink_ = &buckets_[0];
278 BucketIndex bucketIndex = hashedKey % bucketsSize_;
281 current = current->
next_ )
285 if ( current->items_[index].isItemAvailable() )
287 if ( strcmp( key, current->keys_[index] ) == 0 )
288 return ¤t->items_[index];
299 return const_cast<Value *
>( constThis->
find( key ) );
310 BucketIndex bucketIndex = hashedKey % bucketsSize_;
315 previous = ¤t->
next_, current = current->
next_ )
319 if ( current->items_[index].isItemAvailable() )
320 return setNewItem( key, isStatic, current, index );
321 if ( strcmp( key, current->keys_[index] ) == 0 )
322 return current->items_[index];
328 return unsafeAdd( key, isStatic, hashedKey );
338 BucketIndex bucketIndex = hashedKey % bucketsSize_;
346 if ( link->items_[index].isItemAvailable() )
348 if ( strcmp( key, link->keys_[index] ) == 0 )
371 if ( lastLink->
items_[lastItemIndex].isItemAvailable() )
377 Value *valueToPreserve = &lastLink->
items_[lastUsedIndex];
378 if ( valueToDelete != valueToPreserve )
379 valueToDelete->
swap( *valueToPreserve );
380 if ( lastUsedIndex == 0 )
383 if ( linkPreviousToLast != 0 )
386 linkPreviousToLast->
next_ = 0;
387 lastLink = linkPreviousToLast;
393 valueToPreserve->
swap( dummy );
394 valueToPreserve->setItemUsed(
false );
403 if ( bucketIndex == bucketsSize_ - 1 )
407 previous = &buckets_[bucketIndex];
420 link->
keys_[index] = duplicatedKey;
421 link->
items_[index].setItemUsed();
422 link->
items_[index].setMemberNameIsStatic( isStatic );
423 return link->
items_[index];
432 JSON_ASSERT_MESSAGE( bucketsSize_ > 0,
"ValueInternalMap::unsafeAdd(): internal logic error." );
433 BucketIndex bucketIndex = hashedKey % bucketsSize_;
439 if ( link->
items_[index].isItemAvailable() )
442 if ( index == ValueInternalLink::itemPerLink )
446 link->
next_ = newLink;
447 previousLink = newLink;
450 return setNewItem( key, isStatic, link, index );
467 int sizeDiff( itemCount_ - other.itemCount_ );
473 makeBeginIterator( it );
474 makeEndIterator( itEnd );
475 for ( ; !equals(it,itEnd); increment(it) )
477 if ( !other.
find( key( it ) ) )
482 makeBeginIterator( it );
483 for ( ; !equals(it,itEnd); increment(it) )
485 const Value *otherValue = other.
find( key( it ) );
486 int valueDiff = value(it).
compare( *otherValue );
487 if ( valueDiff != 0 )
495 ValueInternalMap::makeBeginIterator( IteratorState &it )
const
505 ValueInternalMap::makeEndIterator( IteratorState &it )
const
508 it.bucketIndex_ = bucketsSize_;
515 ValueInternalMap::equals(
const IteratorState &x,
const IteratorState &other )
517 return x.map_ == other.map_
518 && x.bucketIndex_ == other.bucketIndex_
519 && x.link_ == other.link_
520 && x.itemIndex_ == other.itemIndex_;
525 ValueInternalMap::incrementBucket( IteratorState &iterator )
527 ++iterator.bucketIndex_;
529 "ValueInternalMap::increment(): attempting to iterate beyond end." );
530 if ( iterator.bucketIndex_ == iterator.map_->bucketsSize_ )
533 iterator.link_ = &(iterator.map_->buckets_[iterator.bucketIndex_]);
534 iterator.itemIndex_ = 0;
539 ValueInternalMap::increment( IteratorState &iterator )
542 ++iterator.itemIndex_;
543 if ( iterator.itemIndex_ == ValueInternalLink::itemPerLink )
546 "ValueInternalMap::increment(): attempting to iterate beyond end." );
547 iterator.link_ = iterator.link_->next_;
548 if ( iterator.link_ == 0 )
549 incrementBucket( iterator );
551 else if ( iterator.link_->items_[iterator.itemIndex_].isItemAvailable() )
553 incrementBucket( iterator );
559 ValueInternalMap::decrement( IteratorState &iterator )
561 if ( iterator.itemIndex_ == 0 )
564 if ( iterator.link_ == &iterator.map_->buckets_[iterator.bucketIndex_] )
566 JSON_ASSERT_MESSAGE( iterator.bucketIndex_ > 0,
"Attempting to iterate beyond beginning." );
567 --(iterator.bucketIndex_);
569 iterator.link_ = iterator.link_->previous_;
570 iterator.itemIndex_ = ValueInternalLink::itemPerLink - 1;
576 ValueInternalMap::key(
const IteratorState &iterator )
579 return iterator.link_->keys_[iterator.itemIndex_];
583 ValueInternalMap::key(
const IteratorState &iterator,
bool &isStatic )
586 isStatic = iterator.link_->items_[iterator.itemIndex_].isMemberNameStatic();
587 return iterator.link_->keys_[iterator.itemIndex_];
592 ValueInternalMap::value(
const IteratorState &iterator )
595 return iterator.link_->items_[iterator.itemIndex_];
600 ValueInternalMap::distance(
const IteratorState &x,
const IteratorState &y )
603 IteratorState it = x;
604 while ( !equals( it, y ) )