/*****************************************************************
|
| Platinum - AV Media Cache
|
| Copyright (c) 2004-2010, Plutinosoft, LLC.
| All rights reserved.
| http://www.plutinosoft.com
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of the GNU General Public License
| as published by the Free Software Foundation; either version 2
| of the License, or (at your option) any later version.
|
| OEMs, ISVs, VARs and other distributors that combine and
| distribute commercially licensed software with Platinum software
| and do not wish to distribute the source code for the commercially
| licensed software under version 2, or (at your option) any later
| version, of the GNU General Public License (the "GPL") must enter
| into a commercial license agreement with Plutinosoft, LLC.
| licensing@plutinosoft.com
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License
| along with this program; see the file LICENSE.txt. If not, write to
| the Free Software Foundation, Inc.,
| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
| http://www.gnu.org/licenses/gpl-2.0.html
|
****************************************************************/
/** @file
Simple Object Caching utility.
*/
#ifndef _PLT_MEDIA_CACHE_H_
#define _PLT_MEDIA_CACHE_H_
/*----------------------------------------------------------------------
| includes
+---------------------------------------------------------------------*/
#include "Neptune.h"
/*----------------------------------------------------------------------
| PLT_MediaCache
+---------------------------------------------------------------------*/
/**
The PLT_MediaCache template provides a way to hold references to object in
memory.
*/
template <typename T, typename U>
class PLT_MediaCache
{
public:
typedef typename NPT_Map<NPT_String,T>::Entry ElementEntry;
typedef typename NPT_List<ElementEntry*>::Iterator ElementIterator;
PLT_MediaCache<T,U>() {}
virtual ~PLT_MediaCache<T,U>() {}
NPT_Result Put(const char* root, const char* key, T& value, U* tag = NULL);
NPT_Result Get(const char* root, const char* key, T& value, U* tag = NULL);
NPT_Result Clear(const char* root, const char* key);
NPT_Result Clear(const char* root = NULL);
private:
// methods
NPT_String GenerateKey(const char* root, const char* key);
private:
// members
NPT_Mutex m_Mutex;
NPT_Map<NPT_String, T> m_Items;
NPT_Map<NPT_String, U> m_Tags;
};
/*----------------------------------------------------------------------
| PLT_MediaCache::GenerateKey
+---------------------------------------------------------------------*/
template <typename T, typename U>
inline
NPT_String
PLT_MediaCache<T,U>::GenerateKey(const char* root, const char* key)
{
// TODO: There could be collision
NPT_String result = root;
result += "/";
result += key;
return result;
}
/*----------------------------------------------------------------------
| PLT_MediaCache::Put
+---------------------------------------------------------------------*/
template <typename T, typename U>
inline
NPT_Result
PLT_MediaCache<T,U>::Put(const char* root,
const char* key,
T& value,
U* tag)
{
NPT_AutoLock lock(m_Mutex);
NPT_String fullkey = GenerateKey(root, key);
if (fullkey.GetLength() == 0) return NPT_ERROR_INVALID_PARAMETERS;
m_Items.Erase(fullkey);
NPT_CHECK(m_Items.Put(fullkey, value));
if (tag) NPT_CHECK(m_Tags.Put(fullkey, *tag));
return NPT_SUCCESS;
}
/*----------------------------------------------------------------------
| PLT_MediaCache::Get
+---------------------------------------------------------------------*/
template <typename T, typename U>
inline
NPT_Result
PLT_MediaCache<T,U>::Get(const char* root,
const char* key,
T& value,
U* tag /* = NULL */)
{
NPT_AutoLock lock(m_Mutex);
NPT_String fullkey = GenerateKey(root, key);
if (fullkey.GetLength() == 0) return NPT_ERROR_INVALID_PARAMETERS;
T* _value = NULL;
NPT_CHECK(m_Items.Get(fullkey, _value));
U* _tag;
if (tag) {
m_Tags.Get(fullkey, _tag);
if (_tag) *tag = *_tag;
}
value = *_value;
return NPT_SUCCESS;
}
/*----------------------------------------------------------------------
| PLT_MediaCache::Clear
+---------------------------------------------------------------------*/
template <typename T, typename U>
inline
NPT_Result
PLT_MediaCache<T,U>::Clear(const char* root, const char* key)
{
NPT_AutoLock lock(m_Mutex);
NPT_String fullkey = GenerateKey(root, key);
if (fullkey.GetLength() == 0) return NPT_ERROR_INVALID_PARAMETERS;
ElementIterator entries = m_Items.GetEntries().GetFirstItem();
ElementIterator entry;
while (entries) {
entry = entries++;
if ((*entry)->GetKey() == (fullkey)) {
m_Items.Erase(fullkey);
m_Tags.Erase(fullkey);
return NPT_SUCCESS;
}
}
return NPT_ERROR_NO_SUCH_ITEM;
}
/*----------------------------------------------------------------------
| PLT_MediaCache::Clear
+---------------------------------------------------------------------*/
template <typename T, typename U>
inline
NPT_Result
PLT_MediaCache<T,U>::Clear(const char* root)
{
NPT_AutoLock lock(m_Mutex);
if (!root || root[0]=='\0')
return m_Items.Clear();
NPT_String key = GenerateKey(root, "");
ElementIterator entries = m_Items.GetEntries().GetFirstItem();
ElementIterator entry;
while (entries) {
entry = entries++;
NPT_String entry_key = (*entry)->GetKey();
if (entry_key.StartsWith(key)) {
m_Items.Erase(entry_key);
m_Tags.Erase(entry_key);
}
}
return NPT_SUCCESS;
}
#endif /* _PLT_MEDIA_CACHE_H_ */