1257 lines
29 KiB
C++
1257 lines
29 KiB
C++
/*
|
||
----
|
||
This file is part of SECONDO.
|
||
|
||
Copyright (C) 2004-2009, University in Hagen, Faculty of Mathematics
|
||
and Computer Science, Database Systems for New Applications.
|
||
|
||
SECONDO 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.
|
||
|
||
SECONDO 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 SECONDO; if not, write to the Free Software
|
||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
----
|
||
|
||
*/
|
||
|
||
#pragma once
|
||
|
||
#include "AlgebraTypes.h"
|
||
#include "Attribute.h"
|
||
#include <cstdint>
|
||
#include "NestedList.h"
|
||
#include "ReadWrite.h"
|
||
#include "SecondoSMI.h"
|
||
#include "Shared.h"
|
||
#include <string>
|
||
#include "TypeConstructor.h"
|
||
|
||
/*
|
||
Those classes are used for implementing and using types of kind ATTRARRAY which
|
||
can be used as column-types in column-oriented relations.
|
||
|
||
To implement such a type:
|
||
*your type must derive from ~AttrArray~
|
||
*your types type-constructor must derive from ~AttrArrayTypeConstructor~
|
||
|
||
*/
|
||
|
||
namespace CRelAlgebra
|
||
{
|
||
class AttrArray;
|
||
class AttrArrayEntry;
|
||
class AttrArrayIterator;
|
||
class FilteredAttrArrayIterator;
|
||
class AttrArrayTypeConstructor;
|
||
|
||
/*
|
||
This class adds support to filter a ~AttrArray~'s attributes without copying
|
||
them to a new ~AttrArray~.
|
||
|
||
It does so by providing its own row numbers which are mapped to the
|
||
~AttrArray~'s row numbers.
|
||
|
||
*/
|
||
class AttrArrayFilter
|
||
{
|
||
public:
|
||
/*
|
||
Creates a ~AttrArrayFilter~ for the passed ~array~ containing all
|
||
attributes.
|
||
|
||
Note: The ~AttrArray~'s refcounter is not touched
|
||
|
||
*/
|
||
AttrArrayFilter(const AttrArray &array) :
|
||
m_array(&array)
|
||
{
|
||
}
|
||
|
||
/*
|
||
Creates a ~AttrArrayFilter~ for the passed ~array~ containing all only the
|
||
attributes specified by the passed row numbers in ~filter~.
|
||
|
||
Note: The ~AttrArray~'s refcounter is not touched
|
||
|
||
*/
|
||
AttrArrayFilter(const AttrArray &array,
|
||
const SharedArray<const uint64_t> &filter) :
|
||
m_array(&array),
|
||
m_filter(filter)
|
||
{
|
||
}
|
||
|
||
/*
|
||
Returns the ~AttrArray~'s row number for this ~AttrArrayFilter~'s row number
|
||
~row~.
|
||
|
||
*/
|
||
uint64_t GetAt(uint64_t row) const
|
||
{
|
||
return m_filter.IsNull() ? row : m_filter[row];
|
||
}
|
||
uint64_t operator [] (uint64_t row) const
|
||
{
|
||
return m_filter.IsNull() ? row : m_filter[row];
|
||
}
|
||
|
||
/*
|
||
Returns number of row numbers contained in this ~AttrArrayFilter~.
|
||
|
||
*/
|
||
uint64_t GetCount() const;
|
||
|
||
/*
|
||
Determines if this filter contains / projects indices.
|
||
|
||
*/
|
||
bool HasFilter() const {
|
||
return !m_filter.IsNull();
|
||
}
|
||
|
||
/*
|
||
Returns a iterator over the ~AttrArray~'s attributes taking this
|
||
~AttrArrayFilter~ into account
|
||
|
||
*/
|
||
FilteredAttrArrayIterator GetIterator() const;
|
||
|
||
/*
|
||
Only for range-loop support!
|
||
|
||
*/
|
||
FilteredAttrArrayIterator begin() const;
|
||
FilteredAttrArrayIterator end() const;
|
||
|
||
protected:
|
||
const AttrArray * const m_array;
|
||
|
||
const SharedArray<const uint64_t> m_filter;
|
||
};
|
||
|
||
/*
|
||
Abstract class corresponding to kind ATTRARRAY
|
||
|
||
All attribute array implementations must derive from this class to provide a
|
||
minimum set of functionality which can be used in a generic manner.
|
||
|
||
Note: When accessing a ~AttrArray~'s attributes you probably want to use the
|
||
~AttrArrayFilter~ provided by ~GetFilter~!
|
||
|
||
*/
|
||
class AttrArray
|
||
{
|
||
public:
|
||
static AttrArrayTypeConstructor *GetTypeConstructor(ListExpr type,
|
||
bool checkKind = true);
|
||
|
||
AttrArray() :
|
||
m_filter(*this),
|
||
m_refCount(1)
|
||
{
|
||
}
|
||
|
||
/*
|
||
This constructor must be called in the ~Filter~ functions implementation.
|
||
|
||
*/
|
||
AttrArray(const SharedArray<const uint64_t> &filter) :
|
||
m_filter(*this, filter),
|
||
m_refCount(1)
|
||
{
|
||
}
|
||
|
||
virtual ~AttrArray()
|
||
{
|
||
}
|
||
|
||
/*
|
||
Creates a ~AttrArrayEntry~ representing the entry in the specified ~row~.
|
||
|
||
Precondition: ~row~ < ~GetCount()~
|
||
|
||
*/
|
||
AttrArrayEntry GetAt(uint64_t row) const;
|
||
AttrArrayEntry operator[](uint64_t row) const;
|
||
|
||
/*
|
||
Returns a new ~AttrArray~ instance holding this ~AttrArray~'s attributes
|
||
and a ~AttrArrayFilter~ containing the row numbers in ~filter~ applied to
|
||
it.
|
||
|
||
Notes:
|
||
This function is supposed to filter a ~AttrArray~ WITHOUT copying it's
|
||
attributes.
|
||
|
||
Make shure to make use of ~AttrArray(const SharedArray<const uint64_t>&)~ in
|
||
this function's implementation.
|
||
|
||
The row numbers are NOT copied to support sharing them among multiple
|
||
~AttrArray~s so you shouldn't change ~filter~ after passing it to this
|
||
function.
|
||
|
||
*/
|
||
virtual AttrArray *Filter(
|
||
const SharedArray<const uint64_t> filter) const = 0;
|
||
|
||
/*
|
||
Returns the applied ~AttrArrayFilter~.
|
||
|
||
*/
|
||
const AttrArrayFilter &GetFilter() const
|
||
{
|
||
return m_filter;
|
||
}
|
||
|
||
/*
|
||
Appends a entry located in the passed ~array~ and ~row~.
|
||
|
||
Preconitions:
|
||
*this array and ~array~ are of same type
|
||
*~row~ < ~array.GetCount()~
|
||
|
||
*/
|
||
virtual void Append(const AttrArray &array, uint64_t row) = 0;
|
||
|
||
/*
|
||
Appends a entry created from the passed ~Attribute~.
|
||
|
||
Preconition: ~value~ must be of this array's attribute type
|
||
|
||
*/
|
||
virtual void Append(Attribute &value) = 0;
|
||
|
||
/*
|
||
Appends a entry represented by the provided ~AttrArrayEntry~.
|
||
|
||
Preconition: ~value~ represents the entry of a ~AttrArray~ of this array's
|
||
type
|
||
|
||
*/
|
||
void Append(const AttrArrayEntry &value);
|
||
|
||
/*
|
||
Removes the last entry.
|
||
|
||
Precondition: ~GetCount()~ > 0
|
||
|
||
*/
|
||
virtual void Remove() = 0;
|
||
|
||
/*
|
||
Removes all entries.
|
||
|
||
*/
|
||
virtual void Clear() = 0;
|
||
|
||
/*
|
||
Returns the number of entries.
|
||
|
||
*/
|
||
virtual uint64_t GetCount() const = 0;
|
||
|
||
/*
|
||
Returns the size of this ~AttrArray~ in bytes.
|
||
|
||
*/
|
||
virtual uint64_t GetSize() const = 0;
|
||
|
||
/*
|
||
Returns true if the entry specified by ~row~ is defined, false otherwise.
|
||
|
||
Precondition: ~row~ < ~GetCount()~
|
||
|
||
*/
|
||
virtual bool IsDefined(uint64_t row) const = 0;
|
||
|
||
/*
|
||
All entry comparisons behave like ~Attribute~ comparisons.
|
||
|
||
compare(entryA, entryB) < 0 => entryA < entryB
|
||
compare(entryA, entryB) == 0 => entryA == entryB
|
||
compare(entryA, entryB) > 0 => entryA > entryB
|
||
|
||
Additionaly to an entrie's value, it's definition state must also be
|
||
considered when evaluating comparisons.
|
||
|
||
undefined == undefined
|
||
undefined < value
|
||
|
||
*/
|
||
|
||
/*
|
||
Compares this array's entry in ~rowA~ with ~arrayB~'s entry in ~rowB~.
|
||
|
||
Preconditions:
|
||
*this array and ~arrayB~ are of same type
|
||
*~rowA~ < ~GetCount()~
|
||
*~rowB~ < ~arrayB.GetCount()~
|
||
|
||
*/
|
||
virtual int Compare(uint64_t rowA, const AttrArray &arrayB,
|
||
uint64_t rowB) const = 0;
|
||
|
||
/*
|
||
Compares this array's entry in ~row~ with the passed ~Attribute~'s value.
|
||
|
||
Preconditions:
|
||
*~row~ < ~GetCount()~
|
||
*~value~ must be of this array's attribute type
|
||
|
||
*/
|
||
virtual int Compare(uint64_t row, Attribute &value) const = 0;
|
||
|
||
/*
|
||
Compares this array's entry in ~row~ the entry represented by ~value~.
|
||
|
||
Preconditions:
|
||
*~row~ < ~GetCount()~
|
||
*~value~ represents the entry of a ~AttrArray~ of this array's type
|
||
|
||
*/
|
||
int Compare(uint64_t row, const AttrArrayEntry &value) const;
|
||
|
||
/*
|
||
Compares this array's entry in ~rowA~ with ~arrayB~'s entry in ~rowB~.
|
||
For unprecise datatypes the comparison is performed unprecisely.
|
||
|
||
Preconditions:
|
||
*this array and ~arrayB~ are of same type
|
||
*~rowA~ < ~GetCount()~
|
||
*~rowB~ < ~arrayB.GetCount()~
|
||
|
||
*/
|
||
virtual int CompareAlmost(uint64_t rowA, const AttrArray &arrayB,
|
||
uint64_t rowB) const
|
||
{
|
||
return Compare(rowA, arrayB, rowB);
|
||
}
|
||
|
||
/*
|
||
Compares this array's entry in ~row~ with the passed ~Attribute~'s value.
|
||
For unprecise datatypes the comparison is performed unprecisely.
|
||
|
||
Preconditions:
|
||
*~row~ < ~GetCount()~
|
||
*~value~ must be of this array's attribute type
|
||
|
||
*/
|
||
virtual int CompareAlmost(uint64_t row, Attribute &value) const
|
||
{
|
||
return Compare(row, value);
|
||
}
|
||
|
||
/*
|
||
Compares this array's entry in ~row~ the entry represented by ~value~.
|
||
For unprecise datatypes the comparison is performed unprecisely.
|
||
|
||
Preconditions:
|
||
*~row~ < ~GetCount()~
|
||
*~value~ represents the entry of a ~AttrArray~ of this array's type
|
||
|
||
*/
|
||
int CompareAlmost(uint64_t row, const AttrArrayEntry &value) const;
|
||
|
||
/*
|
||
Checks this array's entry in ~rowA~ with ~arrayB~'s entry in ~rowB~ for
|
||
equality.
|
||
|
||
Preconditions:
|
||
*this array and ~arrayB~ are of same type
|
||
*~rowA~ < ~GetCount()~
|
||
*~rowB~ < ~arrayB.GetCount()~
|
||
|
||
*/
|
||
virtual bool Equals(uint64_t rowA, const AttrArray &arrayB,
|
||
uint64_t rowB) const
|
||
{
|
||
return Compare(rowA, arrayB, rowB) == 0;
|
||
}
|
||
|
||
/*
|
||
Checks this array's entry in ~row~ with the passed ~Attribute~'s value for
|
||
equality.
|
||
|
||
Preconditions:
|
||
*~row~ < ~GetCount()~
|
||
*~value~ must be of this array's attribute type
|
||
|
||
*/
|
||
virtual bool Equals(uint64_t row, Attribute &value) const
|
||
{
|
||
return Compare(row, value) == 0;
|
||
}
|
||
|
||
/*
|
||
Checks this array's entry in ~row~ the entry represented by ~value~ for
|
||
equality.
|
||
|
||
Preconditions:
|
||
*~row~ < ~GetCount()~
|
||
*~value~ represents the entry of a ~AttrArray~ of this array's type
|
||
|
||
*/
|
||
bool Equals(uint64_t row, const AttrArrayEntry &value) const;
|
||
|
||
/*
|
||
Checks this array's entry in ~rowA~ with ~arrayB~'s entry in ~rowB~ for
|
||
unprecise equality.
|
||
|
||
Preconditions:
|
||
*this array and ~arrayB~ are of same type
|
||
*~rowA~ < ~GetCount()~
|
||
*~rowB~ < ~arrayB.GetCount()~
|
||
|
||
*/
|
||
virtual bool EqualsAlmost(uint64_t rowA, const AttrArray &arrayB,
|
||
uint64_t rowB) const
|
||
{
|
||
return CompareAlmost(rowA, arrayB, rowB) == 0;
|
||
}
|
||
|
||
/*
|
||
Checks this array's entry in ~row~ with the passed ~Attribute~'s value for
|
||
unprecise equality.
|
||
|
||
Preconditions:
|
||
*~row~ < ~GetCount()~
|
||
*~value~ must be of this array's attribute type
|
||
|
||
*/
|
||
virtual bool EqualsAlmost(uint64_t row, Attribute &value) const
|
||
{
|
||
return CompareAlmost(row, value) == 0;
|
||
}
|
||
|
||
/*
|
||
Checks this array's entry in ~row~ the entry represented by ~value~ for
|
||
unprecise equality.
|
||
|
||
Preconditions:
|
||
*~row~ < ~GetCount()~
|
||
*~value~ represents the entry of a ~AttrArray~ of this array's type
|
||
|
||
*/
|
||
bool EqualsAlmost(uint64_t row, const AttrArrayEntry &value) const;
|
||
|
||
/*
|
||
Returns a hash value for the entry specified by ~row~
|
||
|
||
Precondition: ~row~ < ~GetCount()~
|
||
|
||
*/
|
||
virtual uint64_t GetHash(uint64_t row) const = 0;
|
||
|
||
/*
|
||
Returns a ~Attribute~ representation of the entry in the specified ~row~.
|
||
|
||
The returned value may be only valid during this array's lifetime.
|
||
Passing ~clone~ == true returns a independent ~Attribute~.
|
||
|
||
The returned object must be released calling ~DeleteIfAllowed()~!
|
||
|
||
Precondition: ~row~ < ~GetCount()~
|
||
|
||
*/
|
||
virtual Attribute *GetAttribute(uint64_t row, bool clone = false) const = 0;
|
||
|
||
/*
|
||
Writes this array's data into the passed target.
|
||
~includeHeader~ determines if ~AttrArrayHeader~ data should be omitted.
|
||
|
||
*/
|
||
virtual void Save(Writer &target, bool includeHeader = true) const = 0;
|
||
|
||
/*
|
||
Deletes persistent data created by this array.
|
||
|
||
*/
|
||
virtual void DeleteRecords()
|
||
{
|
||
}
|
||
|
||
/*
|
||
Returns a ~AttrArrayIterator~ over the entries.
|
||
|
||
*/
|
||
AttrArrayIterator GetIterator() const;
|
||
|
||
FilteredAttrArrayIterator GetFilteredIterator() const;
|
||
|
||
/*
|
||
~AttrArrayIterator~s used (only!) for range-loop support.
|
||
|
||
*/
|
||
AttrArrayIterator begin() const;
|
||
AttrArrayIterator end() const;
|
||
|
||
/*
|
||
Increases the reference counter by one.
|
||
|
||
*/
|
||
void IncRef() const
|
||
{
|
||
++m_refCount;
|
||
}
|
||
|
||
/*
|
||
Decreases the reference counter by one.
|
||
If the reference counter reaches zero this object is deleted.
|
||
|
||
*/
|
||
void DecRef() const
|
||
{
|
||
if (--m_refCount == 0)
|
||
{
|
||
delete this;
|
||
}
|
||
}
|
||
|
||
/*
|
||
Returns the reference count.
|
||
|
||
*/
|
||
uint64_t GetRefCount() const
|
||
{
|
||
return m_refCount;
|
||
}
|
||
|
||
private:
|
||
const AttrArrayFilter m_filter;
|
||
|
||
mutable uint64_t m_refCount;
|
||
};
|
||
|
||
inline uint64_t AttrArrayFilter::GetCount() const
|
||
{
|
||
return m_filter.IsNull() ? m_array->GetCount() : m_filter.GetCapacity();
|
||
}
|
||
|
||
/*
|
||
This class represents the entry of a ~AttrArray~ by a pointer to the array and
|
||
a row number.
|
||
|
||
If either the pointer doesn't point to a ~AttrArray~ instance or the row
|
||
number is out of the array's range of rows, the ~AttrArrayEntry~ is considered
|
||
invalid.
|
||
|
||
This class doesn't change a ~AttrArray~'s reference count.
|
||
If the pointed to array is deleted this ~AttrArrayEntry~ becomes invalid.
|
||
|
||
Using a invalid ~AttrArrayEntry~ is considered undefined behaviour.
|
||
|
||
This class only wraps ~AttrArray~ functions.
|
||
The functions are defined in this header file to enable inlining.
|
||
|
||
*/
|
||
class AttrArrayEntry
|
||
{
|
||
public:
|
||
/*
|
||
Creates a invalid ~AttrArrayEntry~.
|
||
|
||
*/
|
||
AttrArrayEntry()
|
||
{
|
||
}
|
||
|
||
/*
|
||
Creates a ~AttrArrayEntry~ representing the entry in the passed ~array~ and
|
||
~row~.
|
||
|
||
~array->GetCount()~ < ~row~ <=> the returned entry is valid
|
||
|
||
*/
|
||
AttrArrayEntry(const AttrArray *array, uint64_t row) :
|
||
m_array(array),
|
||
m_row(row)
|
||
{
|
||
}
|
||
|
||
/*
|
||
Returns the ~AttrArray~ pointer
|
||
|
||
*/
|
||
const AttrArray *GetArray() const
|
||
{
|
||
return m_array;
|
||
}
|
||
|
||
/*
|
||
Returns the row number
|
||
|
||
*/
|
||
uint64_t GetRow() const
|
||
{
|
||
return m_row;
|
||
}
|
||
|
||
bool IsDefined() const
|
||
{
|
||
return m_array->IsDefined(m_row);
|
||
}
|
||
|
||
int Compare(const AttrArray &array, uint64_t row) const
|
||
{
|
||
return m_array->Compare(m_row, array, row);
|
||
}
|
||
|
||
int Compare(const AttrArrayEntry &value) const
|
||
{
|
||
return m_array->Compare(m_row, *value.m_array, value.m_row);
|
||
}
|
||
|
||
int Compare(uint64_t row, Attribute &value) const
|
||
{
|
||
return m_array->Compare(m_row, value);
|
||
}
|
||
|
||
bool operator < (const AttrArrayEntry& value) const
|
||
{
|
||
return m_array->Compare(m_row, *value.m_array, value.m_row) < 0;
|
||
}
|
||
|
||
bool operator < (Attribute& value) const
|
||
{
|
||
return m_array->Compare(m_row, value) < 0;
|
||
}
|
||
|
||
bool operator <= (const AttrArrayEntry& value) const
|
||
{
|
||
return m_array->Compare(m_row, *value.m_array, value.m_row) <= 0;
|
||
}
|
||
|
||
bool operator <= (Attribute& value) const
|
||
{
|
||
return m_array->Compare(m_row, value) <= 0;
|
||
}
|
||
|
||
bool operator > (const AttrArrayEntry& value) const
|
||
{
|
||
return m_array->Compare(m_row, *value.m_array, value.m_row) > 0;
|
||
}
|
||
|
||
bool operator > (Attribute& value) const
|
||
{
|
||
return m_array->Compare(m_row, value) > 0;
|
||
}
|
||
|
||
bool operator >= (const AttrArrayEntry& value) const
|
||
{
|
||
return m_array->Compare(m_row, *value.m_array, value.m_row) >= 0;
|
||
}
|
||
|
||
bool operator >= (Attribute& value) const
|
||
{
|
||
return m_array->Compare(m_row, value) >= 0;
|
||
}
|
||
|
||
bool Equals(const AttrArray &array, uint64_t row) const
|
||
{
|
||
return m_array->Equals(m_row, array, row);
|
||
}
|
||
|
||
bool Equals(const AttrArrayEntry &value) const
|
||
{
|
||
return m_array->Equals(m_row, *value.m_array, value.m_row);
|
||
}
|
||
|
||
bool Equals(Attribute &value) const
|
||
{
|
||
return m_array->Equals(m_row, value);
|
||
}
|
||
|
||
bool operator == (const AttrArrayEntry& value) const
|
||
{
|
||
return m_array->Equals(m_row, *value.m_array, value.m_row);
|
||
}
|
||
|
||
bool operator == (Attribute& value) const
|
||
{
|
||
return m_array->Equals(m_row, value);
|
||
}
|
||
|
||
bool operator != (const AttrArrayEntry& value) const
|
||
{
|
||
return !m_array->Equals(m_row, *value.m_array, value.m_row);
|
||
}
|
||
|
||
bool operator != (Attribute& value) const
|
||
{
|
||
return !m_array->Equals(m_row, value);
|
||
}
|
||
|
||
uint64_t GetHash() const
|
||
{
|
||
return m_array->GetHash(m_row);
|
||
}
|
||
|
||
Attribute *GetAttribute(bool clone = false) const
|
||
{
|
||
return m_array->GetAttribute(m_row, clone);
|
||
}
|
||
|
||
protected:
|
||
const AttrArray *m_array;
|
||
|
||
uint64_t m_row;
|
||
|
||
friend class AttrArray;
|
||
friend class AttrArrayIterator;
|
||
friend class FilteredAttrArrayIterator;
|
||
};
|
||
|
||
/*
|
||
Those ~AttrArray~ functions should be inlined if possible.
|
||
Yet they depend on ~AttrArrayEntry~ so they are defined here.
|
||
|
||
*/
|
||
|
||
inline AttrArrayEntry AttrArray::GetAt(uint64_t row) const
|
||
{
|
||
return AttrArrayEntry(this, row);
|
||
}
|
||
|
||
inline AttrArrayEntry AttrArray::operator[](uint64_t row) const
|
||
{
|
||
return AttrArrayEntry(this, row);
|
||
}
|
||
|
||
inline void AttrArray::Append(const AttrArrayEntry &value)
|
||
{
|
||
Append(*value.m_array, value.m_row);
|
||
}
|
||
|
||
inline int AttrArray::Compare(uint64_t row, const AttrArrayEntry &value) const
|
||
{
|
||
return Compare(row, *value.m_array, value.m_row);
|
||
}
|
||
|
||
inline int AttrArray::CompareAlmost(uint64_t row,
|
||
const AttrArrayEntry &value) const
|
||
{
|
||
return CompareAlmost(row, *value.m_array, value.m_row);
|
||
}
|
||
|
||
inline bool AttrArray::Equals(uint64_t row, const AttrArrayEntry &value) const
|
||
{
|
||
return Equals(row, *value.m_array, value.m_row);
|
||
}
|
||
|
||
inline bool AttrArray::EqualsAlmost(uint64_t row,
|
||
const AttrArrayEntry &value) const
|
||
{
|
||
return EqualsAlmost(row, *value.m_array, value.m_row);
|
||
}
|
||
|
||
/*
|
||
A very simple implementation of iterator over a ~AttrArray~’s entries.
|
||
|
||
Changes of the ~AttrArray~ invalidate the iterator which is not reflected by
|
||
~AttrArrayIterator.IsValid~. Further usage is considered undefined behaviour.
|
||
|
||
The functions are defined in this header file to enable inlining.
|
||
|
||
*/
|
||
class AttrArrayIterator
|
||
{
|
||
public:
|
||
/*
|
||
Creates a invalid iterator.
|
||
|
||
*/
|
||
AttrArrayIterator() :
|
||
m_count(0),
|
||
m_entry(nullptr, 0)
|
||
{
|
||
}
|
||
|
||
/*
|
||
Creates a iterator pointing at the first entry in the passed ~array~.
|
||
If the ~array~ is empty the iterator is invalid.
|
||
|
||
*/
|
||
AttrArrayIterator(const AttrArray *array) :
|
||
m_array(array),
|
||
m_count(array != nullptr ? array->GetCount() : 0),
|
||
m_entry(array, 0)
|
||
{
|
||
}
|
||
|
||
/*
|
||
Determines if the iterator's current position is valid.
|
||
|
||
*/
|
||
bool IsValid() const
|
||
{
|
||
return m_entry.m_row < m_count;
|
||
}
|
||
|
||
/*
|
||
Moves the iterator to the next position.
|
||
~MoveToNext~ returns true if that position is still valid.
|
||
|
||
Precondition: ~IsValid()~
|
||
|
||
*/
|
||
bool MoveToNext()
|
||
{
|
||
if (m_entry.m_row < m_count)
|
||
{
|
||
return ++m_entry.m_row < m_count;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
AttrArrayIterator &operator ++ ()
|
||
{
|
||
MoveToNext();
|
||
|
||
return *this;
|
||
}
|
||
|
||
/*
|
||
Returns a ~AttrArrayEntry~ representing the entry at the iterator's current
|
||
position.
|
||
|
||
Precondition: ~IsValid()~
|
||
|
||
*/
|
||
AttrArrayEntry &Get()
|
||
{
|
||
return m_entry;
|
||
}
|
||
|
||
AttrArrayEntry &operator * ()
|
||
{
|
||
return Get();
|
||
}
|
||
|
||
/*
|
||
Compares this iterator and the ~other~ iterator for equality.
|
||
|
||
*/
|
||
bool operator == (const AttrArrayIterator &other) const
|
||
{
|
||
return !(*this != other);
|
||
}
|
||
|
||
/*
|
||
Compares this iterator and the ~other~ iterator for inequality.
|
||
|
||
*/
|
||
bool operator != (const AttrArrayIterator &other) const
|
||
{
|
||
if (IsValid())
|
||
{
|
||
if (other.IsValid())
|
||
{
|
||
return m_entry.m_row != other.m_entry.m_row ||
|
||
m_array != other.m_array;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
return other.IsValid();
|
||
}
|
||
|
||
private:
|
||
const AttrArray *m_array;
|
||
|
||
uint64_t m_count;
|
||
|
||
AttrArrayEntry m_entry;
|
||
};
|
||
|
||
/*
|
||
Those ~AttrArray~ functions should be inlined if possible.
|
||
Yet they depend on ~AttrArrayIterator~ so they are defined here.
|
||
|
||
*/
|
||
|
||
inline AttrArrayIterator AttrArray::GetIterator() const
|
||
{
|
||
return AttrArrayIterator(this);
|
||
}
|
||
|
||
inline AttrArrayIterator AttrArray::begin() const
|
||
{
|
||
return GetIterator();
|
||
}
|
||
|
||
inline AttrArrayIterator AttrArray::end() const
|
||
{
|
||
return AttrArrayIterator();
|
||
}
|
||
|
||
class FilteredAttrArrayIterator
|
||
{
|
||
public:
|
||
/*
|
||
Creates a invalid iterator.
|
||
|
||
*/
|
||
FilteredAttrArrayIterator() :
|
||
m_count(0),
|
||
m_row(0),
|
||
m_entry(nullptr, 0)
|
||
{
|
||
}
|
||
|
||
/*
|
||
Creates a iterator pointing at the first entry in the passed ~array~.
|
||
If the ~array~ is empty the iterator is invalid.
|
||
|
||
*/
|
||
FilteredAttrArrayIterator(const AttrArray *array) :
|
||
m_filter(array != nullptr ? &array->GetFilter() : nullptr),
|
||
m_count(m_filter != nullptr ? m_filter->GetCount() : 0),
|
||
m_row(0),
|
||
m_entry(array, m_count > 0 ? m_filter->GetAt(0) : 0)
|
||
{
|
||
}
|
||
|
||
/*
|
||
Determines if the iterator's current position is valid.
|
||
|
||
*/
|
||
bool IsValid() const
|
||
{
|
||
return m_row < m_count;
|
||
}
|
||
|
||
/*
|
||
Moves the iterator to the next position.
|
||
~MoveToNext~ returns true if that position is still valid.
|
||
|
||
Precondition: ~IsValid()~
|
||
|
||
*/
|
||
bool MoveToNext()
|
||
{
|
||
if (m_row < m_count)
|
||
{
|
||
if (++m_row < m_count)
|
||
{
|
||
m_entry.m_row = m_filter->GetAt(m_row);
|
||
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
FilteredAttrArrayIterator &operator ++ ()
|
||
{
|
||
MoveToNext();
|
||
|
||
return *this;
|
||
}
|
||
|
||
/*
|
||
Returns a ~AttrArrayEntry~ representing the entry at the iterator's current
|
||
position.
|
||
|
||
Precondition: ~IsValid()~
|
||
|
||
*/
|
||
AttrArrayEntry &Get()
|
||
{
|
||
return m_entry;
|
||
}
|
||
|
||
AttrArrayEntry &operator * ()
|
||
{
|
||
return Get();
|
||
}
|
||
|
||
/*
|
||
Compares this iterator and the ~other~ iterator for equality.
|
||
|
||
*/
|
||
bool operator == (const FilteredAttrArrayIterator &other) const
|
||
{
|
||
return !(*this != other);
|
||
}
|
||
|
||
/*
|
||
Compares this iterator and the ~other~ iterator for inequality.
|
||
|
||
*/
|
||
bool operator != (const FilteredAttrArrayIterator &other) const
|
||
{
|
||
if (IsValid())
|
||
{
|
||
if (other.IsValid())
|
||
{
|
||
return m_row != other.m_row || m_filter != other.m_filter;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
return other.IsValid();
|
||
}
|
||
|
||
private:
|
||
const AttrArrayFilter *m_filter;
|
||
|
||
uint64_t m_count,
|
||
m_row;
|
||
|
||
AttrArrayEntry m_entry;
|
||
};
|
||
|
||
inline FilteredAttrArrayIterator AttrArrayFilter::GetIterator() const
|
||
{
|
||
return FilteredAttrArrayIterator(m_array);
|
||
}
|
||
|
||
inline FilteredAttrArrayIterator AttrArrayFilter::begin() const
|
||
{
|
||
return FilteredAttrArrayIterator(m_array);
|
||
}
|
||
|
||
inline FilteredAttrArrayIterator AttrArrayFilter::end() const
|
||
{
|
||
return FilteredAttrArrayIterator();
|
||
}
|
||
|
||
inline FilteredAttrArrayIterator AttrArray::GetFilteredIterator() const
|
||
{
|
||
return FilteredAttrArrayIterator(this);
|
||
}
|
||
|
||
/*
|
||
Class used to persist some members of a attribute array seperately to avoid
|
||
data redundancy in ~TBlock~s and ~CRel~s.
|
||
|
||
*/
|
||
class AttrArrayHeader
|
||
{
|
||
public:
|
||
//number of rows in a ~AttrArray~.
|
||
uint64_t count;
|
||
|
||
//id of the file a ~AttrArray~ should use for ~Flob~ storage.
|
||
SmiFileId flobFileId;
|
||
|
||
AttrArrayHeader()
|
||
{
|
||
}
|
||
|
||
AttrArrayHeader(uint64_t count, SmiFileId flobFileId) :
|
||
count(count),
|
||
flobFileId(flobFileId)
|
||
{
|
||
}
|
||
};
|
||
|
||
/*
|
||
~AttrArrayManager~ allows to create and load instances of ~AttrArray~s without
|
||
knowledge of the implementing class.
|
||
|
||
Instances of ~AttrArrayManager~ can be obtained from a
|
||
~AttrArrayTypeConstructor~.
|
||
|
||
*/
|
||
class AttrArrayManager
|
||
{
|
||
public:
|
||
AttrArrayManager();
|
||
|
||
virtual ~AttrArrayManager();
|
||
|
||
/*
|
||
Creates a new instance of ~AttrArray~, providing a file id for ~Flob~
|
||
storage.
|
||
|
||
~flobFileId~ == 0 => no ~Flob~ storage
|
||
|
||
The returned object must be released using ~DecRef~.
|
||
|
||
*/
|
||
virtual AttrArray *Create(SmiFileId flobFileId) = 0;
|
||
|
||
/*
|
||
Loads a new instance of ~AttrArray~ from the provided ~source~.
|
||
|
||
Preconditions:
|
||
*~source~ holds data created by calling a ~AttrArray~'s ~Save~ function
|
||
with ~includeHeader~ == true
|
||
*the ~AttrArray~ was created by this ~AttrArrayManager~ implementation
|
||
|
||
The returned object must be released using ~DecRef~.
|
||
|
||
*/
|
||
virtual AttrArray *Load(Reader &source) = 0;
|
||
|
||
/*
|
||
Loads a new instance of ~AttrArray~ from the provided ~source~ passing
|
||
~AttrArrayHeader~ data seperately.
|
||
|
||
Preconditions:
|
||
*~source~ holds data created by calling a ~AttrArray~'s ~Save~ function
|
||
with ~includeHeader~ == false
|
||
*the ~AttrArray~ was created by this ~AttrArrayManager~ implementation
|
||
|
||
The returned object must be released using ~DecRef~.
|
||
|
||
*/
|
||
virtual AttrArray *Load(Reader &source, const AttrArrayHeader &header) = 0;
|
||
|
||
/*
|
||
Increases the reference counter by one.
|
||
|
||
*/
|
||
void IncRef() const;
|
||
|
||
/*
|
||
Decreases the reference counter by one.
|
||
If the reference counter reaches zero this object is deleted.
|
||
|
||
*/
|
||
void DecRef() const;
|
||
|
||
|
||
/*
|
||
Returns the reference count.
|
||
|
||
*/
|
||
uint64_t GetRefCount() const;
|
||
|
||
private:
|
||
mutable uint64_t m_refCount;
|
||
};
|
||
|
||
/*
|
||
This function is supposed to return the attribute type for a attribute-array
|
||
type ~typeExpr~.
|
||
|
||
If ~numeric~ the provided and returned types must be in their numeric
|
||
representation (see ~SecondoCatalog~).
|
||
|
||
*/
|
||
typedef ListExpr (*AttrArrayTypeFunction)(ListExpr typeExpr, bool numeric);
|
||
|
||
/*
|
||
This function is supposed to return instance of ~AttrArrayManager~ for the
|
||
provided attribute type.
|
||
|
||
Normally ~attributeType~ was previously determined by a
|
||
~AttrArrayTypeFunction~.
|
||
|
||
*/
|
||
typedef AttrArrayManager *(*AttrArrayManagerFunction)(ListExpr attributeType);
|
||
|
||
/*
|
||
~TypeConstructor~ for ATTRARRAY types.
|
||
Every ~TypeConstructor~ for a ATTRARRAY type must derive from
|
||
~AttrArrayTypeConstructor~ to provide functions used by ~TBlock~ and ~CRel~.
|
||
|
||
*/
|
||
class AttrArrayTypeConstructor : public TypeConstructor
|
||
{
|
||
public:
|
||
/*
|
||
This function returns a default ATTRARRAY type with the provided attribute
|
||
type.
|
||
|
||
If ~numeric~ the provided and returned types must be in their numeric
|
||
representation (see ~SecondoCatalog~).
|
||
|
||
*/
|
||
static ListExpr GetDefaultAttrArrayType(ListExpr attributeType,
|
||
bool numeric);
|
||
|
||
/*
|
||
Creates a ~AttrArrayTypeConstructor~ with the provided ~name~ and functions
|
||
and accociates it with ATTRARRAY.
|
||
|
||
*/
|
||
AttrArrayTypeConstructor(const std::string& name, TypeProperty typeProperty,
|
||
TypeCheckFunction typeCheck,
|
||
AttrArrayTypeFunction attributeType,
|
||
AttrArrayManagerFunction manager);
|
||
|
||
/*
|
||
Creates a ~AttrArrayTypeConstructor~ with the provided ~name~ and functions
|
||
and accociates it with ATTRARRAY.
|
||
|
||
*/
|
||
AttrArrayTypeConstructor(const std::string& name, TypeProperty typeProperty,
|
||
OutObject out, InObject in, ObjectCreation create,
|
||
ObjectDeletion del, ObjectOpen open,
|
||
ObjectSave save, ObjectClose close,
|
||
ObjectClone clone, ObjectCast cast,
|
||
ObjectSizeof sizeOf, TypeCheckFunction typeCheck,
|
||
AttrArrayTypeFunction attributeType,
|
||
AttrArrayManagerFunction manager);
|
||
|
||
/*
|
||
Returns the attribute type for this ~TypeConstructor~'s ATTRARRAY type
|
||
~typeExpr~.
|
||
|
||
If ~numeric~ the provided and returned types must be in their numeric
|
||
representation (see ~SecondoCatalog~).
|
||
|
||
*/
|
||
ListExpr GetAttributeType(ListExpr typeExpr, bool numeric);
|
||
|
||
/*
|
||
Returns a instance of ~AttrArrayManager~ for this ~TypeConstructor~'s
|
||
ATTRARRAY type with the provided attribute type.
|
||
|
||
The returned object must be released using ~DecRef~.
|
||
|
||
*/
|
||
AttrArrayManager *CreateManager(ListExpr attributeType);
|
||
|
||
protected:
|
||
/*
|
||
Default implementations of some ~TypeConstructor~ functions for
|
||
ATTRARRAY types.
|
||
|
||
*/
|
||
|
||
static Word DefaultIn(ListExpr typeExpr, ListExpr value, int errorPos,
|
||
ListExpr &errorInfo, bool &correct);
|
||
|
||
static ListExpr DefaultOut(ListExpr typeExpr, Word value);
|
||
|
||
static Word DefaultCreate(const ListExpr typeExpr);
|
||
|
||
static void DefaultDelete(const ListExpr typeExpr, Word &value);
|
||
|
||
static bool DefaultOpen(SmiRecord &valueRecord, size_t &offset,
|
||
const ListExpr typeExpr, Word &value);
|
||
|
||
static bool DefaultSave(SmiRecord &valueRecord, size_t &offset,
|
||
const ListExpr typeExpr, Word &value);
|
||
|
||
static void DefaultClose(const ListExpr typeExpr, Word &value);
|
||
|
||
static void *DefaultCast(void *addr);
|
||
|
||
static int DefaultSizeOf();
|
||
|
||
static Word DefaultClone(const ListExpr typeExpr, const Word &value);
|
||
|
||
private:
|
||
AttrArrayTypeFunction m_getAttributeType;
|
||
|
||
AttrArrayManagerFunction m_createManager;
|
||
};
|
||
}
|