implement metadata storage (hash)table
not passing all tests yet
This commit is contained in:
parent
c91e703682
commit
f849ca62d9
1 changed files with 88 additions and 9 deletions
|
|
@ -57,8 +57,11 @@
|
||||||
#include "lib/error.hpp"
|
#include "lib/error.hpp"
|
||||||
#include "lib/symbol.hpp"
|
#include "lib/symbol.hpp"
|
||||||
#include "lib/functor-util.hpp"
|
#include "lib/functor-util.hpp"
|
||||||
|
#include "lib/util-foreach.hpp"
|
||||||
|
#include "include/logging.h"
|
||||||
|
|
||||||
#include <tr1/functional>
|
#include <tr1/functional>
|
||||||
|
#include <tr1/unordered_map>
|
||||||
#include <boost/functional/hash.hpp>
|
#include <boost/functional/hash.hpp>
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
|
|
||||||
|
|
@ -67,6 +70,7 @@ namespace engine {
|
||||||
|
|
||||||
using lib::HashVal;
|
using lib::HashVal;
|
||||||
using lib::Literal;
|
using lib::Literal;
|
||||||
|
using util::for_each;
|
||||||
using std::tr1::bind;
|
using std::tr1::bind;
|
||||||
using std::tr1::function;
|
using std::tr1::function;
|
||||||
using std::tr1::placeholders::_1;
|
using std::tr1::placeholders::_1;
|
||||||
|
|
@ -392,7 +396,7 @@ namespace engine {
|
||||||
bool
|
bool
|
||||||
isLocked() const
|
isLocked() const
|
||||||
{
|
{
|
||||||
ASSERT (NIL != state_ && FREE != state_);
|
ASSERT (!buffer_ || (NIL != state_ && FREE != state_));
|
||||||
return bool(buffer_);
|
return bool(buffer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -461,8 +465,9 @@ namespace engine {
|
||||||
__must_not_be_NIL() const
|
__must_not_be_NIL() const
|
||||||
{
|
{
|
||||||
if (NIL == state_)
|
if (NIL == state_)
|
||||||
throw error::Fatal ("Concrete buffer entry with state==NIL encountered."
|
throw error::Fatal ("Buffer metadata entry with state==NIL encountered."
|
||||||
"State transition logic broken (programming error)");
|
"State transition logic broken (programming error)"
|
||||||
|
, LUMIERA_ERROR_LIFECYCLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -478,29 +483,103 @@ namespace engine {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (Hash)Table to store and manage buffer metadata
|
* (Hash)Table to store and manage buffer metadata.
|
||||||
|
* Buffer metadata entries are comprised of a Key part and an extended
|
||||||
|
* Entry, holding the actual management and housekeeping metadata. The
|
||||||
|
* Keys are organised hierarchically and denote the "kind" of buffer.
|
||||||
|
* The hash values for lookup are based on the key part, chained with
|
||||||
|
* the actual memory location of the concrete buffer corresponding
|
||||||
|
* to the metadata entry to be retrieved.
|
||||||
*/
|
*/
|
||||||
class Table
|
class Table
|
||||||
{
|
{
|
||||||
|
typedef std::tr1::unordered_map<HashVal,Entry> MetadataStore;
|
||||||
|
|
||||||
|
MetadataStore entries_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
~Table() { verify_all_buffers_freed(); }
|
||||||
|
|
||||||
|
/** fetch metadata record, if any
|
||||||
|
* @param hashID for the Key part of the metadata entry
|
||||||
|
* @return pointer to the entry in the table or NULL
|
||||||
|
*/
|
||||||
Entry*
|
Entry*
|
||||||
fetch (HashVal hashID) const
|
fetch (HashVal hashID)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED ("fetch metadata record by ID");
|
MetadataStore::iterator pos = entries_.find (hashID);
|
||||||
|
if (pos != entries_.end())
|
||||||
|
return &(pos->second);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Entry*
|
||||||
|
fetch (HashVal hashID) const
|
||||||
|
{
|
||||||
|
MetadataStore::const_iterator pos = entries_.find (hashID);
|
||||||
|
if (pos != entries_.end())
|
||||||
|
return &(pos->second);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** store a copy of the given new metadata entry.
|
||||||
|
* The hash key for lookup is retrieved from the given Entry, by conversion to HashVal.
|
||||||
|
* Consequently, this will be the hashID of the parent Key (type), when the entry holds
|
||||||
|
* a NULL buffer (i.e a "pseudo entry"). Otherwise, it will be this parent Key hash,
|
||||||
|
* extended by hashing the actual buffer address.
|
||||||
|
* @return reference to relevant entry for this Key. This might be a copy
|
||||||
|
* of the new entry, or an already existing entry with the same Key
|
||||||
|
*/
|
||||||
Entry&
|
Entry&
|
||||||
store (Entry const& newEntry)
|
store (Entry const& newEntry)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED ("store new metadata record");
|
using std::make_pair;
|
||||||
|
REQUIRE (!fetch (newEntry), "duplicate buffer metadata entry");
|
||||||
|
MetadataStore::iterator pos = entries_.insert (make_pair (HashVal(newEntry), newEntry))
|
||||||
|
.first;
|
||||||
|
|
||||||
|
ENSURE (pos != entries_.end());
|
||||||
|
return pos->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
remove (HashVal hashID)
|
remove (HashVal hashID)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED ("delete metadata record");
|
uint cnt = entries_.erase (hashID);
|
||||||
|
ENSURE (cnt, "entry to remove didn't exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void
|
||||||
|
verify_all_buffers_freed()
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for_each (entries_, verify_is_free);
|
||||||
|
}
|
||||||
|
catch (std::exception& problem)
|
||||||
|
{
|
||||||
|
const char* errID = lumiera_error();
|
||||||
|
const char* operation = "Shutdown of BufferProvider metadata store";
|
||||||
|
WARN (engine, "%s failed: %s", operation, problem.what());
|
||||||
|
TRACE (debugging, "Error flag was: %s", errID);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
const char* errID = lumiera_error();
|
||||||
|
const char* operation = "Shutdown of BufferProvider metadata store";
|
||||||
|
ERROR (engine, "%s failed with unknown exception; error flag is: %s", operation, errID);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
verify_is_free (std::pair<HashVal, Entry> const& e)
|
||||||
|
{
|
||||||
|
WARN_IF (e.second.isLocked(), engine,
|
||||||
|
"Buffer still in use while shutting down BufferProvider? ");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}//namespace metadata
|
}//namespace metadata
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -651,7 +730,7 @@ namespace engine {
|
||||||
bool
|
bool
|
||||||
isLocked (HashVal key) const
|
isLocked (HashVal key) const
|
||||||
{
|
{
|
||||||
Entry* entry = table_.fetch (key);
|
const Entry* entry = table_.fetch (key);
|
||||||
return entry
|
return entry
|
||||||
&& entry->isLocked();
|
&& entry->isLocked();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue