⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 json_internalmap.inl.svn-base

📁 这是基于jsoncpp项目写扩展功能
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
// included by json_value.cpp
// everything is within Json namespace

// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////
// 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<ValueInternalMap,1> mapsAllocator_;
   BatchAllocator<ValueInternalLink,1> 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 =( const ValueInternalMap &other )
{
   ValueInternalMap dummy( other );
   swap( dummy );
   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 &current->items_[index];
      }
   }
   return 0;
}


Value *
ValueInternalMap::find( const char *key )
{
   const ValueInternalMap *constThis = this;
   return const_cast<Value *>( constThis->find( key ) );
}


Value &
ValueInternalMap::resolveReference( const char *key,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -