Change session registry to a template class
The template class wraps a HashMap such that only a few operations are allowed. Usage requires specializing a RegistryTraits class template for each entry type.
This commit is contained in:
@ -14,6 +14,7 @@
|
||||
|
||||
#include <maxscale/cppdefs.hh>
|
||||
#include <stdio.h>
|
||||
#include <tr1/unordered_map>
|
||||
|
||||
namespace maxscale
|
||||
{
|
||||
@ -177,4 +178,94 @@ struct CloserTraits<FILE*>
|
||||
}
|
||||
};
|
||||
|
||||
/* Helper type for Registry. Must be specialized for each EntryType. The types
|
||||
* listed below are just examples and will not compile. */
|
||||
template<typename EntryType>
|
||||
struct RegistryTraits
|
||||
{
|
||||
typedef int id_type;
|
||||
typedef EntryType* entry_type;
|
||||
|
||||
static id_type get_id(entry_type entry)
|
||||
{
|
||||
static_assert(sizeof(EntryType) != sizeof(EntryType), "get_id() and the"
|
||||
" surrounding struct must be specialized for every EntryType!");
|
||||
return 0;
|
||||
}
|
||||
static entry_type null_entry()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Class Registy wraps a map, allowing only a few operations on it. The intended
|
||||
* use is simple registries, such as the session registry in Worker. The owner
|
||||
* can expose a reference to this class without exposing all the methods the
|
||||
* underlying container implements. When instantiating with a new EntryType, the
|
||||
* traits-class RegistryTraits should be specialized for the new type as well.
|
||||
*/
|
||||
template <typename EntryType>
|
||||
class Registry
|
||||
{
|
||||
Registry(const Registry&);
|
||||
Registry& operator = (const Registry&);
|
||||
public:
|
||||
typedef typename RegistryTraits<EntryType>::id_type id_type;
|
||||
typedef typename RegistryTraits<EntryType>::entry_type entry_type;
|
||||
|
||||
Registry()
|
||||
{
|
||||
}
|
||||
/**
|
||||
* Find an entry in the registry.
|
||||
*
|
||||
* @param id Entry key
|
||||
* @return The found entry, or NULL if not found
|
||||
*/
|
||||
entry_type lookup(id_type id) const
|
||||
{
|
||||
entry_type rval = RegistryTraits<EntryType>::null_entry();
|
||||
typename ContainerType::const_iterator iter = m_registry.find(id);
|
||||
if (iter != m_registry.end())
|
||||
{
|
||||
rval = iter->second;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an entry to the registry.
|
||||
*
|
||||
* @param entry The entry to add
|
||||
* @return True if successful, false if id was already in
|
||||
*/
|
||||
bool add(entry_type entry)
|
||||
{
|
||||
id_type id = RegistryTraits<EntryType>::get_id(entry);
|
||||
typename ContainerType::value_type new_value(id, entry);
|
||||
return m_registry.insert(new_value).second;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an entry from the registry.
|
||||
*
|
||||
* @param id Entry id
|
||||
* @return True if an entry was removed, false if not found
|
||||
*/
|
||||
bool remove(id_type id)
|
||||
{
|
||||
entry_type rval = lookup(id);
|
||||
if (rval)
|
||||
{
|
||||
m_registry.erase(id);
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
private:
|
||||
typedef typename std::tr1::unordered_map<id_type, entry_type> ContainerType;
|
||||
ContainerType m_registry;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ bool mxs_worker_register_session(MXS_SESSION* session);
|
||||
* @param id Which id to remove.
|
||||
* @return The removed session or NULL if not found.
|
||||
*/
|
||||
MXS_SESSION* mxs_worker_deregister_session(uint64_t id);
|
||||
bool mxs_worker_deregister_session(uint64_t id);
|
||||
|
||||
/**
|
||||
* Find a session in the current worker's session container.
|
||||
|
Reference in New Issue
Block a user