예제 #1
0
  // 該当するTTEntryを返す。
  const TTEntry& TranspositionTable::GetEntry(Hash pos_hash,
  int depth) const {
    // エントリーを得る。
    std::size_t index = GetTableIndex(pos_hash);
    if ((entry_table_[index].depth() >= depth)
    && (entry_table_[index].pos_hash() == pos_hash)) {
      return entry_table_[index];
    }

    // 条件外なので、無効なエントリーを返す。
    return null_entry_;
  }
예제 #2
0
  // 該当するTTEntryを返す。
  TTEntry* TranspositionTable::GetEntry(Hash pos_hash,
  int depth) {
    std::unique_lock<std::mutex> lock(mutex_);  // ロック。

    // エントリーを得る。
    TTEntry* entry_ptr = nullptr;
    std::size_t index = GetTableIndex(pos_hash);
    if ((entry_table_[index].depth() >= depth)
    && (entry_table_[index].pos_hash() == pos_hash)) {
      entry_ptr = &(entry_table_[index]);
    }

    return entry_ptr;
  }
예제 #3
0
ezResult ezImageConversionBase::Convert(const ezImage& source, ezImage& target, ezImageFormat::Enum targetFormat)
{
  ezImageFormat::Enum sourceFormat = source.GetImageFormat();

  // Trivial copy
  if (sourceFormat == targetFormat)
  {
    target = source;
    return EZ_SUCCESS;
  }

  if (!s_bConversionTableValid)
  {
    RebuildConversionTable();
  }

  ezUInt32 uiCurrentTableIndex = GetTableIndex(sourceFormat, targetFormat);

  // No conversion known
  if (s_conversionTable[uiCurrentTableIndex] == nullptr)
  {
    return EZ_FAILURE;
  }

  const ezImageConversionBase* pConversion = s_conversionTable[uiCurrentTableIndex];
  const SubConversion& subConversion = pConversion->m_subConversions[s_subConversionTable[uiCurrentTableIndex]];

  if (subConversion.m_targetFormat == targetFormat)
  {
    if (&source == &target && !subConversion.m_flags.IsSet(ezImageConversionFlags::InPlace))
    {
      ezImage copy = source;
      return pConversion->DoConvert(copy, target, subConversion.m_targetFormat);
    }
    else
    {
      return pConversion->DoConvert(source, target, subConversion.m_targetFormat);
    }
  }
  else
  {
    ezImage intermediate;
    if (pConversion->DoConvert(source, intermediate, subConversion.m_targetFormat) == EZ_FAILURE)
    {
      return EZ_FAILURE;
    }

    return Convert(intermediate, target, targetFormat);
  }
}
예제 #4
0
  // テーブルに追加する。
  void TranspositionTable::Add(Hash pos_hash, int depth, int score,
  ScoreType score_type, Move best_move, int ply_mate) {
    std::unique_lock<std::mutex> lock(mutex_);  // ロック。

    // テーブルのインデックスを得る。
    std::size_t index = GetTableIndex(pos_hash);

    // 空いているエントリーへの登録なら使用済みエントリー数をカウント。
    if (entry_table_[index].depth() <= -MAX_VALUE) {
      num_used_entries_++;
    }

    // テーブルが若い時にに登録されているものなら上書き。
    // depthがすでに登録されているエントリー以上なら登録。
    if ((entry_table_[index].table_age() < age_)
    || (depth >= entry_table_[index].depth())) {
      entry_table_[index] =
      TTEntry(pos_hash, depth, score, score_type, best_move, ply_mate, age_);
    }
  }
예제 #5
0
ezImageFormat::Enum ezImageConversionBase::FindClosestCompatibleFormat(ezImageFormat::Enum format, const ezImageFormat::Enum* pCompatibleFormats, ezUInt32 uiNumCompatible)
{
  if (!s_bConversionTableValid)
  {
    RebuildConversionTable();
  }

  float fBestCost = ezMath::BasicType<float>::GetInfinity();
  ezImageFormat::Enum bestFormat = ezImageFormat::UNKNOWN;

  for (ezUInt32 uiTargetIndex = 0; uiTargetIndex < uiNumCompatible; uiTargetIndex++)
  {
    float fCost = s_costTable[GetTableIndex(format, pCompatibleFormats[uiTargetIndex])];
    if (fCost < fBestCost)
    {
      fBestCost = fCost;
      bestFormat = pCompatibleFormats[uiTargetIndex];
    }
  }

  return bestFormat;
}
예제 #6
0
파일: GameData.cpp 프로젝트: BehoIder/gemrb
/** Loads a 2DA Table, returns -1 on error or the Table Index on success */
int GameData::LoadTable(const ieResRef ResRef, bool silent)
{
	int ind = GetTableIndex( ResRef );
	if (ind != -1) {
		tables[ind].refcount++;
		return ind;
	}
	//print("(%s) Table not found... Loading from file", ResRef);
	DataStream* str = GetResource( ResRef, IE_2DA_CLASS_ID, silent );
	if (!str) {
		return -1;
	}
	PluginHolder<TableMgr> tm(IE_2DA_CLASS_ID);
	if (!tm) {
		delete str;
		return -1;
	}
	if (!tm->Open(str)) {
		return -1;
	}
	Table t;
	t.refcount = 1;
	strncpy( t.ResRef, ResRef, 8 );
	t.tm = tm;
	ind = -1;
	for (size_t i = 0; i < tables.size(); i++) {
		if (tables[i].refcount == 0) {
			ind = ( int ) i;
			break;
		}
	}
	if (ind != -1) {
		tables[ind] = t;
		return ind;
	}
	tables.push_back( t );
	return ( int ) tables.size() - 1;
}
예제 #7
0
void ezImageConversionBase::RebuildConversionTable()
{
  s_conversionTable.SetCount(ezImageFormat::NUM_FORMATS * ezImageFormat::NUM_FORMATS);
  s_subConversionTable.SetCount(ezImageFormat::NUM_FORMATS * ezImageFormat::NUM_FORMATS);
  s_costTable.SetCount(ezImageFormat::NUM_FORMATS * ezImageFormat::NUM_FORMATS);

  for (ezUInt32 tableIdx = 0; tableIdx < s_conversionTable.GetCount(); tableIdx++)
  {
    s_conversionTable[tableIdx] = nullptr;
    s_costTable[tableIdx] = ezMath::BasicType<float>::GetInfinity();
  }

  // Prime conversion table with known conversions
  for (ezImageConversionBase* pConversion = ezImageConversionBase::GetFirstInstance(); pConversion; pConversion = pConversion->GetNextInstance())
  {
    for (ezUInt32 uiSubConversion = 0; uiSubConversion < pConversion->m_subConversions.GetCount(); uiSubConversion++)
    {
      const SubConversion& subConversion = pConversion->m_subConversions[uiSubConversion];

      if (subConversion.m_flags.IsSet(ezImageConversionFlags::InPlace))
      {
        EZ_ASSERT_DEBUG(ezImageFormat::GetBitsPerPixel(subConversion.m_sourceFormat) == ezImageFormat::GetBitsPerPixel(subConversion.m_targetFormat),
          "In-place conversions are only allowed between formats of the same number of bits per pixel");
        EZ_ASSERT_DEBUG(ezImageFormat::GetType(subConversion.m_sourceFormat) == ezImageFormat::GetType(subConversion.m_targetFormat),
          "In-place conversions are only allowed between formats of the same type");
      }

      ezUInt32 uiTableIndex = GetTableIndex(subConversion.m_sourceFormat, subConversion.m_targetFormat);

      // Use the cheapest known conversion for each combination in case there are multiple ones
      if (s_costTable[uiTableIndex] > GetConversionCost(subConversion.m_flags))
      {
        s_conversionTable[uiTableIndex] = pConversion;
        s_subConversionTable[uiTableIndex] = uiSubConversion;
        s_costTable[uiTableIndex] = GetConversionCost(subConversion.m_flags);
      }
    }
  }

  for (ezUInt32 i = 0; i < ezImageFormat::NUM_FORMATS; i++)
  {
    // Add copy-conversion (from and to same format)
    s_costTable[GetTableIndex(i, i)] = GetConversionCost(ezImageConversionFlags::InPlace);
  }

  // Straight from http://en.wikipedia.org/wiki/Floyd-Warshall_algorithm
  for (ezUInt32 k = 0; k < ezImageFormat::NUM_FORMATS; k++)
  {
    for (ezUInt32 i = 0; i < ezImageFormat::NUM_FORMATS; i++)
    {
      ezUInt32 uiTableIndexIK = GetTableIndex(i, k);
      for (ezUInt32 j = 0; j < ezImageFormat::NUM_FORMATS; j++)
      {
        ezUInt32 uiTableIndexIJ = GetTableIndex(i, j);
        ezUInt32 uiTableIndexKJ = GetTableIndex(k, j);
        if (s_costTable[uiTableIndexIK] + s_costTable[uiTableIndexKJ] < s_costTable[uiTableIndexIJ])
        {
          s_costTable[uiTableIndexIJ] = s_costTable[uiTableIndexIK] + s_costTable[uiTableIndexKJ];

          const ezImageConversionBase* pConversion = s_conversionTable[uiTableIndexIK];

          // To convert from format I to format J, first convert from I to K
          s_conversionTable[uiTableIndexIJ] = pConversion;
          s_subConversionTable[uiTableIndexIJ] = s_subConversionTable[uiTableIndexIK];
        }
      }
    }
  }

  s_bConversionTableValid = true;
}
예제 #8
0
// --------------------------------------------------------------------------------------
// 
// Stores hot data reported by IBC in profile data (code:CorProfileData) to a stream.
// Aligns output stream to 4-bytes.
// 
__checkReturn 
HRESULT 
HotHeapWriter::SaveToStream(
    IStream        *pStream, 
    CorProfileData *pProfileData, 
    UINT32         *pnSavedSize) const
{
    _ASSERTE(pStream != NULL);
    _ASSERTE(pProfileData != NULL);
    _ASSERTE(pnSavedSize != NULL);
    
#ifdef FEATURE_PREJIT
    HRESULT hr = S_OK;
    UINT32 nOffset = 0;
    UINT32 nValueHeapStart_PositiveOffset;
    UINT32 nValueOffsetTableStart_PositiveOffset;
    UINT32 nIndexTableStart_PositiveOffset;
    
    // data
    //
    
    // number of hot tokens
    UINT32 nHotItemsCount = pProfileData->GetHotTokens(
        GetTableIndex(), 
        1 << ProfilingFlags_MetaData, 
        1 << ProfilingFlags_MetaData, 
        NULL, 
        0);
    CONSISTENCY_CHECK(nHotItemsCount != 0);
    
    NewArrayHolder<UINT32> hotItemArr = new (nothrow) UINT32[nHotItemsCount];
    IfNullRet(hotItemArr);
    
    // get hot tokens
    static_assert_no_msg(sizeof(UINT32) == sizeof(mdToken));
    pProfileData->GetHotTokens(
        GetTableIndex(), 
        1 << ProfilingFlags_MetaData, 
        1 << ProfilingFlags_MetaData, 
        reinterpret_cast<mdToken *>(&hotItemArr[0]), 
        nHotItemsCount);
    
    // convert tokens to rids
    for (UINT32 i = 0; i < nHotItemsCount; i++)
    {
        hotItemArr[i] = RidFromToken(hotItemArr[i]);
    }
    
    NewArrayHolder<RidOffsetPair> offsetMapping = new (nothrow) RidOffsetPair[nHotItemsCount];
    IfNullRet(offsetMapping);
    
    // write data
    nValueHeapStart_PositiveOffset = nOffset;
    
    // note that we write hot items in the order they appear in pProfileData->GetHotTokens
    // this is so that we preserve the ordering optimizations done by IbcMerge
    for (UINT32 i = 0; i < nHotItemsCount; i++)
    {
        DataBlob data;
        IfFailRet(GetData(
            hotItemArr[i], 
            &data));
        
        // keep track of the offset at which each hot item is written
        offsetMapping[i].rid = hotItemArr[i];
        offsetMapping[i].offset = nOffset;
        
        IfFailRet(StreamUtil::WriteToStream(
            pStream, 
            data.GetDataPointer(), 
            data.GetSize(), 
            &nOffset));
    }
    
    IfFailRet(StreamUtil::AlignDWORD(pStream, &nOffset));
    
    // sort by rid so that a hot rid can be looked up by binary search
    qsort(offsetMapping, nHotItemsCount, sizeof(RidOffsetPair), RidOffsetPair::Compare);
    
    // initialize table of offsets to data
    NewArrayHolder<UINT32> dataIndices = new (nothrow) UINT32[nHotItemsCount];
    IfNullRet(dataIndices);
    
    // fill in the hotItemArr (now sorted by rid) and dataIndices array with each offset
    for (UINT32 i = 0; i < nHotItemsCount; i++)
    {
        hotItemArr[i] = offsetMapping[i].rid;
        dataIndices[i] = offsetMapping[i].offset;
    }
    
    // table of offsets to data
    //
    
    nValueOffsetTableStart_PositiveOffset = nOffset;
    IfFailRet(StreamUtil::WriteToStream(pStream, &dataIndices[0], sizeof(UINT32) * nHotItemsCount, &nOffset));
    
    // rid table (sorted)
    //
    
    nIndexTableStart_PositiveOffset = nOffset;
    
    IfFailRet(StreamUtil::WriteToStream(pStream, &hotItemArr[0], nHotItemsCount * sizeof(UINT32), &nOffset));
    IfFailRet(StreamUtil::AlignDWORD(pStream, &nOffset));
    
    {
        // hot pool header
        struct HotHeapHeader header;
        
        // fix offsets
        header.m_nIndexTableStart_NegativeOffset = nOffset - nIndexTableStart_PositiveOffset;
        header.m_nValueOffsetTableStart_NegativeOffset = nOffset - nValueOffsetTableStart_PositiveOffset;
        header.m_nValueHeapStart_NegativeOffset = nOffset - nValueHeapStart_PositiveOffset;
        
        // write header
        IfFailRet(StreamUtil::WriteToStream(pStream, &header, sizeof(header), &nOffset));
    }
    
    *pnSavedSize = nOffset;
    
#endif //FEATURE_PREJIT
    
    return S_OK;
} // HotHeapWriter::PersistHotToStream