Files
secondo/Algebras/XTree/XTreeBase.h
2026-01-23 17:03:45 +08:00

650 lines
14 KiB
C++

/*
\newpage
----
This file is part of SECONDO.
Copyright (C) 2004, University in Hagen, Department of 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
----
//[_] [\_]
//characters [1] verbatim: [$] [$]
//characters [2] formula: [$] [$]
//characters [3] capital: [\textsc{] [}]
//characters [4] teletype: [\texttt{] [}]
1 Headerfile "XTreeBase.h"[4]
January-May 2008, Mirko Dibbert
1.1 Overview
This file contains the declarations of the xtree nodes and node entries.
1.1 includes and defines
*/
#ifndef __XTREE_BASE_H__
#define __XTREE_BASE_H__
#include "Algebras/Relation-C++/RelationAlgebra.h"
#include "XTreeAlgebra.h"
namespace xtreeAlgebra {
using gtree::NodePtr;
/********************************************************************
1.1 Class "SplitHist"[4]
This class implements the split history for internal entries, which is stored in one bit per dimension.
********************************************************************/
class SplitHist
{
public:
/*
Contstructor (creates an empty split history)
*/
inline SplitHist(unsigned dim)
: m_len((dim/8)+1), m_hist(new char[m_len])
{ memset(m_hist, 0, m_len); }
/*
Default copy constructor.
*/
inline SplitHist(const SplitHist &e)
: m_len(e.m_len), m_hist(new char[m_len])
{ memcpy(m_hist, e.m_hist, m_len); }
/*
Constructor (reads the histoory from buffer and increases offset)
*/
inline SplitHist(const char *const buffer, int &offset)
{ read(buffer, offset); }
/*
Destructor.
*/
inline ~SplitHist()
{ delete[] m_hist; }
/*
Sets bit n in the Split history.
*/
inline void set(unsigned n)
{
#ifdef __XTREE_DEBUG
assert(n < 8*m_len);
#endif
unsigned i = n/8;
m_hist[i] |= (1 << (n - 8*i));
}
/*
Logical OR operator.
*/
inline void operator |= (const SplitHist &rhs)
{
for (unsigned i=0; i<m_len; ++i)
m_hist[i] |= rhs.m_hist[i];
}
/*
Logical AND operator.
*/
inline void operator &= (const SplitHist &rhs)
{
for (unsigned i=0; i<m_len; ++i)
m_hist[i] &= rhs.m_hist[i];
}
/*
Access operator (returns "true"[4] if bit n is set)
*/
inline bool operator [] (unsigned n)
{
#ifdef __XTREE_DEBUG
assert(n < 8*m_len);
#endif
int i = static_cast<int>(n/8);
return (m_hist[i] & (1 << (n - 8*i)));
}
/*
Writes the history to buffer and increases offset.
*/
inline void write(char *const buffer, int &offset) const
{
memcpy(buffer+offset, &m_len, sizeof(unsigned));
offset += sizeof(unsigned);
memcpy(buffer+offset, m_hist, m_len);
offset += m_len;
}
/*
Returns the size of the history in bytes.
*/
inline size_t size()
{ return sizeof(unsigned) + m_len*sizeof(char); }
private:
/*
Reads the history from buffer and increases offset.
*/
inline void read(const char* const buffer, int &offset)
{
memcpy(&m_len, buffer+offset, sizeof(unsigned));
offset += sizeof(unsigned);
m_hist = new char[m_len];
memcpy(m_hist, buffer+offset, m_len);
offset += m_len;
}
unsigned m_len;
char *m_hist;
};
/********************************************************************
1.1 Class ~LeafEntry~
********************************************************************/
class LeafEntry
: public gtree::LeafEntry
{
public:
/*
Default constructor.
*/
inline LeafEntry()
{}
/*
Constructor (creates a new leaf entry with given values).
*/
inline LeafEntry(TupleId tid, gta::HPoint *p)
: m_tid(tid), m_isPoint(true), m_bbox(p->bbox()), m_point(p)
{
#ifdef __XTREE_DEBUG
assert(p);
#endif
}
/*
Constructor (creates a new leaf entry with given values).
*/
inline LeafEntry(TupleId tid, gta::HRect *bbox)
: m_tid(tid), m_isPoint(false), m_bbox(bbox), m_point(0)
{
#ifdef __XTREE_DEBUG
assert(m_bbox);
#endif
}
/*
Default copy constructor.
*/
inline LeafEntry(const LeafEntry &e)
: m_tid(e.m_tid), m_isPoint(e.m_isPoint),
m_bbox(e.m_bbox), m_point(e.m_point)
{}
/*
Destructor.
*/
inline ~LeafEntry()
{
delete m_bbox;
if (m_point)
delete m_point;
}
/*
Returns the tuple id of the entry.
*/
inline TupleId tid() const
{ return m_tid; }
/*
Returns a reference to the "HRect"[4] object.
*/
inline gta::HRect *bbox()
{ return m_bbox; }
/*
Writes the entry to buffer and increases offset (defined inline, since this method is called only once from Node::write).
*/
inline void write(char *const buffer, int &offset) const
{
gtree::LeafEntry::write(buffer, offset);
// write tuple-id
memcpy(buffer+offset, &m_tid, sizeof(TupleId));
offset += sizeof(TupleId);
// read m_isPoint
memcpy(buffer+offset, &m_isPoint, sizeof(bool));
offset += sizeof(bool);
if (m_isPoint)
m_point->write(buffer, offset);
else
m_bbox->write(buffer, offset);
}
/*
Reads the entry from buffer and increases offset (defined inline, since this method is called only once from Node::read).
*/
inline void read(const char *const buffer, int &offset)
{
gtree::LeafEntry::read(buffer, offset);
// read tuple-id
memcpy(&m_tid, buffer+offset, sizeof(TupleId));
offset += sizeof(TupleId);
// read m_isPoint
memcpy(&m_isPoint, buffer+offset, sizeof(bool));
offset += sizeof(bool);
if (m_isPoint)
{
m_point = new gta::HPoint(buffer, offset);
m_bbox = m_point->bbox();
}
else
{
m_point = 0;
m_bbox = new gta::HRect(buffer, offset);
}
}
/*
Returns the size of the entry on disc.
*/
inline size_t size()
{
if (m_isPoint)
{
return gtree::LeafEntry::size() +
sizeof(TupleId) + sizeof(bool) + m_point->size();
}
else
{
return gtree::LeafEntry::size() + sizeof(bool) +
sizeof(TupleId) + sizeof(bool) + m_bbox->size();
}
}
/*
Returns the square of the Euclidean distance between "p"[4] and the entry data (if the data is no point, the distance to the center of the bounding box is returned).
*/
double dist(gta::HPoint *p)
{
if (m_isPoint)
return gta::SpatialDistfuns::euclDist2(p, m_point);
else
{
gta::HPoint c = m_bbox->center();
return gta::SpatialDistfuns::euclDist2(p, &c);
}
}
private:
TupleId m_tid; // tuple-id of the entry
bool m_isPoint; // true, if data is point data
gta::HRect *m_bbox; // bounding box of the entry
gta::HPoint *m_point; // used for point data
}; // class LeafEntry
/********************************************************************
1.1 Class ~InternalEntry~
********************************************************************/
class InternalEntry
: public gtree::InternalEntry
{
public:
/*
Default constructor.
*/
inline InternalEntry()
{}
/*
Constructor.
*/
inline InternalEntry(gta::HRect *bbox, SmiRecordId _chield)
: gtree::InternalEntry(_chield), m_bbox(bbox),
m_history(new SplitHist(m_bbox->dim()))
{}
/*
Constructor.
*/
inline InternalEntry(
gta::HRect *bbox, SmiRecordId _chield, SplitHist *_hist)
: gtree::InternalEntry(_chield), m_bbox(bbox),
m_history(new SplitHist(*_hist))
{}
/*
Default copy constructor.
*/
inline InternalEntry(const InternalEntry &e)
: gtree::InternalEntry(e), m_bbox(new gta::HRect(*e.m_bbox)),
m_history(e.history())
{}
/*
Destructor.
*/
inline ~InternalEntry()
{
delete m_bbox;
delete m_history;
}
/*
Returns a reference to the "HRect"[4] object.
*/
inline gta::HRect *bbox()
{ return m_bbox; }
/*
Replaces the bounding box with new one (used during split).
*/
inline void replaceHRect(gta::HRect* _bbox)
{
delete m_bbox;
m_bbox = _bbox;
#ifdef __XTREE_DEBUG
assert(m_bbox);
#endif
}
/*
Returns the split history.
*/
inline SplitHist *history() const
{ return m_history; }
/*
Writes the entry to buffer and increases offset (defined inline, since this method is called only once from Node::write).
*/
inline void write(char *const buffer, int &offset) const
{
gtree::InternalEntry::write(buffer, offset);
m_bbox->write(buffer, offset);
m_history->write(buffer, offset);
}
/*
Reads the entry from buffer and increases offset (defined inline, since this method is called only once from Node::read).
*/
inline void read(const char *const buffer, int &offset)
{
gtree::InternalEntry::read(buffer, offset);
m_bbox = new gta::HRect(buffer, offset);
m_history = new SplitHist(buffer, offset);
}
/*
Returns the size of the entry on disc.
*/
inline size_t size()
{
return gtree::InternalEntry::size() +
m_bbox->size() + m_history->size();
}
private:
gta::HRect *m_bbox; // bounding box of the entry
SplitHist *m_history; // split history
}; // class DirEntry
/********************************************************************
1.1 Class ~LeafNode~
********************************************************************/
class LeafNode
: public gtree::LeafNode<LeafEntry>
{
public:
/*
Default constructor.
*/
inline LeafNode(gtree::NodeConfigPtr config)
: gtree::LeafNode<LeafEntry>(config, 0)
{}
/*
Default copy constructor.
*/
inline LeafNode(const LeafNode& node)
: gtree::LeafNode<LeafEntry>(node)
{}
/*
Virtual destructor.
*/
inline virtual ~LeafNode()
{}
/*
Returns a reference to a copy of the node.
*/
virtual LeafNode *clone() const
{ return new LeafNode(*this); }
/*
Returns the union of all contained bounding boxes.
*/
inline gta::HRect *bbox()
{
iterator iter = begin();
gta::HRect *new_bbox = new gta::HRect(*(*iter)->bbox());
while(++iter != end())
new_bbox->unite((*iter)->bbox());
return new_bbox;
}
/*
Returns the union of the given entry vector.
*/
static gta::HRect *bbox(std::vector<LeafEntry*> *entries)
{
iterator iter = entries->begin();
gta::HRect *new_bbox = new gta::HRect(*(*iter)->bbox());
while(++iter != entries->end())
new_bbox->unite((*iter)->bbox());
return new_bbox;
}
}; // class "LeafNode"[4]
/********************************************************************
1.1 Class ~InternalNode~
********************************************************************/
class InternalNode
: public gtree::InternalNode<InternalEntry>
{
public:
/*
Default constructor.
*/
inline InternalNode(
gtree::NodeConfigPtr config,
gtree::NodeConfigPtr defaultConfig,
gtree::NodeConfigPtr supernodeConfig)
: gtree::InternalNode<InternalEntry>(config, 0),
m_defaultConfig(defaultConfig),
m_supernodeConfig(supernodeConfig)
{}
/*
Default copy constructor.
*/
inline InternalNode(const InternalNode &node)
: gtree::InternalNode<InternalEntry>(node),
m_defaultConfig(node.m_defaultConfig),
m_supernodeConfig(node.m_supernodeConfig)
{}
/*
MemSize (used to update used node cache size).
*/
unsigned memSize(bool recompute) const
{
return gtree::InternalNode<InternalEntry>::
memSize(recompute) + 2*sizeof(gtree::NodeConfigPtr);
}
/*
Virtual destructor.
*/
inline virtual ~InternalNode()
{}
/*
Returns a reference to a copy of the node.
*/
virtual InternalNode *clone() const
{ return new InternalNode(*this); }
/*
Sets supernode state.
*/
inline void setSupernode()
{ m_config = m_supernodeConfig; }
/*
Resets supernode state.
*/
inline void resetSupernode()
{ m_config = m_defaultConfig; }
/*
Returns "true"[4] if "this"[4] is a supernode.
*/
inline bool isSupernode()
{ return this->m_config->type() == SUPERNODE; }
/*
Returns the union of all contained bounding boxes.
*/
inline gta::HRect *bbox()
{
iterator iter = begin();
gta::HRect *new_bbox = new gta::HRect(*(*iter)->bbox());
while(++iter != end())
new_bbox->unite((*iter)->bbox());
return new_bbox;
}
/*
Returns the union of the given entry vector.
*/
static gta::HRect *bbox(std::vector <InternalEntry*> *entries)
{
iterator iter = entries->begin();
gta::HRect *new_bbox = new gta::HRect(*(*iter)->bbox());
while(++iter != entries->end())
new_bbox->unite((*iter)->bbox());
return new_bbox;
}
private:
/*
This config objects are needed to change a node into a supernode and vice versa.
*/
gtree::NodeConfigPtr m_defaultConfig;
gtree::NodeConfigPtr m_supernodeConfig;
}; // class "InternalNode"[4]
/********************************************************************
1.1 Typedefs
********************************************************************/
typedef LeafNode* LeafNodePtr;
typedef InternalNode* InternalNodePtr;
} // namespace xtreeAlgebra
#endif // #ifndef __XTREE_BASE_H__