Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/common/classes/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ class Array : public Storage
count = 0;
}

protected:
const T& getElement(size_type index) const noexcept
{
fb_assert(index < count);
Expand All @@ -182,6 +181,7 @@ class Array : public Storage
return data[index];
}

protected:
void freeData() noexcept
{
// CVC: Warning, after this call, "data" is an invalid pointer, be sure to reassign it
Expand Down
2 changes: 2 additions & 0 deletions src/dsql/DsqlRequests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,8 @@ void DsqlDmlRequest::doExecute(thread_db* tdbb, jrd_tra** traHandle,
firstRowFetched = false;
const dsql_msg* message = dsqlStatement->getSendMsg();

req_transaction->processUpdates(tdbb);

if (!message)
{
JRD_start(tdbb, request, req_transaction);
Expand Down
134 changes: 61 additions & 73 deletions src/jrd/CacheVector.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "../jrd/constants.h"
#include "../jrd/tra_proto.h"
#include "../jrd/QualifiedName.h"
#include "../jrd/obj.h"

namespace Jrd {

Expand Down Expand Up @@ -87,6 +88,13 @@ class ElementBase

virtual ~ElementBase();
virtual void cleanup(thread_db* tdbb) = 0;
virtual ObjectType getObjectType() = 0;
virtual void getObjectName(QualifiedName& name) = 0;
virtual void newVersion(thread_db* tdbb) = 0;
virtual bool ensureVersioned(thread_db* tdbb, ObjectBase::Flag fl) = 0;
virtual void makeRequests(thread_db* tdbb) = 0;
virtual void commit(thread_db* tdbb, TraNumber curNumber = 0) = 0;
virtual MdcVersion getVersion(thread_db* tdbb) = 0;

public:
[[noreturn]] void busyError(thread_db* tdbb, MetaId id, const char* family);
Expand All @@ -99,6 +107,9 @@ class ElementBase
return locked;
}

// fill dependencies info
void fillDeps(thread_db* tdbb, bool forceRecompile);

private:
Lock* lock = nullptr;
std::atomic<bool> locked = false;
Expand Down Expand Up @@ -163,11 +174,17 @@ class ListEntry : public HazardObject
public:
enum State { INITIAL, RELOAD, MISSING, SCANNING, READY };

ListEntry(Versioned* object, TraNumber traNumber, ObjectBase::Flag fl, ListEntry* link = nullptr)
ListEntry(thread_db* tdbb, Versioned* object, TraNumber traNumber, ObjectBase::Flag fl, ListEntry* link = nullptr)
: object(object), traNumber(traNumber), cacheFlags(fl), state(INITIAL)
{
if (fl & CacheFlag::ERASED)
fb_assert(!object);

// Handle front & back versions of MDC
VersionIncr incr(tdbb);
version = incr.getVersion();

// Add to linked list
if (link)
next.store(link);
}
Expand Down Expand Up @@ -550,19 +567,9 @@ class ListEntry : public HazardObject
return state == READY ? false : (thd == Thread::getCurrentThreadId()) && (state == SCANNING);
}

static bool upgradable(HazardPtr<ListEntry>& listEntry, const Versioned* from)
MdcVersion getVersion()
{
for (; listEntry; listEntry.set(listEntry->next))
{
if (listEntry->object == from)
return false; // not found upgrade version

if (listEntry->getFlags() & CacheFlag::COMMITTED)
return true; // already upgraded by someone else
}

fb_assert(false);
return false; // miss from what to upgrade
return version;
}

private:
Expand All @@ -582,7 +589,6 @@ class ListEntry : public HazardObject
TraNumber traNumber; // when COMMITTED not set - stores transaction that created this list element
// when COMMITTED is set - stores transaction after which older elements are not needed
// traNumber to be changed BEFORE setting COMMITTED

MdcVersion version = 0; // version of metadata cache when object was added
ThreadId thd = 0; // thread that performs object scan()
std::atomic<ObjectBase::Flag> cacheFlags;
Expand Down Expand Up @@ -677,6 +683,11 @@ class CacheElement : public ElementBase, public P
return getVersioned(tdbb, TransactionNumber::current(tdbb), fl);
}

bool ensureVersioned(thread_db* tdbb, ObjectBase::Flag fl) override
{
return getVersioned(tdbb, fl);
}

bool isReady(thread_db* tdbb)
{
auto entry = getEntry(tdbb, TransactionNumber::current(tdbb), CacheFlag::NOSCAN | CacheFlag::NOCOMMIT);
Expand Down Expand Up @@ -748,7 +759,7 @@ class CacheElement : public ElementBase, public P
ListEntry<Versioned>* newEntry = nullptr;
try
{
newEntry = FB_NEW ListEntry<Versioned>(obj, traNum, fl & ~CacheFlag::ERASED);
newEntry = FB_NEW ListEntry<Versioned>(tdbb, obj, traNum, fl & ~CacheFlag::ERASED);
}
catch (const Firebird::Exception&)
{
Expand Down Expand Up @@ -776,6 +787,7 @@ class CacheElement : public ElementBase, public P
return listEntry; // nullptr
}

toUpdatedList(tdbb, fl);
return HazardPtr<ListEntry<Versioned>>(newEntry);
}

Expand All @@ -784,7 +796,9 @@ class CacheElement : public ElementBase, public P
fb_assert(list.load());
listEntry = list;
}

fl &= ~CacheFlag::AUTOCREATE;
toUpdatedList(tdbb, fl);
return ListEntry<Versioned>::getEntry(tdbb, listEntry, traNum, fl, this);
}

Expand Down Expand Up @@ -812,7 +826,7 @@ class CacheElement : public ElementBase, public P

if (!cur)
cur = TransactionNumber::current(tdbb);
ListEntry<Versioned>* newEntry = FB_NEW ListEntry<Versioned>(obj, cur, fl);
ListEntry<Versioned>* newEntry = FB_NEW ListEntry<Versioned>(tdbb, obj, cur, fl);
if (!ListEntry<Versioned>::add(tdbb, list, newEntry))
{
newEntry->cleanup(tdbb, false);
Expand Down Expand Up @@ -867,15 +881,15 @@ class CacheElement : public ElementBase, public P
return nullptr;
}

void commit(thread_db* tdbb, TraNumber cur = 0)
void commit(thread_db* tdbb, TraNumber curNumber = 0) override
{
HazardPtr<ListEntry<Versioned>> current(list);
if (current)
{
if (!cur)
cur = TransactionNumber::current(tdbb);
if (!curNumber)
curNumber = TransactionNumber::current(tdbb);

auto flags = current->commit(tdbb, cur, TransactionNumber::next(tdbb));
auto flags = current->commit(tdbb, curNumber, TransactionNumber::next(tdbb));

if (flags & CacheFlag::NOCOMMIT) // Committed newly created version in cache
pingLock(tdbb, flags, this->getId(), Versioned::objectFamily(this));
Expand Down Expand Up @@ -938,12 +952,17 @@ class CacheElement : public ElementBase, public P
return listEntry->scanInProgress();
}

static int getObjectType()
ObjectType getObjectType() override
{
return Versioned::objectType();
}

void newVersion(thread_db* tdbb)
void getObjectName(QualifiedName& name) override
{
name = this->getName();
}

void newVersion(thread_db* tdbb) override
{
TraNumber traNum;

Expand All @@ -967,41 +986,25 @@ class CacheElement : public ElementBase, public P
}
}

bool upgrade(thread_db* tdbb, const Versioned* from)
bool nameIs(const QualifiedName& name)
{
HazardPtr<ListEntry<Versioned>> l(list);

// list of versions should be present
fb_assert(l);
if (!l)
return false;

// if there is another version at the top nothing to be added
if (l->getVersioned() != from)
return ListEntry<Versioned>::upgradable(l, from);

// we have candidate for upgrade - make sure it's not half-done
fb_assert(l->getFlags() & CacheFlag::COMMITTED);
if (!(l->getFlags() & CacheFlag::COMMITTED))
return false;

// Try to upgrade
ListEntry<Versioned>* newEntry = FB_NEW ListEntry<Versioned>(nullptr, TransactionNumber::current(tdbb),
CacheFlag::COMMITTED | CacheFlag::MINISCAN | CacheFlag::DB_VERSION, l.getPointer());
if (l.replace(list, newEntry))
return true;
return this->getName() == name;
}

// undo changes
delete newEntry;
// This is needed to check correctness of statements present in current object's version
void makeRequests(thread_db* tdbb) override
{
Versioned* v = getVersioned(tdbb, CacheFlag::AUTOCREATE);
if (!v)
return;

// Someone already added entry - see is it OK for us
l.set(list);
return ListEntry<Versioned>::upgradable(l, from);
v->makeRequests(tdbb);
}

bool nameIs(const QualifiedName& name)
MdcVersion getVersion(thread_db* tdbb) override
{
return this->getName() == name;
auto entry = getEntry(tdbb, TransactionNumber::current(tdbb), CacheFlag::NOSCAN | CacheFlag::NOCOMMIT);
return entry ? entry->getVersion() : 0;
}

private:
Expand All @@ -1011,6 +1014,13 @@ class CacheElement : public ElementBase, public P
atomics::memory_order_release, atomics::memory_order_relaxed);
}

// Check flags and may be fill dependencies info
void toUpdatedList(thread_db* tdbb, ObjectBase::Flag fl)
{
if (fl & CacheFlag::DEPENDS)
ElementBase::fillDeps(tdbb, true);
}

private:
std::atomic<ListEntry<Versioned>*> list = nullptr;
std::atomic<TraNumber> resetAt = 0;
Expand Down Expand Up @@ -1211,28 +1221,6 @@ class CacheVector : public Firebird::PermanentStorage
return data;
}

bool upgrade(thread_db* tdbb, MetaId id, const Versioned* from)
{
fb_assert(id < getCount());

if (id < getCount())
{
auto ptr = getDataPointer(id);
fb_assert(ptr);

if (ptr)
{
StoredElement* data = ptr->load(atomics::memory_order_acquire);
fb_assert(data);

if (data)
return data->upgrade(tdbb, from);
}
}

return false;
}

bool lookup(thread_db* tdbb, const QualifiedName& name, ObjectBase::Flag fl,
StoredElement** element, Versioned** versioned)
{
Expand Down
2 changes: 2 additions & 0 deletions src/jrd/CharSetContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ class CharSetVers final : public ObjectBase

static ObjectType objectType() noexcept;

void makeRequests(thread_db* tdbb) { }

bool hash(thread_db*, Firebird::sha512&)
{
return true;
Expand Down
2 changes: 1 addition & 1 deletion src/jrd/Function.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ namespace Jrd
}

public:
int getObjectType() const noexcept override
ObjectType getObjectType() const noexcept override
{
return objectType();
}
Expand Down
4 changes: 3 additions & 1 deletion src/jrd/Package.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ class Package final : public Firebird::PermanentStorage, public ObjectBase
return getPermanent()->id;
}

int getObjectType() const noexcept
ObjectType getObjectType() const noexcept
{
return objectType();
}
Expand All @@ -226,6 +226,8 @@ class Package final : public Firebird::PermanentStorage, public ObjectBase

static ObjectType objectType() noexcept;

void makeRequests(thread_db* tdbb) {/*!!!!!!!!!!!!!!!*/}

bool hash(thread_db* tdbb, Firebird::sha512& digest);

Cached::Package* getPermanent() const noexcept
Expand Down
6 changes: 6 additions & 0 deletions src/jrd/Relation.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ class DbTriggers final : public Triggers, public ObjectBase

static ObjectType objectType() noexcept;

void makeRequests(thread_db* tdbb) {/*!!!!!!!!!!!!!!!*/}

private:
DbTriggersHeader* perm;

Expand Down Expand Up @@ -565,6 +567,8 @@ class IndexVersion final : public ObjectBase
static std::optional<MetaId> getIdByName(thread_db* tdbb, ExName<RelationPermanent*> name);
static ObjectType objectType() noexcept;

void makeRequests(thread_db* tdbb) {/*!!!!!!!!!!!!!!!*/}

ScanResult reload(thread_db* tdbb, ObjectBase::Flag flags)
{
return scan(tdbb, flags);
Expand Down Expand Up @@ -693,6 +697,8 @@ class jrd_rel final : public ObjectBase
static const char* objectFamily(RelationPermanent* perm);
static ObjectType objectType() noexcept;

void makeRequests(thread_db* tdbb) {/*!!!!!!!!!!!!!!!*/}

void releaseTriggers(thread_db* tdbb, bool destroy);
const Trigger* findTrigger(const QualifiedName& trig_name) const;
const Format* currentFormat(thread_db* tdbb);
Expand Down
7 changes: 7 additions & 0 deletions src/jrd/Routine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,13 @@ void Routine::parseMessages(thread_db* tdbb, CompilerScratch* csb, BlrReader blr
}
}

void Routine::makeRequests(thread_db* tdbb)
{
auto *req = statement->findRequest(tdbb);
if (req)
req->setUnused();
}

bool Routine::hash(thread_db* tdbb, Firebird::sha512& digest)
{
if (inputFields.hasData())
Expand Down
4 changes: 3 additions & 1 deletion src/jrd/Routine.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,11 @@ namespace Jrd

void sharedCheckUnlock(thread_db* tdbb);

void makeRequests(thread_db* tdbb);

public:
virtual RoutinePermanent* getPermanent() const noexcept = 0; // Permanent part of data
virtual int getObjectType() const noexcept = 0;
virtual ObjectType getObjectType() const noexcept = 0;
virtual SLONG getSclType() const noexcept = 0;

private:
Expand Down
Loading
Loading