blob: 6aa6baa5b317611466610293dc711a16fdb4dcef [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "impl/affinity/affinity_manager.h"
namespace ignite
{
namespace impl
{
namespace thin
{
namespace affinity
{
AffinityManager::AffinityManager() :
cacheAffinity(new CacheAffinityMap),
updateCounter(0)
{
// No-op.
}
void AffinityManager::UpdateAffinity(const AffinityTopologyVersion& ver)
{
if (topologyVersion >= ver)
return;
ResetAffinity(ver);
}
void AffinityManager::UpdateAffinity(const std::vector<PartitionAwarenessGroup>& groups,
const AffinityTopologyVersion& ver)
{
if (topologyVersion > ver)
return;
bool processed = false;
while (!processed)
{
uint64_t cnt;
SP_CacheAffinityMap oldAffinityPtr = GetAffinity(cnt);
SP_CacheAffinityMap newAffinityPtr(new CacheAffinityMap(*oldAffinityPtr.Get()));
CacheAffinityMap& newAffinity = *newAffinityPtr.Get();
std::vector<PartitionAwarenessGroup>::const_iterator group;
for (group = groups.begin(); group != groups.end(); ++group)
{
SP_AffinityAssignment newMapping(new AffinityAssignment(group->GetNodePartitions()));
const std::vector<CacheAffinityConfigs>& caches = group->GetCaches();
std::vector<CacheAffinityConfigs>::const_iterator cache;
for (cache = caches.begin(); cache != caches.end(); ++cache)
newAffinity[cache->GetCacheId()].Swap(newMapping);
}
processed = UpdateAffinity(ver, cnt, newAffinityPtr);
}
}
SP_AffinityAssignment AffinityManager::GetAffinityAssignment(int32_t cacheId) const
{
SP_CacheAffinityMap ptr = GetAffinity();
CacheAffinityMap& cacheAffinity0 = *ptr.Get();
CacheAffinityMap::const_iterator it = cacheAffinity0.find(cacheId);
if (it == cacheAffinity0.end())
return SP_AffinityAssignment();
return it->second;
}
void AffinityManager::ResetAffinity(const AffinityTopologyVersion& ver)
{
common::concurrent::RwExclusiveLockGuard lock(affinityRwl);
if (topologyVersion > ver)
return;
topologyVersion = ver;
SP_CacheAffinityMap empty(new CacheAffinityMap);
cacheAffinity.Swap(empty);
++updateCounter;
}
bool AffinityManager::UpdateAffinity(const AffinityTopologyVersion& ver, uint64_t cnt,
SP_CacheAffinityMap& affinity)
{
common::concurrent::RwExclusiveLockGuard lock(affinityRwl);
if (topologyVersion > ver)
return true;
if (updateCounter != cnt)
return false;
topologyVersion = ver;
cacheAffinity.Swap(affinity);
++updateCounter;
return true;
}
AffinityManager::SP_CacheAffinityMap AffinityManager::GetAffinity() const
{
common::concurrent::RwSharedLockGuard lock(affinityRwl);
SP_CacheAffinityMap ptr(cacheAffinity);
lock.Reset();
return ptr;
}
AffinityManager::SP_CacheAffinityMap AffinityManager::GetAffinity(uint64_t& cnt) const
{
common::concurrent::RwSharedLockGuard lock(affinityRwl);
SP_CacheAffinityMap ptr(cacheAffinity);
cnt = updateCounter;
lock.Reset();
return ptr;
}
}
}
}
}