json_internalmap.inl 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. // included by json_value.cpp
  2. // everything is within Json namespace
  3. // //////////////////////////////////////////////////////////////////
  4. // //////////////////////////////////////////////////////////////////
  5. // //////////////////////////////////////////////////////////////////
  6. // class ValueInternalMap
  7. // //////////////////////////////////////////////////////////////////
  8. // //////////////////////////////////////////////////////////////////
  9. // //////////////////////////////////////////////////////////////////
  10. /** \internal MUST be safely initialized using memset( this, 0, sizeof(ValueInternalLink) );
  11. * This optimization is used by the fast allocator.
  12. */
  13. ValueInternalLink::ValueInternalLink()
  14. : previous_( 0 )
  15. , next_( 0 )
  16. {
  17. }
  18. ValueInternalLink::~ValueInternalLink()
  19. {
  20. for ( int index =0; index < itemPerLink; ++index )
  21. {
  22. if ( !items_[index].isItemAvailable() )
  23. {
  24. if ( !items_[index].isMemberNameStatic() )
  25. free( keys_[index] );
  26. }
  27. else
  28. break;
  29. }
  30. }
  31. ValueMapAllocator::~ValueMapAllocator()
  32. {
  33. }
  34. #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
  35. class DefaultValueMapAllocator : public ValueMapAllocator
  36. {
  37. public: // overridden from ValueMapAllocator
  38. virtual ValueInternalMap *newMap()
  39. {
  40. return new ValueInternalMap();
  41. }
  42. virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
  43. {
  44. return new ValueInternalMap( other );
  45. }
  46. virtual void destructMap( ValueInternalMap *map )
  47. {
  48. delete map;
  49. }
  50. virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
  51. {
  52. return new ValueInternalLink[size];
  53. }
  54. virtual void releaseMapBuckets( ValueInternalLink *links )
  55. {
  56. delete [] links;
  57. }
  58. virtual ValueInternalLink *allocateMapLink()
  59. {
  60. return new ValueInternalLink();
  61. }
  62. virtual void releaseMapLink( ValueInternalLink *link )
  63. {
  64. delete link;
  65. }
  66. };
  67. #else
  68. /// @todo make this thread-safe (lock when accessign batch allocator)
  69. class DefaultValueMapAllocator : public ValueMapAllocator
  70. {
  71. public: // overridden from ValueMapAllocator
  72. virtual ValueInternalMap *newMap()
  73. {
  74. ValueInternalMap *map = mapsAllocator_.allocate();
  75. new (map) ValueInternalMap(); // placement new
  76. return map;
  77. }
  78. virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
  79. {
  80. ValueInternalMap *map = mapsAllocator_.allocate();
  81. new (map) ValueInternalMap( other ); // placement new
  82. return map;
  83. }
  84. virtual void destructMap( ValueInternalMap *map )
  85. {
  86. if ( map )
  87. {
  88. map->~ValueInternalMap();
  89. mapsAllocator_.release( map );
  90. }
  91. }
  92. virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
  93. {
  94. return new ValueInternalLink[size];
  95. }
  96. virtual void releaseMapBuckets( ValueInternalLink *links )
  97. {
  98. delete [] links;
  99. }
  100. virtual ValueInternalLink *allocateMapLink()
  101. {
  102. ValueInternalLink *link = linksAllocator_.allocate();
  103. memset( link, 0, sizeof(ValueInternalLink) );
  104. return link;
  105. }
  106. virtual void releaseMapLink( ValueInternalLink *link )
  107. {
  108. link->~ValueInternalLink();
  109. linksAllocator_.release( link );
  110. }
  111. private:
  112. BatchAllocator<ValueInternalMap,1> mapsAllocator_;
  113. BatchAllocator<ValueInternalLink,1> linksAllocator_;
  114. };
  115. #endif
  116. static ValueMapAllocator *&mapAllocator()
  117. {
  118. static DefaultValueMapAllocator defaultAllocator;
  119. static ValueMapAllocator *mapAllocator = &defaultAllocator;
  120. return mapAllocator;
  121. }
  122. static struct DummyMapAllocatorInitializer {
  123. DummyMapAllocatorInitializer()
  124. {
  125. mapAllocator(); // ensure mapAllocator() statics are initialized before main().
  126. }
  127. } dummyMapAllocatorInitializer;
  128. // h(K) = value * K >> w ; with w = 32 & K prime w.r.t. 2^32.
  129. /*
  130. use linked list hash map.
  131. buckets array is a container.
  132. linked list element contains 6 key/values. (memory = (16+4) * 6 + 4 = 124)
  133. value have extra state: valid, available, deleted
  134. */
  135. ValueInternalMap::ValueInternalMap()
  136. : buckets_( 0 )
  137. , tailLink_( 0 )
  138. , bucketsSize_( 0 )
  139. , itemCount_( 0 )
  140. {
  141. }
  142. ValueInternalMap::ValueInternalMap( const ValueInternalMap &other )
  143. : buckets_( 0 )
  144. , tailLink_( 0 )
  145. , bucketsSize_( 0 )
  146. , itemCount_( 0 )
  147. {
  148. reserve( other.itemCount_ );
  149. IteratorState it;
  150. IteratorState itEnd;
  151. other.makeBeginIterator( it );
  152. other.makeEndIterator( itEnd );
  153. for ( ; !equals(it,itEnd); increment(it) )
  154. {
  155. bool isStatic;
  156. const char *memberName = key( it, isStatic );
  157. const Value &aValue = value( it );
  158. resolveReference(memberName, isStatic) = aValue;
  159. }
  160. }
  161. ValueInternalMap &
  162. ValueInternalMap::operator =( const ValueInternalMap &other )
  163. {
  164. ValueInternalMap dummy( other );
  165. swap( dummy );
  166. return *this;
  167. }
  168. ValueInternalMap::~ValueInternalMap()
  169. {
  170. if ( buckets_ )
  171. {
  172. for ( BucketIndex bucketIndex =0; bucketIndex < bucketsSize_; ++bucketIndex )
  173. {
  174. ValueInternalLink *link = buckets_[bucketIndex].next_;
  175. while ( link )
  176. {
  177. ValueInternalLink *linkToRelease = link;
  178. link = link->next_;
  179. mapAllocator()->releaseMapLink( linkToRelease );
  180. }
  181. }
  182. mapAllocator()->releaseMapBuckets( buckets_ );
  183. }
  184. }
  185. void
  186. ValueInternalMap::swap( ValueInternalMap &other )
  187. {
  188. ValueInternalLink *tempBuckets = buckets_;
  189. buckets_ = other.buckets_;
  190. other.buckets_ = tempBuckets;
  191. ValueInternalLink *tempTailLink = tailLink_;
  192. tailLink_ = other.tailLink_;
  193. other.tailLink_ = tempTailLink;
  194. BucketIndex tempBucketsSize = bucketsSize_;
  195. bucketsSize_ = other.bucketsSize_;
  196. other.bucketsSize_ = tempBucketsSize;
  197. BucketIndex tempItemCount = itemCount_;
  198. itemCount_ = other.itemCount_;
  199. other.itemCount_ = tempItemCount;
  200. }
  201. void
  202. ValueInternalMap::clear()
  203. {
  204. ValueInternalMap dummy;
  205. swap( dummy );
  206. }
  207. ValueInternalMap::BucketIndex
  208. ValueInternalMap::size() const
  209. {
  210. return itemCount_;
  211. }
  212. bool
  213. ValueInternalMap::reserveDelta( BucketIndex growth )
  214. {
  215. return reserve( itemCount_ + growth );
  216. }
  217. bool
  218. ValueInternalMap::reserve( BucketIndex newItemCount )
  219. {
  220. if ( !buckets_ && newItemCount > 0 )
  221. {
  222. buckets_ = mapAllocator()->allocateMapBuckets( 1 );
  223. bucketsSize_ = 1;
  224. tailLink_ = &buckets_[0];
  225. }
  226. // BucketIndex idealBucketCount = (newItemCount + ValueInternalLink::itemPerLink) / ValueInternalLink::itemPerLink;
  227. return true;
  228. }
  229. const Value *
  230. ValueInternalMap::find( const char *key ) const
  231. {
  232. if ( !bucketsSize_ )
  233. return 0;
  234. HashKey hashedKey = hash( key );
  235. BucketIndex bucketIndex = hashedKey % bucketsSize_;
  236. for ( const ValueInternalLink *current = &buckets_[bucketIndex];
  237. current != 0;
  238. current = current->next_ )
  239. {
  240. for ( BucketIndex index=0; index < ValueInternalLink::itemPerLink; ++index )
  241. {
  242. if ( current->items_[index].isItemAvailable() )
  243. return 0;
  244. if ( strcmp( key, current->keys_[index] ) == 0 )
  245. return &current->items_[index];
  246. }
  247. }
  248. return 0;
  249. }
  250. Value *
  251. ValueInternalMap::find( const char *key )
  252. {
  253. const ValueInternalMap *constThis = this;
  254. return const_cast<Value *>( constThis->find( key ) );
  255. }
  256. Value &
  257. ValueInternalMap::resolveReference( const char *key,
  258. bool isStatic )
  259. {
  260. HashKey hashedKey = hash( key );
  261. if ( bucketsSize_ )
  262. {
  263. BucketIndex bucketIndex = hashedKey % bucketsSize_;
  264. ValueInternalLink **previous = 0;
  265. BucketIndex index;
  266. for ( ValueInternalLink *current = &buckets_[bucketIndex];
  267. current != 0;
  268. previous = &current->next_, current = current->next_ )
  269. {
  270. for ( index=0; index < ValueInternalLink::itemPerLink; ++index )
  271. {
  272. if ( current->items_[index].isItemAvailable() )
  273. return setNewItem( key, isStatic, current, index );
  274. if ( strcmp( key, current->keys_[index] ) == 0 )
  275. return current->items_[index];
  276. }
  277. }
  278. }
  279. reserveDelta( 1 );
  280. return unsafeAdd( key, isStatic, hashedKey );
  281. }
  282. void
  283. ValueInternalMap::remove( const char *key )
  284. {
  285. HashKey hashedKey = hash( key );
  286. if ( !bucketsSize_ )
  287. return;
  288. BucketIndex bucketIndex = hashedKey % bucketsSize_;
  289. for ( ValueInternalLink *link = &buckets_[bucketIndex];
  290. link != 0;
  291. link = link->next_ )
  292. {
  293. BucketIndex index;
  294. for ( index =0; index < ValueInternalLink::itemPerLink; ++index )
  295. {
  296. if ( link->items_[index].isItemAvailable() )
  297. return;
  298. if ( strcmp( key, link->keys_[index] ) == 0 )
  299. {
  300. doActualRemove( link, index, bucketIndex );
  301. return;
  302. }
  303. }
  304. }
  305. }
  306. void
  307. ValueInternalMap::doActualRemove( ValueInternalLink *link,
  308. BucketIndex index,
  309. BucketIndex bucketIndex )
  310. {
  311. // find last item of the bucket and swap it with the 'removed' one.
  312. // set removed items flags to 'available'.
  313. // if last page only contains 'available' items, then desallocate it (it's empty)
  314. ValueInternalLink *&lastLink = getLastLinkInBucket( index );
  315. BucketIndex lastItemIndex = 1; // a link can never be empty, so start at 1
  316. for ( ;
  317. lastItemIndex < ValueInternalLink::itemPerLink;
  318. ++lastItemIndex ) // may be optimized with dicotomic search
  319. {
  320. if ( lastLink->items_[lastItemIndex].isItemAvailable() )
  321. break;
  322. }
  323. BucketIndex lastUsedIndex = lastItemIndex - 1;
  324. Value *valueToDelete = &link->items_[index];
  325. Value *valueToPreserve = &lastLink->items_[lastUsedIndex];
  326. if ( valueToDelete != valueToPreserve )
  327. valueToDelete->swap( *valueToPreserve );
  328. if ( lastUsedIndex == 0 ) // page is now empty
  329. { // remove it from bucket linked list and delete it.
  330. ValueInternalLink *linkPreviousToLast = lastLink->previous_;
  331. if ( linkPreviousToLast != 0 ) // can not deleted bucket link.
  332. {
  333. mapAllocator()->releaseMapLink( lastLink );
  334. linkPreviousToLast->next_ = 0;
  335. lastLink = linkPreviousToLast;
  336. }
  337. }
  338. else
  339. {
  340. Value dummy;
  341. valueToPreserve->swap( dummy ); // restore deleted to default Value.
  342. valueToPreserve->setItemUsed( false );
  343. }
  344. --itemCount_;
  345. }
  346. ValueInternalLink *&
  347. ValueInternalMap::getLastLinkInBucket( BucketIndex bucketIndex )
  348. {
  349. if ( bucketIndex == bucketsSize_ - 1 )
  350. return tailLink_;
  351. ValueInternalLink *&previous = buckets_[bucketIndex+1].previous_;
  352. if ( !previous )
  353. previous = &buckets_[bucketIndex];
  354. return previous;
  355. }
  356. Value &
  357. ValueInternalMap::setNewItem( const char *key,
  358. bool isStatic,
  359. ValueInternalLink *link,
  360. BucketIndex index )
  361. {
  362. char *duplicatedKey = valueAllocator()->makeMemberName( key );
  363. ++itemCount_;
  364. link->keys_[index] = duplicatedKey;
  365. link->items_[index].setItemUsed();
  366. link->items_[index].setMemberNameIsStatic( isStatic );
  367. return link->items_[index]; // items already default constructed.
  368. }
  369. Value &
  370. ValueInternalMap::unsafeAdd( const char *key,
  371. bool isStatic,
  372. HashKey hashedKey )
  373. {
  374. JSON_ASSERT_MESSAGE( bucketsSize_ > 0, "ValueInternalMap::unsafeAdd(): internal logic error." );
  375. BucketIndex bucketIndex = hashedKey % bucketsSize_;
  376. ValueInternalLink *&previousLink = getLastLinkInBucket( bucketIndex );
  377. ValueInternalLink *link = previousLink;
  378. BucketIndex index;
  379. for ( index =0; index < ValueInternalLink::itemPerLink; ++index )
  380. {
  381. if ( link->items_[index].isItemAvailable() )
  382. break;
  383. }
  384. if ( index == ValueInternalLink::itemPerLink ) // need to add a new page
  385. {
  386. ValueInternalLink *newLink = mapAllocator()->allocateMapLink();
  387. index = 0;
  388. link->next_ = newLink;
  389. previousLink = newLink;
  390. link = newLink;
  391. }
  392. return setNewItem( key, isStatic, link, index );
  393. }
  394. ValueInternalMap::HashKey
  395. ValueInternalMap::hash( const char *key ) const
  396. {
  397. HashKey hash = 0;
  398. while ( *key )
  399. hash += *key++ * 37;
  400. return hash;
  401. }
  402. int
  403. ValueInternalMap::compare( const ValueInternalMap &other ) const
  404. {
  405. int sizeDiff( itemCount_ - other.itemCount_ );
  406. if ( sizeDiff != 0 )
  407. return sizeDiff;
  408. // Strict order guaranty is required. Compare all keys FIRST, then compare values.
  409. IteratorState it;
  410. IteratorState itEnd;
  411. makeBeginIterator( it );
  412. makeEndIterator( itEnd );
  413. for ( ; !equals(it,itEnd); increment(it) )
  414. {
  415. if ( !other.find( key( it ) ) )
  416. return 1;
  417. }
  418. // All keys are equals, let's compare values
  419. makeBeginIterator( it );
  420. for ( ; !equals(it,itEnd); increment(it) )
  421. {
  422. const Value *otherValue = other.find( key( it ) );
  423. int valueDiff = value(it).compare( *otherValue );
  424. if ( valueDiff != 0 )
  425. return valueDiff;
  426. }
  427. return 0;
  428. }
  429. void
  430. ValueInternalMap::makeBeginIterator( IteratorState &it ) const
  431. {
  432. it.map_ = const_cast<ValueInternalMap *>( this );
  433. it.bucketIndex_ = 0;
  434. it.itemIndex_ = 0;
  435. it.link_ = buckets_;
  436. }
  437. void
  438. ValueInternalMap::makeEndIterator( IteratorState &it ) const
  439. {
  440. it.map_ = const_cast<ValueInternalMap *>( this );
  441. it.bucketIndex_ = bucketsSize_;
  442. it.itemIndex_ = 0;
  443. it.link_ = 0;
  444. }
  445. bool
  446. ValueInternalMap::equals( const IteratorState &x, const IteratorState &other )
  447. {
  448. return x.map_ == other.map_
  449. && x.bucketIndex_ == other.bucketIndex_
  450. && x.link_ == other.link_
  451. && x.itemIndex_ == other.itemIndex_;
  452. }
  453. void
  454. ValueInternalMap::incrementBucket( IteratorState &iterator )
  455. {
  456. ++iterator.bucketIndex_;
  457. JSON_ASSERT_MESSAGE( iterator.bucketIndex_ <= iterator.map_->bucketsSize_,
  458. "ValueInternalMap::increment(): attempting to iterate beyond end." );
  459. if ( iterator.bucketIndex_ == iterator.map_->bucketsSize_ )
  460. iterator.link_ = 0;
  461. else
  462. iterator.link_ = &(iterator.map_->buckets_[iterator.bucketIndex_]);
  463. iterator.itemIndex_ = 0;
  464. }
  465. void
  466. ValueInternalMap::increment( IteratorState &iterator )
  467. {
  468. JSON_ASSERT_MESSAGE( iterator.map_, "Attempting to iterator using invalid iterator." );
  469. ++iterator.itemIndex_;
  470. if ( iterator.itemIndex_ == ValueInternalLink::itemPerLink )
  471. {
  472. JSON_ASSERT_MESSAGE( iterator.link_ != 0,
  473. "ValueInternalMap::increment(): attempting to iterate beyond end." );
  474. iterator.link_ = iterator.link_->next_;
  475. if ( iterator.link_ == 0 )
  476. incrementBucket( iterator );
  477. }
  478. else if ( iterator.link_->items_[iterator.itemIndex_].isItemAvailable() )
  479. {
  480. incrementBucket( iterator );
  481. }
  482. }
  483. void
  484. ValueInternalMap::decrement( IteratorState &iterator )
  485. {
  486. if ( iterator.itemIndex_ == 0 )
  487. {
  488. JSON_ASSERT_MESSAGE( iterator.map_, "Attempting to iterate using invalid iterator." );
  489. if ( iterator.link_ == &iterator.map_->buckets_[iterator.bucketIndex_] )
  490. {
  491. JSON_ASSERT_MESSAGE( iterator.bucketIndex_ > 0, "Attempting to iterate beyond beginning." );
  492. --(iterator.bucketIndex_);
  493. }
  494. iterator.link_ = iterator.link_->previous_;
  495. iterator.itemIndex_ = ValueInternalLink::itemPerLink - 1;
  496. }
  497. }
  498. const char *
  499. ValueInternalMap::key( const IteratorState &iterator )
  500. {
  501. JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." );
  502. return iterator.link_->keys_[iterator.itemIndex_];
  503. }
  504. const char *
  505. ValueInternalMap::key( const IteratorState &iterator, bool &isStatic )
  506. {
  507. JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." );
  508. isStatic = iterator.link_->items_[iterator.itemIndex_].isMemberNameStatic();
  509. return iterator.link_->keys_[iterator.itemIndex_];
  510. }
  511. Value &
  512. ValueInternalMap::value( const IteratorState &iterator )
  513. {
  514. JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." );
  515. return iterator.link_->items_[iterator.itemIndex_];
  516. }
  517. int
  518. ValueInternalMap::distance( const IteratorState &x, const IteratorState &y )
  519. {
  520. int offset = 0;
  521. IteratorState it = x;
  522. while ( !equals( it, y ) )
  523. increment( it );
  524. return offset;
  525. }