// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #include "lib/Api.Image/pch.h" #include "inc/ConverterResourceStore.h" #include #include #include #include using namespace _winml; ConverterResources::ConverterResources(Pool& pool, ConverterResourceDescription& descriptor) : m_pool(pool), Descriptor(descriptor), Tensorizer(std::make_unique()), Detensorizer(std::make_unique()) { } void ConverterResources::ReturnToCache() { if (auto pool = m_pool.lock()) { pool->Store(shared_from_this()); } } ConverterResourceStore::ConverterResourceStore(size_t nCacheSize) : m_cacheSize(nCacheSize) { } std::shared_ptr ConverterResourceStore::Fetch(ConverterResourceDescription& descriptor) { std::lock_guard lock(m_mutex); auto resource = FetchAndRemoveObject(descriptor); if (resource == nullptr) { // Create the resource resource = ConverterResources::Create(shared_from_this(), descriptor); } return resource; } std::shared_ptr ConverterResourceStore::FetchAndRemoveObject(ConverterResourceDescription& desc) { // Iterate through the resources and find all the resources which are completed and unallocate auto foundIt = std::find_if(std::begin(m_objects), std::end(m_objects), [&](const auto& cachedObject) { return desc == cachedObject.Resource->Descriptor; }); if (foundIt == std::end(m_objects)) { return nullptr; } else { std::shared_ptr object = foundIt->Resource; // Remove the item from the cache so that it is not reused by another call m_objects.erase(foundIt); return object; } } void ConverterResourceStore::Store(std::shared_ptr object) { std::lock_guard lock(m_mutex); auto foundIt = std::find_if(std::begin(m_objects), std::end(m_objects), [&](const auto& cachedObject) { return object == cachedObject.Resource; }); if (foundIt == std::end(m_objects)) { // If the resource is not already cached if (m_objects.size() < m_cacheSize) { // If the cache has free slots, then use one m_objects.push_back( PoolObject{ object, storeId++}); } else { // If the cache has no free slots, then evict the oldest EvictOldestPoolObject(); m_objects.push_back( PoolObject{ object, storeId++}); } } } void ConverterResourceStore::EvictOldestPoolObject() { auto oldestIt = std::min_element(std::begin(m_objects), std::end(m_objects), [&](const auto& left, const auto& right) { return left.StoreId < right.StoreId; }); // Remove the oldest item from the cache m_objects.erase(oldestIt); }