Invocation: settle upon a way to mark the output buffer
...this is a surprisingly tricky issue, since it undercuts the generic and recursive implementation of buffer handling; fortunately I've foreseen such demands may arise down the road and I've reserved an »Local Key« (now renamed into `LocalTag`), whose meaning is implementation defined and interpreted by the specific `BufferProvider`
This commit is contained in:
parent
ea183086ca
commit
6d7a814495
11 changed files with 350 additions and 157 deletions
|
|
@ -50,12 +50,12 @@ namespace engine {
|
|||
|
||||
|
||||
/**
|
||||
* an opaque ID to be used by the BufferProvider implementation.
|
||||
* an opaque mark to be used by the BufferProvider implementation.
|
||||
* Typically this will be used, to set apart some pre-registered
|
||||
* kinds of buffers. It is treated as being part of the buffer type.
|
||||
* LocalKey objects may be copied but not re-assigned or changed.
|
||||
* LocalTag objects may be copied but not re-assigned or changed.
|
||||
*/
|
||||
class LocalKey
|
||||
class LocalTag
|
||||
{
|
||||
union OpaqueData
|
||||
{
|
||||
|
|
@ -67,17 +67,19 @@ namespace engine {
|
|||
|
||||
public:
|
||||
explicit
|
||||
LocalKey (uint64_t opaqueValue=0)
|
||||
LocalTag (uint64_t opaqueValue=0)
|
||||
{
|
||||
privateID_._as_number = opaqueValue;
|
||||
}
|
||||
|
||||
LocalKey (void* impl_related_ptr)
|
||||
LocalTag (void* impl_related_ptr)
|
||||
{
|
||||
privateID_._as_number = 0;
|
||||
privateID_._as_pointer = impl_related_ptr;
|
||||
}
|
||||
|
||||
/** Marker when no distinct local key is given */
|
||||
static const LocalTag UNKNOWN;
|
||||
|
||||
operator uint64_t() const
|
||||
{
|
||||
|
|
@ -89,26 +91,26 @@ namespace engine {
|
|||
return privateID_._as_pointer;
|
||||
}
|
||||
|
||||
bool
|
||||
isDefined() const
|
||||
explicit
|
||||
operator bool() const
|
||||
{
|
||||
return bool(privateID_._as_number);
|
||||
}
|
||||
|
||||
friend size_t
|
||||
hash_value (LocalKey const& lkey)
|
||||
hash_value (LocalTag const& lkey)
|
||||
{
|
||||
boost::hash<uint64_t> hashFunction;
|
||||
return hashFunction(lkey.privateID_._as_number);
|
||||
}
|
||||
|
||||
friend bool
|
||||
operator== (LocalKey const& left, LocalKey const& right)
|
||||
operator== (LocalTag const& left, LocalTag const& right)
|
||||
{
|
||||
return uint64_t(left) == uint64_t(right);
|
||||
}
|
||||
friend bool
|
||||
operator!= (LocalKey const& left, LocalKey const& right)
|
||||
operator!= (LocalTag const& left, LocalTag const& right)
|
||||
{
|
||||
return uint64_t(left) != uint64_t(right);
|
||||
}
|
||||
|
|
@ -116,7 +118,7 @@ namespace engine {
|
|||
|
||||
private:
|
||||
/** assignment usually prohibited */
|
||||
LocalKey& operator= (LocalKey const& o)
|
||||
LocalTag& operator= (LocalTag const& o)
|
||||
{
|
||||
privateID_ = o.privateID_;
|
||||
return *this;
|
||||
|
|
|
|||
|
|
@ -104,19 +104,16 @@ namespace engine {
|
|||
|
||||
namespace { // internal constants to mark the default case
|
||||
|
||||
const LocalKey UNSPECIFIC;
|
||||
const TypeHandler RAW_BUFFER;
|
||||
|
||||
inline bool
|
||||
nontrivial (TypeHandler const& toVerify)
|
||||
{
|
||||
return RAW_BUFFER != toVerify;
|
||||
return TypeHandler::RAW != toVerify;
|
||||
}
|
||||
|
||||
inline bool
|
||||
nontrivial (LocalKey const& toVerify)
|
||||
nontrivial (LocalTag const& toVerify)
|
||||
{
|
||||
return UNSPECIFIC != toVerify;
|
||||
return LocalTag::UNKNOWN != toVerify;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -151,7 +148,7 @@ namespace engine {
|
|||
protected:
|
||||
size_t storageSize_;
|
||||
TypeHandler instanceFunc_;
|
||||
LocalKey specifics_;
|
||||
LocalTag specifics_;
|
||||
|
||||
|
||||
public:
|
||||
|
|
@ -165,8 +162,8 @@ namespace engine {
|
|||
: parent_(familyID)
|
||||
, hashID_(chainedHash (familyID, storageSize))
|
||||
, storageSize_(storageSize)
|
||||
, instanceFunc_(RAW_BUFFER)
|
||||
, specifics_(UNSPECIFIC)
|
||||
, instanceFunc_(TypeHandler::RAW)
|
||||
, specifics_(LocalTag::UNKNOWN)
|
||||
{ }
|
||||
|
||||
// standard copy operations permitted
|
||||
|
|
@ -201,12 +198,12 @@ namespace engine {
|
|||
* Using a different private ID than the parent type,
|
||||
* all else remaining the same
|
||||
*/
|
||||
Key (Key const& parent, LocalKey anotherTypeSpecificInternalID)
|
||||
Key (Key const& parent, LocalTag anotherTypeSpecificInternalTag)
|
||||
: parent_(parent.hashID_)
|
||||
, hashID_(chainedHash (parent_, anotherTypeSpecificInternalID))
|
||||
, hashID_(chainedHash (parent_, anotherTypeSpecificInternalTag))
|
||||
, storageSize_(parent.storageSize_)
|
||||
, instanceFunc_(parent.instanceFunc_)
|
||||
, specifics_(anotherTypeSpecificInternalID) // differing from parent
|
||||
, specifics_(anotherTypeSpecificInternalTag) // differing from parent
|
||||
{ }
|
||||
|
||||
|
||||
|
|
@ -217,19 +214,19 @@ namespace engine {
|
|||
* For NULL buffer a copy of the parent is returned.
|
||||
*/
|
||||
static Key
|
||||
forEntry (Key const& parent, const void* bufferAddr, LocalKey const& implID =UNSPECIFIC)
|
||||
forEntry (Key const& parent, const void* bufferAddr, LocalTag const& localTag =LocalTag::UNKNOWN)
|
||||
{
|
||||
Key newKey(parent);
|
||||
Key newKey{parent}; // copy of parent as baseline
|
||||
if (bufferAddr)
|
||||
{
|
||||
newKey.parent_ = HashVal(parent);
|
||||
newKey.hashID_ = chainedHash(parent, bufferAddr);
|
||||
if (nontrivial(implID))
|
||||
if (nontrivial(localTag))
|
||||
{
|
||||
REQUIRE (!newKey.specifics_.isDefined(),
|
||||
"Implementation defined local key should not be overridden. "
|
||||
"Underlying buffer type already defines a nontrivial LocalKey");
|
||||
newKey.specifics_ = implID;
|
||||
if (nontrivial(parent.specifics_))
|
||||
throw error::Logic{"Implementation defined local key should not be overridden. "
|
||||
"Underlying buffer type already defines a nontrivial LocalTag"};
|
||||
newKey.specifics_ = localTag;
|
||||
} }
|
||||
return newKey;
|
||||
}
|
||||
|
|
@ -244,7 +241,7 @@ namespace engine {
|
|||
}
|
||||
|
||||
|
||||
LocalKey const& localKey() const { return specifics_;}
|
||||
LocalTag const& localTag() const { return specifics_;}
|
||||
size_t storageSize() const { return storageSize_; }
|
||||
|
||||
HashVal parentKey() const { return parent_;}
|
||||
|
|
@ -273,10 +270,13 @@ namespace engine {
|
|||
void* buffer_;
|
||||
|
||||
protected:
|
||||
Entry (Key const& parent, void* bufferPtr =0, LocalKey const& implID =UNSPECIFIC)
|
||||
: Key (Key::forEntry (parent, bufferPtr, implID))
|
||||
, state_(bufferPtr? LOCKED:NIL)
|
||||
, buffer_(bufferPtr)
|
||||
Entry (Key const& parent
|
||||
,void* bufferPtr =nullptr
|
||||
,LocalTag const& specialTag =LocalTag::UNKNOWN
|
||||
)
|
||||
: Key{Key::forEntry (parent, bufferPtr, specialTag)}
|
||||
, state_{bufferPtr? LOCKED:NIL}
|
||||
, buffer_{bufferPtr}
|
||||
{ }
|
||||
|
||||
/// BufferMetadata is allowed to create
|
||||
|
|
@ -290,7 +290,7 @@ namespace engine {
|
|||
bool
|
||||
isLocked() const
|
||||
{
|
||||
ASSERT (!buffer_ || (NIL != state_ && FREE != state_));
|
||||
ASSERT (!buffer_ or (NIL != state_ and FREE != state_));
|
||||
return bool(buffer_);
|
||||
}
|
||||
|
||||
|
|
@ -300,7 +300,7 @@ namespace engine {
|
|||
bool
|
||||
isTypeKey() const
|
||||
{
|
||||
return NIL == state_ && !buffer_;
|
||||
return NIL == state_ and not buffer_;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -326,13 +326,13 @@ namespace engine {
|
|||
{
|
||||
__must_not_be_NIL();
|
||||
|
||||
if ( (state_ == FREE && newState == LOCKED)
|
||||
||(state_ == LOCKED && newState == EMITTED)
|
||||
||(state_ == LOCKED && newState == BLOCKED)
|
||||
||(state_ == LOCKED && newState == FREE)
|
||||
||(state_ == EMITTED && newState == BLOCKED)
|
||||
||(state_ == EMITTED && newState == FREE)
|
||||
||(state_ == BLOCKED && newState == FREE))
|
||||
if ( (state_ == FREE and newState == LOCKED)
|
||||
or (state_ == LOCKED and newState == EMITTED)
|
||||
or (state_ == LOCKED and newState == BLOCKED)
|
||||
or (state_ == LOCKED and newState == FREE)
|
||||
or (state_ == EMITTED and newState == BLOCKED)
|
||||
or (state_ == EMITTED and newState == FREE)
|
||||
or (state_ == BLOCKED and newState == FREE))
|
||||
{
|
||||
// allowed transition
|
||||
if (newState == FREE)
|
||||
|
|
@ -357,7 +357,7 @@ namespace engine {
|
|||
Entry&
|
||||
invalidate (bool invokeDtor =true)
|
||||
{
|
||||
if (buffer_ && invokeDtor)
|
||||
if (buffer_ and invokeDtor)
|
||||
invokeEmbeddedDtor_and_clear();
|
||||
buffer_ = 0;
|
||||
state_ = FREE;
|
||||
|
|
@ -546,8 +546,8 @@ namespace engine {
|
|||
///////////////////////////TICKET #854 : ensure proper locking happens "somewhere" when mutating metadata
|
||||
|
||||
public:
|
||||
typedef metadata::Key Key;
|
||||
typedef metadata::Entry Entry;
|
||||
using Key = metadata::Key;
|
||||
using Entry = metadata::Entry;
|
||||
|
||||
/** establish a metadata registry.
|
||||
* Such will maintain a family of buffer type entries
|
||||
|
|
@ -566,15 +566,15 @@ namespace engine {
|
|||
* from that point on. Properties are combined according to
|
||||
* a fixed type specialisation order, with the buffer size
|
||||
* forming the base level, possible TypeHandler functors the
|
||||
* second level, and implementation defined LocalKey entries
|
||||
* second level, and implementation defined LocalTag entries
|
||||
* the third level. All these levels describe abstract type
|
||||
* keys, not entries for concrete buffers. The latter are
|
||||
* always created as children of a known type key.
|
||||
*/
|
||||
Key
|
||||
key ( size_t storageSize
|
||||
, TypeHandler instanceFunc =RAW_BUFFER
|
||||
, LocalKey specifics =UNSPECIFIC)
|
||||
, TypeHandler instanceFunc =TypeHandler::RAW
|
||||
, LocalTag specifics =LocalTag::UNKNOWN)
|
||||
{
|
||||
REQUIRE (storageSize);
|
||||
Key typeKey = trackKey (family_, storageSize);
|
||||
|
|
@ -598,7 +598,7 @@ namespace engine {
|
|||
/** create a sub-type,
|
||||
* using a different private-ID (implementation defined) */
|
||||
Key
|
||||
key (Key const& parentKey, LocalKey specifics)
|
||||
key (Key const& parentKey, LocalTag specifics)
|
||||
{
|
||||
return trackKey (parentKey, specifics);
|
||||
}
|
||||
|
|
@ -608,13 +608,13 @@ namespace engine {
|
|||
* @note might create/register a new Entry as a side-effect
|
||||
*/
|
||||
Key const&
|
||||
key (Key const& parentKey, void* concreteBuffer, LocalKey const& implID =UNSPECIFIC)
|
||||
key (Key const& parentKey, void* concreteBuffer, LocalTag const& specifics =LocalTag::UNKNOWN)
|
||||
{
|
||||
Key derivedKey = Key::forEntry (parentKey, concreteBuffer);
|
||||
Entry* existing = table_.fetch (derivedKey);
|
||||
|
||||
return existing? *existing
|
||||
: markLocked (parentKey,concreteBuffer,implID);
|
||||
: markLocked (parentKey,concreteBuffer,specifics);
|
||||
}
|
||||
|
||||
/** core operation to access or create a concrete buffer metadata entry.
|
||||
|
|
@ -642,21 +642,21 @@ namespace engine {
|
|||
Entry&
|
||||
lock (Key const& parentKey
|
||||
,void* concreteBuffer
|
||||
,LocalKey const& implID =UNSPECIFIC
|
||||
,LocalTag const& specifics =LocalTag::UNKNOWN
|
||||
,bool onlyNew =false)
|
||||
{
|
||||
if (!concreteBuffer)
|
||||
throw error::Invalid{"Attempt to lock a slot for a NULL buffer"
|
||||
, LERR_(BOTTOM_VALUE)};
|
||||
|
||||
Entry newEntry(parentKey, concreteBuffer, implID);
|
||||
Entry newEntry{parentKey, concreteBuffer, specifics};
|
||||
Entry* existing = table_.fetch (newEntry);
|
||||
|
||||
if (existing && onlyNew)
|
||||
if (existing and onlyNew)
|
||||
throw error::Logic{"Attempt to lock a slot for a new buffer, "
|
||||
"while actually the old buffer is still locked"
|
||||
, LERR_(LIFECYCLE)};
|
||||
if (existing && existing->isLocked())
|
||||
if (existing and existing->isLocked())
|
||||
throw error::Logic{"Attempt to re-lock a buffer still in use"
|
||||
, LERR_(LIFECYCLE)};
|
||||
|
||||
|
|
@ -695,7 +695,7 @@ namespace engine {
|
|||
{
|
||||
const Entry* entry = table_.fetch (key);
|
||||
return entry
|
||||
&& entry->isLocked();
|
||||
and entry->isLocked();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -713,13 +713,13 @@ namespace engine {
|
|||
* created, but is marked as FREE
|
||||
*/
|
||||
Entry&
|
||||
markLocked (Key const& parentKey, void* buffer, LocalKey const& implID =UNSPECIFIC)
|
||||
markLocked (Key const& parentKey, void* buffer, LocalTag const& specifics =LocalTag::UNKNOWN)
|
||||
{
|
||||
if (!buffer)
|
||||
throw error::Fatal{"Attempt to lock for a NULL buffer. Allocation floundered?"
|
||||
, LERR_(BOTTOM_VALUE)};
|
||||
|
||||
return this->lock(parentKey, buffer, implID, true); // force creation of a new entry
|
||||
return this->lock (parentKey, buffer, specifics, true); // force creation of a new entry
|
||||
}
|
||||
|
||||
/** purge the bare metadata Entry from the metadata tables.
|
||||
|
|
@ -731,7 +731,7 @@ namespace engine {
|
|||
Entry* entry = table_.fetch (key);
|
||||
if (!entry) return;
|
||||
|
||||
ASSERT (entry && (key == HashVal(*entry)));
|
||||
ASSERT (entry and (key == HashVal(*entry)));
|
||||
release (*entry);
|
||||
}
|
||||
|
||||
|
|
@ -787,6 +787,5 @@ namespace engine {
|
|||
|
||||
|
||||
|
||||
|
||||
}} // namespace steam::engine
|
||||
#endif
|
||||
#endif /*STEAM_ENGINE_BUFFR_METADATA_H*/
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@ using util::isSameObject;
|
|||
namespace steam {
|
||||
namespace engine {
|
||||
|
||||
// storage for the default-marker constants
|
||||
const TypeHandler TypeHandler::RAW{};
|
||||
const LocalTag LocalTag::UNKNOWN{};
|
||||
|
||||
|
||||
namespace { // impl. details and definitions
|
||||
|
||||
|
|
@ -98,10 +102,10 @@ namespace engine {
|
|||
* actual buffer, which is locked for exclusive use by one client.
|
||||
*/
|
||||
BuffHandle
|
||||
BufferProvider::buildHandle (HashVal typeID, void* storage, LocalKey const& implID)
|
||||
BufferProvider::buildHandle (HashVal typeID, void* storage, LocalTag const& localTag)
|
||||
{
|
||||
metadata::Key& typeKey = meta_->get (typeID);
|
||||
metadata::Entry& entry = meta_->markLocked(typeKey, storage, implID);
|
||||
metadata::Entry& entry = meta_->markLocked(typeKey, storage, localTag);
|
||||
|
||||
return BuffHandle (BuffDescr(*this, entry), storage);
|
||||
}
|
||||
|
|
@ -167,7 +171,7 @@ namespace engine {
|
|||
BufferProvider::emitBuffer (BuffHandle const& handle)
|
||||
{
|
||||
metadata::Entry& metaEntry = meta_->get (handle.entryID());
|
||||
mark_emitted (metaEntry.parentKey(), metaEntry.localKey());
|
||||
mark_emitted (metaEntry.parentKey(), metaEntry.localTag());
|
||||
metaEntry.mark(EMITTED);
|
||||
}
|
||||
|
||||
|
|
@ -185,7 +189,7 @@ namespace engine {
|
|||
try {
|
||||
metadata::Entry& metaEntry = meta_->get (handle.entryID());
|
||||
metaEntry.mark(FREE); // might invoke embedded dtor function
|
||||
detachBuffer (metaEntry.parentKey(), metaEntry.localKey());
|
||||
detachBuffer (metaEntry.parentKey(), metaEntry.localTag());
|
||||
meta_->release (metaEntry);
|
||||
}
|
||||
ERROR_LOG_AND_IGNORE (engine, "releasing a buffer from BufferProvider")
|
||||
|
|
@ -229,7 +233,7 @@ namespace engine {
|
|||
try {
|
||||
metadata::Entry& metaEntry = meta_->get (target.entryID());
|
||||
metaEntry.invalidate (invokeDtor);
|
||||
detachBuffer (metaEntry.parentKey(), metaEntry.localKey());
|
||||
detachBuffer (metaEntry.parentKey(), metaEntry.localTag());
|
||||
meta_->release (metaEntry);
|
||||
}
|
||||
ERROR_LOG_AND_IGNORE (engine, "cleanup of buffer metadata while handling an error")
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ namespace engine {
|
|||
* The pointer to actual buffer storage can be retrieved by
|
||||
* - optionally announcing the required buffer(s) beforehand
|
||||
* - "locking" a buffer to yield a buffer handle
|
||||
* - dereferencing this smart-handle class
|
||||
* - then dereferencing the obtained smart-handle
|
||||
*
|
||||
* @warning all of BufferProvider is assumed to run within a threadsafe environment.
|
||||
*
|
||||
|
|
@ -93,8 +93,8 @@ namespace engine {
|
|||
virtual uint prepareBuffers (uint count, HashVal typeID) =0;
|
||||
|
||||
virtual BuffHandle provideLockedBuffer (HashVal typeID) =0;
|
||||
virtual void mark_emitted (HashVal typeID, LocalKey const&) =0;
|
||||
virtual void detachBuffer (HashVal typeID, LocalKey const&) =0;
|
||||
virtual void mark_emitted (HashVal typeID, LocalTag const&) =0;
|
||||
virtual void detachBuffer (HashVal typeID, LocalTag const&) =0;
|
||||
|
||||
|
||||
public:
|
||||
|
|
@ -131,7 +131,7 @@ namespace engine {
|
|||
size_t getBufferSize (HashVal typeID) const;
|
||||
|
||||
protected:
|
||||
BuffHandle buildHandle (HashVal typeID, void* storage, LocalKey const&);
|
||||
BuffHandle buildHandle (HashVal typeID, void* storage, LocalTag const& =LocalTag::UNKNOWN);
|
||||
|
||||
bool was_created_by_this_provider (BuffDescr const&) const;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ namespace engine {
|
|||
|
||||
/** convenience shortcut: access the buffer contents casted to a specific type.
|
||||
* @warning this is a \em blind cast, there is no type safety.
|
||||
* @note clients can utilise the metadata::LocalKey to keep track of some
|
||||
* @note clients can utilise the metadata::LocalTag to keep track of some
|
||||
* specific property of the buffer, like e.g. the type of object.
|
||||
*/
|
||||
template<typename BU>
|
||||
|
|
|
|||
|
|
@ -252,9 +252,9 @@ namespace engine {
|
|||
|
||||
|
||||
void
|
||||
TrackingHeapBlockProvider::mark_emitted (HashVal typeID, LocalKey const& implID)
|
||||
TrackingHeapBlockProvider::mark_emitted (HashVal typeID, LocalTag const& specifics)
|
||||
{
|
||||
diagn::Block* block4buffer = locateBlock (typeID, implID);
|
||||
diagn::Block* block4buffer = locateBlock (typeID, specifics);
|
||||
if (!block4buffer)
|
||||
throw error::Logic ("Attempt to emit a buffer not known to this BufferProvider"
|
||||
, LUMIERA_ERROR_BUFFER_MANAGEMENT);
|
||||
|
|
@ -265,9 +265,9 @@ namespace engine {
|
|||
|
||||
/** mark a buffer as officially discarded */
|
||||
void
|
||||
TrackingHeapBlockProvider::detachBuffer (HashVal typeID, LocalKey const& implID)
|
||||
TrackingHeapBlockProvider::detachBuffer (HashVal typeID, LocalTag const& specifics)
|
||||
{
|
||||
diagn::Block* block4buffer = locateBlock (typeID, implID);
|
||||
diagn::Block* block4buffer = locateBlock (typeID, specifics);
|
||||
REQUIRE (block4buffer, "releasing a buffer not allocated through this provider");
|
||||
block4buffer->markReleased();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
** the fact.
|
||||
**
|
||||
** The allocated buffers are numbered with a simple ascending sequence of integers,
|
||||
** used as LocalKey (see BufferMetadata). Clients can just request a Buffer with the
|
||||
** used as LocalTag (see BufferMetadata). Clients can just request a Buffer with the
|
||||
** given number, causing that block to be allocated. There is a "backdoor", allowing
|
||||
** to access any allocated block, even if it is considered "released" by the terms
|
||||
** of the usual lifecycle. Only when the provider object itself gets destroyed,
|
||||
|
|
@ -136,8 +136,8 @@ namespace engine {
|
|||
|
||||
virtual uint prepareBuffers (uint count, HashVal typeID);
|
||||
virtual BuffHandle provideLockedBuffer (HashVal typeID);
|
||||
virtual void mark_emitted (HashVal entryID, LocalKey const&);
|
||||
virtual void detachBuffer (HashVal entryID, LocalKey const&);
|
||||
virtual void mark_emitted (HashVal entryID, LocalTag const&);
|
||||
virtual void detachBuffer (HashVal entryID, LocalTag const&);
|
||||
|
||||
public:
|
||||
TrackingHeapBlockProvider();
|
||||
|
|
|
|||
|
|
@ -118,6 +118,9 @@ namespace engine {
|
|||
DoInBuffer destroyAttached;
|
||||
HashVal identity;
|
||||
|
||||
/** Marker for the default case: raw buffer without type handling */
|
||||
static const TypeHandler RAW;
|
||||
|
||||
/** build an invalid NIL TypeHandler */
|
||||
TypeHandler()
|
||||
: createAttached()
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ namespace test {
|
|||
{
|
||||
size_t const& investigateSize() const { return this->storageSize_; }
|
||||
TypeHandler const& investigateHandler() const { return this->instanceFunc_; }
|
||||
LocalKey const& investigateSpecifics() const { return this->specifics_; }
|
||||
LocalTag const& investigateSpecifics() const { return this->specifics_; }
|
||||
|
||||
KeyTypeSpecialisationDiagnostics (Key const& toInvestigate)
|
||||
: Key(toInvestigate)
|
||||
|
|
@ -140,7 +140,7 @@ namespace test {
|
|||
return KeyTypeSpecialisationDiagnostics(subject).investigateHandler();
|
||||
}
|
||||
|
||||
inline const LocalKey
|
||||
inline const LocalTag
|
||||
verifySpecifics (Key const& subject)
|
||||
{
|
||||
return KeyTypeSpecialisationDiagnostics(subject).investigateSpecifics();
|
||||
|
|
@ -191,7 +191,7 @@ namespace test {
|
|||
HashVal family(123);
|
||||
Key k1(family, SIZE_A);
|
||||
Key k12(k1, SIZE_B);
|
||||
Key k123(k12, LocalKey(56));
|
||||
Key k123(k12, LocalTag(56));
|
||||
|
||||
CHECK (HashVal (k1));
|
||||
CHECK (HashVal (k12));
|
||||
|
|
@ -257,8 +257,8 @@ namespace test {
|
|||
TypeHandler placeMarker = TypeHandler::create<Marker>();
|
||||
TypeHandler noHandler;
|
||||
|
||||
LocalKey opaque1 (rand() % 1000);
|
||||
LocalKey opaque2 (1000 + rand() % 1000);
|
||||
LocalTag opaque1 (rand() % 1000);
|
||||
LocalTag opaque2 (1000 + rand() % 1000);
|
||||
|
||||
Key k_siz (kb, SIZE_B); // sub-key to "root": use a different buffer size
|
||||
Key k_han0(kb, noHandler); // sub-key to "root": use a locally defined type functor
|
||||
|
|
@ -305,19 +305,19 @@ namespace test {
|
|||
CHECK (SIZE_A == verifySize(k_loc1));
|
||||
CHECK (SIZE_A == verifySize(k_loc2));
|
||||
|
||||
CHECK (RAW_BUFFER == verifyHandler(kb ));
|
||||
CHECK (RAW_BUFFER == verifyHandler(k_siz ));
|
||||
CHECK (noHandler == verifyHandler(k_han0));
|
||||
CHECK (placeMarker == verifyHandler(k_han1));
|
||||
CHECK (RAW_BUFFER == verifyHandler(k_loc1));
|
||||
CHECK (RAW_BUFFER == verifyHandler(k_loc2));
|
||||
CHECK (TypeHandler::RAW == verifyHandler(kb ));
|
||||
CHECK (TypeHandler::RAW == verifyHandler(k_siz ));
|
||||
CHECK ( noHandler == verifyHandler(k_han0));
|
||||
CHECK ( placeMarker == verifyHandler(k_han1));
|
||||
CHECK (TypeHandler::RAW == verifyHandler(k_loc1));
|
||||
CHECK (TypeHandler::RAW == verifyHandler(k_loc2));
|
||||
|
||||
CHECK (UNSPECIFIC == verifySpecifics(kb ));
|
||||
CHECK (UNSPECIFIC == verifySpecifics(k_siz ));
|
||||
CHECK (UNSPECIFIC == verifySpecifics(k_han0));
|
||||
CHECK (UNSPECIFIC == verifySpecifics(k_han1));
|
||||
CHECK (opaque1 == verifySpecifics(k_loc1));
|
||||
CHECK (opaque2 == verifySpecifics(k_loc2));
|
||||
CHECK (LocalTag::UNKNOWN == verifySpecifics(kb ));
|
||||
CHECK (LocalTag::UNKNOWN == verifySpecifics(k_siz ));
|
||||
CHECK (LocalTag::UNKNOWN == verifySpecifics(k_han0));
|
||||
CHECK (LocalTag::UNKNOWN == verifySpecifics(k_han1));
|
||||
CHECK ( opaque1 == verifySpecifics(k_loc1));
|
||||
CHECK ( opaque2 == verifySpecifics(k_loc2));
|
||||
|
||||
|
||||
// Verify 2nd level specialisation (some examples)
|
||||
|
|
@ -338,8 +338,8 @@ namespace test {
|
|||
CHECK (placeMarker == verifyHandler(k_han1_siz_loc2));
|
||||
CHECK (placeMarker == verifyHandler(k_loc2_han1_siz));
|
||||
|
||||
CHECK (UNSPECIFIC == verifySpecifics(k_han1_siz ));
|
||||
CHECK (UNSPECIFIC == verifySpecifics(k_siz_han1 ));
|
||||
CHECK (LocalTag::UNKNOWN == verifySpecifics(k_han1_siz ));
|
||||
CHECK (LocalTag::UNKNOWN == verifySpecifics(k_siz_han1 ));
|
||||
CHECK (opaque2 == verifySpecifics(k_han1_siz_loc2));
|
||||
CHECK (opaque2 == verifySpecifics(k_loc2_han1_siz));
|
||||
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ namespace test {
|
|||
* BufferProviderProtocol_test#verifyStandardCase()
|
||||
* This testcase here performs precisely the metadata related
|
||||
* operations necessary to carry out the standard case
|
||||
* outlined on a higher level in the mentioned test.
|
||||
* outlined at a higher level in the aforementioned test.
|
||||
*/
|
||||
void
|
||||
verifyStandardCase()
|
||||
|
|
@ -206,8 +206,8 @@ namespace test {
|
|||
metadata::Key rawBuffType = meta_->key(SIZE_B);
|
||||
|
||||
// to announce using a number of buffers of this type
|
||||
LocalKey transaction1(1);
|
||||
LocalKey transaction2(2);
|
||||
LocalTag transaction1(1);
|
||||
LocalTag transaction2(2);
|
||||
bufferType1 = meta_->key(bufferType1, transaction1);
|
||||
rawBuffType = meta_->key(rawBuffType, transaction2);
|
||||
// these type keys are now handed over to the client,
|
||||
|
|
@ -235,11 +235,11 @@ namespace test {
|
|||
CHECK (LOCKED == r0.state());
|
||||
CHECK (LOCKED == r1.state());
|
||||
|
||||
CHECK (transaction1 == f0.localKey());
|
||||
CHECK (transaction1 == f1.localKey());
|
||||
CHECK (transaction1 == f2.localKey());
|
||||
CHECK (transaction2 == r0.localKey());
|
||||
CHECK (transaction2 == r1.localKey());
|
||||
CHECK (transaction1 == f0.localTag());
|
||||
CHECK (transaction1 == f1.localTag());
|
||||
CHECK (transaction1 == f2.localTag());
|
||||
CHECK (transaction2 == r0.localTag());
|
||||
CHECK (transaction2 == r1.localTag());
|
||||
|
||||
|
||||
CHECK (f0.access() == frames+0);
|
||||
|
|
|
|||
|
|
@ -4369,9 +4369,7 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1481599413419" HGAP="34" ID="ID_673133356" MODIFIED="1576282358148" TEXT="Ticket #318" VSHIFT="-7">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
....das ist schon mehr ein Meta-Ticket,
|
||||
|
|
@ -4442,9 +4440,7 @@
|
|||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1481684391921" ID="ID_138369898" MODIFIED="1576282358147" TEXT="Front-End">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
das Lock sorgt hier für konsistenten Zustand und Sichtbarkeit (memory barrier)
|
||||
|
|
@ -4454,9 +4450,7 @@
|
|||
</node>
|
||||
<node CREATED="1481684394544" ID="ID_1314197501" MODIFIED="1576282358147" TEXT="Back-End">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Lock ist hier das Dispatcher-Lock
|
||||
|
|
@ -5092,9 +5086,7 @@
|
|||
<node CREATED="1553902314962" ID="ID_1100232681" MODIFIED="1553902322907" TEXT="vorläufige Platzhalter-Implementierung"/>
|
||||
<node CREATED="1553902329566" ID="ID_149032705" MODIFIED="1576282358142" TEXT="PanelLocator">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
8/2018 there is some overlap with the (not yet fully functional) 
|
||||
|
|
@ -5825,9 +5817,7 @@
|
|||
<node CREATED="1567875285952" ID="ID_979231150" MODIFIED="1567875288691" TEXT="TestControl"/>
|
||||
<node COLOR="#435e98" CREATED="1567875664340" ID="ID_994953692" MODIFIED="1567875770727">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
<b>TestControl</b> Dialogbox
|
||||
|
|
@ -7555,9 +7545,7 @@
|
|||
<node CREATED="1508016623480" ID="ID_66450805" MODIFIED="1518487921064" TEXT="Element speichert seine UICoord"/>
|
||||
<node CREATED="1508016658684" ID="ID_116864327" MODIFIED="1518487921064" TEXT="globaler Index beim Erstellen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...der beim Erstellen des Elements
|
||||
|
|
@ -10053,9 +10041,7 @@
|
|||
<node CREATED="1513447967084" ID="ID_476332936" MODIFIED="1513447978718" TEXT="d.h. muß die logische Tiefe widerspiegeln"/>
|
||||
<node CREATED="1513447979450" ID="ID_224439756" MODIFIED="1513448250249" TEXT="...auch wenn der Vater bereits erschöpft ist">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
wir hatten bisher eine auto-Aufräum-Routine in iterNext(),
|
||||
|
|
@ -13742,9 +13728,7 @@
|
|||
<node CREATED="1518742996348" ID="ID_328356111" MODIFIED="1518743006606" TEXT="von der Ebene der Sprache her schwer zu verstehen"/>
|
||||
<node CREATED="1518743012337" ID="ID_1220573120" MODIFIED="1518743054926">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
bleibt dem Charakter nach <i>imperativ</i>
|
||||
|
|
@ -52706,9 +52690,7 @@
|
|||
</node>
|
||||
<node CREATED="1492174243863" ID="ID_900555701" MODIFIED="1492174267140">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
aber: Parametrisierung <i>könnte</i> partiell sein
|
||||
|
|
@ -52757,9 +52739,7 @@
|
|||
<node CREATED="1492269422257" ID="ID_921483875" MODIFIED="1492269432251" TEXT="aber nur im ProcDispatcher"/>
|
||||
<node CREATED="1492269451181" ID="ID_800020285" MODIFIED="1492269548819">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
sie wird nicht zum <i>Parameter-Sammeln</i> verwendet
|
||||
|
|
@ -52774,9 +52754,7 @@
|
|||
</node>
|
||||
<node CREATED="1492269922724" ID="ID_806519829" MODIFIED="1576282357981" TEXT="Idee: on demand">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...eine Instanz wird dann erzeugt, wenn sie notwendig wird.
|
||||
|
|
@ -80753,6 +80731,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1713795084878" ID="ID_900623108" MODIFIED="1713795152331" TEXT="das Buffer-Protocol gilt als gesetzt">
|
||||
<linktarget COLOR="#3c61b7" DESTINATION="ID_900623108" ENDARROW="Default" ENDINCLINATION="-475;-40;" ID="Arrow_ID_245920004" SOURCE="ID_267762321" STARTARROW="None" STARTINCLINATION="-218;8;"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
<node COLOR="#435e98" CREATED="1721958694600" ID="ID_769985598" MODIFIED="1721958851624" TEXT="dokumentiert durch: nur BufferProviderProtocol_test">
|
||||
<arrowlink COLOR="#5387dc" DESTINATION="ID_1661035289" ENDARROW="Default" ENDINCLINATION="-1176;-93;" ID="Arrow_ID_1311080426" STARTARROW="None" STARTINCLINATION="-1176;64;"/>
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#2a0f69" CREATED="1721958519256" ID="ID_876959484" MODIFIED="1721958541355" TEXT="wichtig zum Verständnis: BufferMetadata_test">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1713819850506" ID="ID_1750491613" MODIFIED="1713819862771" TEXT="zu klären">
|
||||
|
|
@ -88404,8 +88389,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<i>was bis jetzt feststeht</i>: dem Weaving-Pattern werden <font face="Monospaced" color="#37285a"><b>BufferDescriptor</b></font>s gegeben
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
<node CREATED="1721833630028" ID="ID_1463882000" MODIFIED="1721833743407">
|
||||
|
|
@ -88416,8 +88400,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
Begründung: der <i>Aufrufer</i> legt das zusammen mit der konkreten Funktion fest
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
|
|
@ -88425,8 +88408,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
Der Aufrufer ist Code im Kontext der Domain-Ontology, und nur von dort kann bekannt sein, was die eingebundene Funktion konkret auf jedem »output slot« liefert
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1721833744653" ID="ID_564134305" MODIFIED="1721833811643">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
|
|
@ -88436,8 +88418,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
Einschränkung: der Aufrufer kennt den <i>benötigten Typ</i> des Buffers
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<font NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node COLOR="#5b280f" CREATED="1721833852346" ID="ID_1878630710" MODIFIED="1721833866578">
|
||||
|
|
@ -88481,8 +88462,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
heißt konkret, ein BufferProdiver könnte einen BufferDescriptor eines anderen Providers übernehmen und re-interpretieren
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -88537,8 +88517,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<font color="#302948" face="Monospaced">  BufferProvider::</font><font color="#251e7b" face="Monospaced">getDescriptor</font><font color="#302948" face="Monospaced"> (</font><font color="#981d2b" face="Monospaced"><b>ARGS</b></font><font color="#302948" face="Monospaced">  ...args)</font>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1721841418133" HGAP="22" ID="ID_358050145" MODIFIED="1721841447356" TEXT="das wäre dann aber noch eine weitere Indirektion" VSHIFT="11">
|
||||
|
|
@ -88561,8 +88540,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
⟹ das müßte dann in den <font face="Monospaced"><b>shed()</b></font>-Aufruf gehen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -88582,8 +88560,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
...im aktuellen Stand brauchen wir die Info nur während dem Build-Vorgang; sobald man aber später übergeht zu einem ctor-λ, müßte man die Info in die Node (in den Turnout) materialisieren. Nun könnte man aktuell „einfach“ einen std::vector nehmen — oder aber, genauso „einfach“ einen weiteren SeveralBuilder mitlaufen lassen. Vorteil: der Speicher liegt im AllocationCluster / Nachteil: der Speicher wird verschwendet
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1721842211509" ID="ID_136741154" MODIFIED="1721842223063" TEXT="nun kann man zwei Richtungen einschlagen...">
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1721842070408" ID="ID_405313573" MODIFIED="1721842263407" TEXT="wennschon dennschon ⟹ dann auch gleich vorsorglich mit materialisieren">
|
||||
|
|
@ -88648,6 +88625,213 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<linktarget COLOR="#494465" DESTINATION="ID_611993343" ENDARROW="Default" ENDINCLINATION="-3;-124;" ID="Arrow_ID_490283859" SOURCE="ID_1921234844" STARTARROW="Default" STARTINCLINATION="-2;70;"/>
|
||||
<linktarget COLOR="#5d434b" DESTINATION="ID_611993343" ENDARROW="Default" ENDINCLINATION="60;-165;" ID="Arrow_ID_819933510" SOURCE="ID_1665424296" STARTARROW="None" STARTINCLINATION="-74;5;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1721866481394" ID="ID_1853457963" MODIFIED="1721866534078" TEXT="zu klären: Scope zur Verdrahtung dieser Services">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1721866537521" ID="ID_1964460392" MODIFIED="1721866548867" TEXT="sie sind effektiv global"/>
|
||||
<node CREATED="1721866551423" ID="ID_779602459" MODIFIED="1721866584882" TEXT="problematisch dabei: der Output-BufferProivder">
|
||||
<node CREATED="1721866589257" ID="ID_1094487880" MODIFIED="1721866862199" TEXT="dieser muß allerdings einen konkreten Bezug herstellen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
im Codepfad des konkreten Aufrufs erfolgt ein lockBuffer() — und dieser muß exakt den Ausgabe-Puffer für diesen Aufruf liefern
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1721866600848" ID="ID_1628166057" MODIFIED="1721866621316" TEXT="und zwar für den einzelnen Slot im jeweiligen Aufruf"/>
|
||||
<node CREATED="1721866623093" ID="ID_172617821" MODIFIED="1721946404316" TEXT="Möglichkeiten für diesen direkten Bezug">
|
||||
<node CREATED="1721946663784" ID="ID_958099025" MODIFIED="1721956949794" TEXT="Output stets explizit kopieren">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
heißt: wir vergeben diese nulläre Optimierung und legen fest, daß das Ergebnis einfach in einem Buffer im Arbeitsspeicher liegt. Jeder Render-Job bekommt dann einen explizit gecodeten Kopier-Schritt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1721866917499" ID="ID_1329080039" MODIFIED="1722005129923" TEXT="ein spezielles Tag im Buffer-Descriptor ablegen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
das müßte eine Marke sein, die die spezielle BufferProvider-Implementierung — also der OutputBufferProvider — erkennt und daraufhin den konkreten extrnen Output-Buffer herausgibt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<linktarget COLOR="#4395d3" DESTINATION="ID_1329080039" ENDARROW="Default" ENDINCLINATION="-105;0;" ID="Arrow_ID_1999279188" SOURCE="ID_1451110951" STARTARROW="None" STARTINCLINATION="6;-21;"/>
|
||||
</node>
|
||||
<node CREATED="1721867643305" ID="ID_327945127" MODIFIED="1721947494363" TEXT="aus dem Schema ausbrechen und diesen Buffer dirrekt durchgeben">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Das würde bedeuten, eine spezielle Ausnahme in die shed()-Funktion einzubauen, um das lockBuffer() fürden tatsächlichen »output-slot« zu unterdrücken und stattdessen hier einen aus dem Kontext bezogenen Buffer einzusetzen. Im Gegenzug würde der Rückgabewert wegfallen und das Ergebnis würde stattdessen per Seiteneffekt herausgeführt.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1721866938881" ID="ID_1696632082" MODIFIED="1721946997871" TEXT="die Annahme machen, daß es in jedem Callstack nur einen solchen Request gibt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Diese Annahme kann man ziemlich sicher machen; eine Abweichung davon wäre nur möglich bei einem ziemlich speziellen Setup, bei dem dann setets mehrere Ergebnise auf verschiedenen Ebenen aber im gleichen Rechenprozeß anfallen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1721956892200" ID="ID_1451110951" MODIFIED="1721956974355" TEXT="strukturell wäre das Spezial-Tag die beste Lösung">
|
||||
<arrowlink COLOR="#4395d3" DESTINATION="ID_1329080039" ENDARROW="Default" ENDINCLINATION="-105;0;" ID="Arrow_ID_1999279188" STARTARROW="None" STARTINCLINATION="6;-21;"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
<node COLOR="#435e98" CREATED="1721957000178" ID="ID_917881726" MODIFIED="1721962405933" TEXT="fragt sich nur: ist das möglich...?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1721957022223" ID="ID_936909569" MODIFIED="1722091785735" TEXT="stelle fest: damals habe ich einen »LocalKey« eingeführt">
|
||||
<node COLOR="#435e98" CREATED="1722091787094" ID="ID_1141022486" MODIFIED="1722091804995" TEXT="inzwischen umbenannt ⟶ LocalTag">
|
||||
<font NAME="SansSerif" SIZE="11"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1721957037236" ID="ID_1595632989" MODIFIED="1721957052094" TEXT="und dazu eine hierarchische Struktur in den Buffer-Metadaten">
|
||||
<node CREATED="1721959590082" ID="ID_526174965" MODIFIED="1722091814802" TEXT="der Metadata-Entry zum Key hat ein zusätzliches Feld LocalTag"/>
|
||||
<node CREATED="1721959630820" ID="ID_1258781639" MODIFIED="1721959649772" TEXT="dieses kann spezialisiert werden — unabhängig vom Type-Handler"/>
|
||||
<node CREATED="1721959662520" ID="ID_820266104" MODIFIED="1721959689960" TEXT="später für die Buffer-Lebenszyklus-Aktionen wird dieses mitgegeben"/>
|
||||
<node CREATED="1721959691067" ID="ID_1814549151" MODIFIED="1722091848881" TEXT="⟹ die konkrete BufferProvider-Impl sieht deses LocalTag...">
|
||||
<node CREATED="1721959715905" ID="ID_1998103464" MODIFIED="1721959721516" TEXT="beim lock() eines Buffers"/>
|
||||
<node CREATED="1721959722368" ID="ID_984626240" MODIFIED="1721959725644" TEXT="beim emit()"/>
|
||||
<node CREATED="1721959726632" ID="ID_639484944" MODIFIED="1721959731395" TEXT="beim release()"/>
|
||||
</node>
|
||||
<node CREATED="1721960062374" ID="ID_465493891" MODIFIED="1721960085785" TEXT="Demo-Impl : TrackingHeapBlockProvider">
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1721960087782" ID="ID_829505722" MODIFIED="1722091866224">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
dieser assoziiert den <b>Buffer-Header</b> als LocalTag
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1721960123381" ID="ID_539555902" MODIFIED="1721962016975" TEXT="macht Sinn, da der Type-Handler ja noch generisch und duplizierbar ist"/>
|
||||
<node CREATED="1721962046996" ID="ID_1135222824" MODIFIED="1721962156716" TEXT="und als Storage nur der eigentliche Buffer gespeichert wird">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...dieser eigentliche Buffer kann auch nochmal per TypeHandler einen »Inlay-Type« bekommen; aber hier beim TrackingHeapBlockProvider ist ja der entscheidenden Punkt, jede Allokation nochmal sekundär zu verzeichnen und nachzuverfolgen, um entsprechende Verifikationen in den Tests zu ermöglichen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1721962165891" ID="ID_1229002680" MODIFIED="1722091876751" TEXT="das LocalTag darf in jeder Hierarchie genau einmal gesetzt werden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
siehe Key::forEntry
|
||||
</p>
|
||||
<p>
|
||||
Das heißt, entweder man setzt ihn schon beim BufferDescriptor, oder man setzt ihn erst mit dem sub-Entry für den konkreten Buffer beim lock() — aber beides zusammen ist nicht erlaubt
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1721957074061" ID="ID_1934276567" LINK="#ID_876959484" MODIFIED="1721958546357" TEXT="siehe BufferMetadata_test::verifyStandardCase()"/>
|
||||
<node COLOR="#435e98" CREATED="1721962300725" ID="ID_1284720886" MODIFIED="1721962403740" TEXT="Fazit">
|
||||
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1721962307945" ID="ID_944887840" MODIFIED="1721962326774" TEXT="meine Analyse von 2013 war gründlich"/>
|
||||
<node CREATED="1721962327606" ID="ID_535842224" MODIFIED="1721962350354">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
deshalb habe ich <b>genau für diesen Zweck</b> bereits einen Mechanismus geschaffen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1721962371425" ID="ID_1532700922" MODIFIED="1722091708754">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
dieses <font color="#1b40b4" face="Monospaced">LocalTag</font> ist aber nicht überall auf das Buffer-Provider-API herausgeführt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1721962419154" ID="ID_197438854" MODIFIED="1721962438994" TEXT="zu überlegen: wann im Lebenszyklus muß diese Info gegeben werden">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1722005002357" ID="ID_1859901064" MODIFIED="1722005054298" TEXT="im Kern ist es eine spezielle Marke für jeden einzelnen Aufruf"/>
|
||||
<node CREATED="1722005137995" ID="ID_1498833312" MODIFIED="1722005163168" TEXT="damit kann sie stets nur für die einzelne Job-Invocation gegeben sein"/>
|
||||
<node CREATED="1722005561810" ID="ID_605283552" MODIFIED="1722005604557" TEXT="zu dem Zeitpunkt haben wir einen Buffer-Descriptor vorliegen">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1722006966966" ID="ID_80799942" MODIFIED="1722007044652" TEXT="neues API benötigt">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<node CREATED="1722006974253" ID="ID_1472014079" MODIFIED="1722006984025" TEXT="aufrufbar auf/mit einem BufferDescriptor"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1722006984755" ID="ID_1802025811" MODIFIED="1722092863044" TEXT="kann ein LocalTag setzen">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1722092776817" ID="ID_1178263086" MODIFIED="1722092793427" TEXT="Bezugspunkt: BufferMetadata::lock()">
|
||||
<node CREATED="1722092795833" ID="ID_444477764" MODIFIED="1722092803241" TEXT="konstruiert einen abgeleiteten Entry"/>
|
||||
<node CREATED="1722092804037" ID="ID_696205920" MODIFIED="1722092813545" TEXT="konstruiert dabei einen abgeleiteten Key"/>
|
||||
<node CREATED="1722092814539" ID="ID_32890513" MODIFIED="1722092832617" TEXT="speichert diesen abgeleiteten Entriy in die Metadaten-Tabelle"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1722092834937" ID="ID_1568128579" MODIFIED="1722092977474" TEXT="prüfen: Hash-Behandlung konsistent">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
im Besonderen an die Reihenfolge denken ... mir fällt auf, daß ich <i>chainedHash</i>  verwende; damit wäre der Hash-Key <i>pfadabhängig</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1722006993331" ID="ID_1387727951" MODIFIED="1722091917790" TEXT="muß mehrfach-Spezialisierung unterbinden">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1722007009608" ID="ID_79703512" MODIFIED="1722091915536" TEXT="benötigt Default-Wert auf der normalen buildHandle">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1722007026247" ID="ID_1017662774" MODIFIED="1722090095412" TEXT="muß dafür die Konstante UNSPECIFIC sichtbar machen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1722092440857" ID="ID_1519590593" MODIFIED="1722092453705" TEXT="(Assertion verschärft in eine Exception)"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1722090806138" ID="ID_1141466279" MODIFIED="1722092473594">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
nebenbei: umbenennen ⟶ <b>LocalTag</b>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -88956,7 +89140,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<linktarget COLOR="#ca3e80" DESTINATION="ID_1795755773" ENDARROW="Default" ENDINCLINATION="333;-16;" ID="Arrow_ID_778082175" SOURCE="ID_1238813567" STARTARROW="None" STARTINCLINATION="-512;47;"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1713824325760" ID="ID_1661035289" MODIFIED="1713824498751" TEXT="BufferProviderProtocol_test">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1713824325760" ID="ID_1661035289" MODIFIED="1721958851624" TEXT="BufferProviderProtocol_test">
|
||||
<linktarget COLOR="#5387dc" DESTINATION="ID_1661035289" ENDARROW="Default" ENDINCLINATION="-1176;-93;" ID="Arrow_ID_1311080426" SOURCE="ID_769985598" STARTARROW="None" STARTINCLINATION="-1176;64;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1713824328087" ID="ID_1065671274" MODIFIED="1713824335184" TEXT="Standard-Fall fertigstellen"/>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue