786 lines
16 KiB
C++
786 lines
16 KiB
C++
/*
|
|
----
|
|
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
|
|
----
|
|
|
|
//paragraph [1] title: [{\Large \bf ] [}]
|
|
|
|
|
|
|
|
[1] Polygon Algebra
|
|
|
|
January 2003 VTA
|
|
|
|
December 2005, Victor Almeida deleted the deprecated algebra levels
|
|
(~executable~, ~descriptive~, and ~hibrid~). Only the executable
|
|
level remains. Models are also removed from type constructors.
|
|
|
|
This ~polygon~ example algebra is intended as a documentation of the state diagram of objects inside the Secondo system. This state diagram shown in Figure 1 is needed because objects can have some persistent part handled by its own algebra.
|
|
Every object in the Secondo system must have a memory part and may have a persistent part not handled by the Secondo system, but by the algebra from which the object belongs.
|
|
In this algebra, the vertices of the polygon are persistent using a ~DBArray~ (from Persistent Array) structure.
|
|
|
|
In this way, objects, when they exist in the Secondo system, can stay into two states: \emph{opened} and \emph{closed}. Figure 1 shows the state diagram for objects in the Secondo system. When an object is in ~opened~ state, it has the memory part already loaded into memory and the files/records needed for the persistent part (if used) are opened and ready for use. When an object is in ~closed~ state the files/records needed for the persistent part are closed and the memory part is freed.
|
|
|
|
|
|
Figure 1: Object state diagram [objstatediag.eps]
|
|
|
|
These six transition functions are implemented in the ~polygon~ algebra by the functions: ~CreatePolygon~, ~DeletePolygon~, ~OpenPolygon~, ~ClosePolygon~, ~SavePolygon~, and ~ClonePolygon~.
|
|
|
|
1 Preliminaries
|
|
|
|
1.1 Includes and global declarations
|
|
|
|
*/
|
|
|
|
#include <iostream>
|
|
|
|
#include "Algebra.h"
|
|
#include "NestedList.h"
|
|
#include "QueryProcessor.h"
|
|
#include "SecondoSystem.h"
|
|
#include "../../Tools/Flob/DbArray.h"
|
|
#include "Attribute.h"
|
|
#include "Symbols.h"
|
|
#include "ListUtils.h"
|
|
|
|
/*
|
|
GNU gcc 3.2 includes the header 'windows.h' from standard headers.
|
|
Therefore we need to change internally the name of the Polygon
|
|
class since Windows defines an API function 'Polygon'.
|
|
|
|
*/
|
|
|
|
extern NestedList* nl;
|
|
extern QueryProcessor *qp;
|
|
|
|
|
|
namespace polygonalg{
|
|
|
|
/*
|
|
|
|
2 Data structures
|
|
|
|
2.1 Struct Vertex
|
|
|
|
*/
|
|
struct Vertex
|
|
{
|
|
Vertex() {}
|
|
/*
|
|
Do not use this constructor.
|
|
|
|
*/
|
|
|
|
Vertex( int xcoord, int ycoord ):
|
|
x( xcoord ), y( ycoord )
|
|
{}
|
|
|
|
Vertex(const Vertex& v) : x(v.x), y(v.y) {}
|
|
|
|
Vertex& operator=(const Vertex& v){
|
|
x = v.x;
|
|
y = v.y;
|
|
return *this;
|
|
}
|
|
|
|
~Vertex(){}
|
|
|
|
int x;
|
|
int y;
|
|
};
|
|
|
|
/*
|
|
|
|
2.2 Class Edge
|
|
|
|
*/
|
|
class Edge
|
|
{
|
|
public:
|
|
Edge( const Vertex& s, const Vertex& e ) :
|
|
start( s ), end( e )
|
|
{}
|
|
|
|
Edge(const Edge& src) : start(src.start), end(src.end){}
|
|
|
|
Edge& operator=(const Edge& src){
|
|
start = src.start;
|
|
end = src.end;
|
|
return *this;
|
|
}
|
|
|
|
~Edge(){}
|
|
|
|
Vertex& Start()
|
|
{ return start; }
|
|
|
|
Vertex& End()
|
|
{ return end; }
|
|
|
|
private:
|
|
Vertex start;
|
|
Vertex end;
|
|
};
|
|
|
|
enum PolygonState { partial, complete };
|
|
|
|
/*
|
|
|
|
2.3 Class Polygon
|
|
|
|
*/
|
|
class Polygon : public Attribute
|
|
{
|
|
|
|
public:
|
|
Polygon( const int n, const int *X = 0, const int *Y = 0 );
|
|
~Polygon();
|
|
|
|
Polygon(const Polygon& src);
|
|
Polygon& operator=(const Polygon& src);
|
|
|
|
int NumOfFLOBs() const;
|
|
Flob *GetFLOB(const int i);
|
|
int Compare(const Attribute*) const;
|
|
bool Adjacent(const Attribute*) const;
|
|
Polygon *Clone() const;
|
|
size_t Sizeof() const;
|
|
std::ostream& Print( std::ostream& os ) const;
|
|
|
|
void Append( const Vertex &v );
|
|
void Complete();
|
|
bool Correct();
|
|
void Destroy();
|
|
int GetNoEdges() const { return GetNoVertices(); }
|
|
int GetNoVertices() const;
|
|
Edge GetEdge( int i ) const;
|
|
Vertex GetVertex( int i ) const;
|
|
std::string GetState() const;
|
|
const bool IsEmpty() const;
|
|
void CopyFrom(const Attribute* right);
|
|
size_t HashValue() const;
|
|
|
|
friend std::ostream& operator <<( std::ostream& os, const Polygon& p );
|
|
|
|
static Word In( const ListExpr typeInfo, const ListExpr instance,
|
|
const int errorPos, ListExpr& errorInfo,
|
|
bool& correct );
|
|
|
|
static ListExpr Out( ListExpr typeInfo, Word value );
|
|
|
|
static Word Create( const ListExpr typeInfo );
|
|
|
|
static void Delete( const ListExpr typeInfo, Word& w );
|
|
|
|
static void Close( const ListExpr typeInfo, Word& w );
|
|
|
|
static bool Save( SmiRecord& valueRecord, size_t& offset,
|
|
const ListExpr typeInfo, Word& value );
|
|
|
|
static bool Open( SmiRecord& valueRecord, size_t& offset,
|
|
const ListExpr typeInfo, Word& value );
|
|
|
|
static Word Clone( const ListExpr typeInfo, const Word& w );
|
|
|
|
|
|
static bool KindCheck( ListExpr type, ListExpr& errorInfo );
|
|
|
|
static int SizeOfObj();
|
|
|
|
static ListExpr Property();
|
|
|
|
static void* Cast(void* addr);
|
|
|
|
static const std::string BasicType() { return "polygon"; }
|
|
static const bool checkType(const ListExpr type){
|
|
return listutils::isSymbol(type, BasicType());
|
|
}
|
|
|
|
private:
|
|
Polygon() {} // this constructor is reserved for the cast function.
|
|
DbArray<Vertex> vertices;
|
|
PolygonState state;
|
|
};
|
|
|
|
/*
|
|
2.3.18 Print functions
|
|
|
|
*/
|
|
std::ostream& operator<<(std::ostream& os, const Vertex& v)
|
|
{
|
|
os << "(" << v.x << "," << v.y << ")";
|
|
return os;
|
|
}
|
|
|
|
|
|
std::ostream& operator<<(std::ostream& os, const Polygon& p)
|
|
{
|
|
os << " State: " << p.GetState()
|
|
<< "<";
|
|
|
|
for(int i = 0; i < p.GetNoVertices(); i++)
|
|
os << p.GetVertex( i ) << " ";
|
|
|
|
os << ">";
|
|
|
|
return os;
|
|
}
|
|
|
|
/*
|
|
2.3.1 Constructors.
|
|
|
|
This first constructor creates a new polygon.
|
|
|
|
*/
|
|
Polygon::Polygon( const int n, const int *X, const int *Y ) :
|
|
Attribute(true),
|
|
vertices( n ),
|
|
state( partial )
|
|
{
|
|
SetDefined(true);
|
|
if( n > 0 )
|
|
{
|
|
for( int i = 0; i < n; i++ )
|
|
{
|
|
Vertex v( X[i], Y[i] );
|
|
Append( v );
|
|
}
|
|
Complete();
|
|
}
|
|
}
|
|
|
|
/*
|
|
2.3.2 Copy Constructor
|
|
|
|
*/
|
|
Polygon::Polygon(const Polygon& src):
|
|
Attribute(src.IsDefined()),
|
|
vertices(src.vertices.Size()),state(src.state){
|
|
vertices.copyFrom(src.vertices);
|
|
}
|
|
|
|
/*
|
|
|
|
2.3.2 Destructor.
|
|
|
|
*/
|
|
Polygon::~Polygon()
|
|
{
|
|
}
|
|
|
|
Polygon& Polygon::operator=(const Polygon& src){
|
|
this->state = src.state;
|
|
vertices.copyFrom(src.vertices);
|
|
return *this;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
2.3.3 NumOfFLOBs.
|
|
|
|
|
|
*/
|
|
int Polygon::NumOfFLOBs() const
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
2.3.4 GetFLOB
|
|
|
|
|
|
*/
|
|
Flob *Polygon::GetFLOB(const int i)
|
|
{
|
|
assert( i >= 0 && i < NumOfFLOBs() );
|
|
return &vertices;
|
|
}
|
|
|
|
/*
|
|
2.3.5 Compare
|
|
|
|
Not yet implemented. Needed to be a tuple attribute.
|
|
|
|
*/
|
|
int Polygon::Compare(const Attribute*) const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
2.3.6 HashValue
|
|
|
|
Because Compare returns alway 0, we can only return a constant hash value.
|
|
|
|
*/
|
|
size_t Polygon::HashValue() const{
|
|
return 1;
|
|
}
|
|
|
|
|
|
/*
|
|
2.3.5 Adjacent
|
|
|
|
Not yet implemented. Needed to be a tuple attribute.
|
|
|
|
*/
|
|
bool Polygon::Adjacent(const Attribute*) const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
2.3.7 Clone
|
|
|
|
Returns a new created polygon (clone) which is a
|
|
copy of ~this~.
|
|
|
|
*/
|
|
Polygon *Polygon::Clone() const
|
|
{
|
|
assert( state == complete );
|
|
Polygon *p = new Polygon( *this );
|
|
return p;
|
|
}
|
|
|
|
void Polygon::CopyFrom(const Attribute* right){
|
|
*this = *( (Polygon*) right);
|
|
}
|
|
|
|
/*
|
|
2.3.8 Sizeof
|
|
|
|
*/
|
|
size_t Polygon::Sizeof() const
|
|
{
|
|
return sizeof( *this );
|
|
}
|
|
|
|
/*
|
|
2.3.8 Print
|
|
|
|
*/
|
|
std::ostream& Polygon::Print( std::ostream& os ) const
|
|
{
|
|
return (os << *this);
|
|
}
|
|
|
|
/*
|
|
2.3.9 Append
|
|
|
|
Appends a vertex ~v~ at the end of the polygon.
|
|
|
|
*Precondition* ~state == partial~.
|
|
|
|
*/
|
|
void Polygon::Append( const Vertex& v )
|
|
{
|
|
assert( state == partial );
|
|
vertices.Append( v );
|
|
}
|
|
|
|
/*
|
|
2.3.10 Complete
|
|
|
|
Turns the polygon into the ~complete~ state.
|
|
|
|
*Precondition* ~state == partial~.
|
|
|
|
*/
|
|
void Polygon::Complete()
|
|
{
|
|
assert( state == partial );
|
|
state = complete;
|
|
}
|
|
|
|
/*
|
|
2.3.11 Correct
|
|
|
|
Not yet implemented.
|
|
|
|
*/
|
|
bool Polygon::Correct()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
2.3.13 Destroy
|
|
|
|
Turns the polygon into the ~closed~ state destroying the
|
|
vertices array.
|
|
|
|
*Precondition* ~state == complete~.
|
|
|
|
*/
|
|
void Polygon::Destroy()
|
|
{
|
|
assert( state == complete );
|
|
vertices.destroy();
|
|
}
|
|
|
|
/*
|
|
2.3.14 NoEdges
|
|
|
|
Returns the number of edges of the polygon.
|
|
|
|
*Precondition* ~state == complete~.
|
|
|
|
*/
|
|
int Polygon::GetNoVertices() const
|
|
{
|
|
return vertices.Size();
|
|
}
|
|
|
|
/*
|
|
2.3.15 GetVertex
|
|
|
|
Returns a vertex indexed by ~i~.
|
|
|
|
*Precondition* ~state == complete \&\& 0 <= i < noVertices~.
|
|
|
|
*/
|
|
Vertex Polygon::GetVertex( int i ) const
|
|
{
|
|
assert( state == complete );
|
|
assert( 0 <= i && i < GetNoVertices() );
|
|
|
|
Vertex v;
|
|
vertices.Get( i, &v );
|
|
return v;
|
|
}
|
|
|
|
/*
|
|
2.3.15 GetEdge
|
|
|
|
Returns an edge indexed by ~i~.
|
|
|
|
*Precondition* ~state == complete \&\& 0 <= i < noVertices~.
|
|
|
|
*/
|
|
Edge Polygon::GetEdge( int i ) const
|
|
{
|
|
assert( state == complete );
|
|
assert( 0 <= i && i < GetNoVertices() );
|
|
|
|
Vertex v, w;
|
|
vertices.Get( i, &v );
|
|
vertices.Get( i+1, &w );
|
|
|
|
Edge e( v, w );
|
|
|
|
return e;
|
|
}
|
|
|
|
/*
|
|
2.3.16 GetState
|
|
|
|
Returns the state of the polygon in string format.
|
|
|
|
*/
|
|
std::string Polygon::GetState() const
|
|
{
|
|
switch( state )
|
|
{
|
|
case partial:
|
|
return "partial";
|
|
case complete:
|
|
return "complete";
|
|
}
|
|
return "";
|
|
}
|
|
|
|
|
|
/*
|
|
2.3.18 IsEmpty
|
|
|
|
Returns if the polygon is empty or not.
|
|
|
|
*/
|
|
const bool Polygon::IsEmpty() const
|
|
{
|
|
assert( state == complete );
|
|
return GetNoVertices() == 0;
|
|
}
|
|
|
|
/*
|
|
3 Polygon Algebra.
|
|
|
|
3.1 List Representation
|
|
|
|
The list representation of a polygon is
|
|
|
|
---- ( (<recordId>) (x1 y1) (x2 y2) ... (xn yn) )
|
|
----
|
|
|
|
3.2 ~In~ and ~Out~ Functions
|
|
|
|
*/
|
|
|
|
ListExpr
|
|
Polygon::Out( ListExpr typeInfo, Word value )
|
|
{
|
|
Polygon* polygon = (Polygon*)(value.addr);
|
|
|
|
if( !polygon->IsDefined() ){
|
|
return nl->SymbolAtom(Symbol::UNDEFINED());
|
|
}
|
|
if( polygon->IsEmpty() )
|
|
{
|
|
return (nl->TheEmptyList());
|
|
}
|
|
else
|
|
{
|
|
ListExpr result =
|
|
nl->OneElemList(
|
|
nl->TwoElemList(
|
|
nl->IntAtom( polygon->GetVertex(0).x ),
|
|
nl->IntAtom( polygon->GetVertex(0).y ) ) );
|
|
ListExpr last = result;
|
|
|
|
for( int i = 1; i < polygon->GetNoVertices(); i++ )
|
|
{
|
|
last = nl->Append( last,
|
|
nl->TwoElemList(
|
|
nl->IntAtom( polygon->GetVertex(i).x ),
|
|
nl->IntAtom( polygon->GetVertex(i).y ) ) );
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
|
|
Word
|
|
Polygon::In( const ListExpr typeInfo, const ListExpr instance,
|
|
const int errorPos, ListExpr& errorInfo, bool& correct )
|
|
{
|
|
Polygon* polygon = new Polygon( 0 );
|
|
polygon->SetDefined(true);
|
|
|
|
if(listutils::isSymbolUndefined( instance )){
|
|
polygon->SetDefined(false);
|
|
correct = true;
|
|
return SetWord( polygon );
|
|
}
|
|
ListExpr first = nl->Empty();
|
|
ListExpr rest = instance;
|
|
while( !nl->IsEmpty( rest ) )
|
|
{
|
|
first = nl->First( rest );
|
|
rest = nl->Rest( rest );
|
|
|
|
if( nl->ListLength( first ) == 2 &&
|
|
nl->IsAtom( nl->First( first ) ) &&
|
|
nl->AtomType( nl->First( first ) ) == IntType &&
|
|
nl->IsAtom( nl->Second( first ) ) &&
|
|
nl->AtomType( nl->Second( first ) ) == IntType )
|
|
{
|
|
Vertex v( nl->IntValue( nl->First( first ) ),
|
|
nl->IntValue( nl->Second( first ) ) );
|
|
polygon->Append( v );
|
|
}
|
|
else
|
|
{
|
|
correct = false;
|
|
delete polygon;
|
|
return SetWord( Address(0) );
|
|
}
|
|
}
|
|
polygon->Complete();
|
|
correct = true;
|
|
return SetWord( polygon );
|
|
}
|
|
|
|
/*
|
|
3.3 Function Describing the Signature of the Type Constructor
|
|
|
|
*/
|
|
|
|
ListExpr
|
|
Polygon::Property()
|
|
{
|
|
return (nl->TwoElemList(
|
|
nl->FiveElemList(nl->StringAtom("Signature"),
|
|
nl->StringAtom("Example Type List"),
|
|
nl->StringAtom("List Rep"),
|
|
nl->StringAtom("Example List"),
|
|
nl->StringAtom("Remarks")),
|
|
nl->FiveElemList(nl->StringAtom("->" + Kind::DATA() ),
|
|
nl->StringAtom(Polygon::BasicType()),
|
|
nl->StringAtom("(<point>*) where <point> is "
|
|
"(<x> <y>)"),
|
|
nl->StringAtom("( (3 4) (10 10) (8 2) (6 4) "
|
|
"(3 4) )"),
|
|
nl->StringAtom("x- and y-coordinates must be of "
|
|
"type int."))));
|
|
}
|
|
|
|
/*
|
|
3.4 Kind Checking Function
|
|
|
|
This function checks whether the type constructor is applied correctly. Since
|
|
type constructor ~polygon~ does not have arguments, this is trivial.
|
|
|
|
*/
|
|
bool
|
|
Polygon::KindCheck( ListExpr type, ListExpr& errorInfo )
|
|
{
|
|
return (nl->IsEqual( type, Polygon::BasicType() ));
|
|
}
|
|
|
|
/*
|
|
|
|
3.5 ~Create~-function
|
|
|
|
*/
|
|
Word Polygon::Create(const ListExpr typeInfo)
|
|
{
|
|
Polygon* polygon = new Polygon( 0 );
|
|
return ( SetWord(polygon) );
|
|
}
|
|
|
|
/*
|
|
3.6 ~Delete~-function
|
|
|
|
*/
|
|
void Polygon::Delete(const ListExpr typeInfo, Word& w)
|
|
{
|
|
Polygon* polygon = (Polygon*)w.addr;
|
|
|
|
polygon->Destroy();
|
|
delete polygon;
|
|
}
|
|
|
|
/*
|
|
3.6 ~Open~-function
|
|
|
|
*/
|
|
bool
|
|
Polygon::Open( SmiRecord& valueRecord,
|
|
size_t& offset,
|
|
const ListExpr typeInfo,
|
|
Word& value )
|
|
{
|
|
Polygon *p = (Polygon*)Attribute::Open( valueRecord, offset, typeInfo );
|
|
value.setAddr( p );
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
3.7 ~Save~-function
|
|
|
|
*/
|
|
bool
|
|
Polygon::Save( SmiRecord& valueRecord,
|
|
size_t& offset,
|
|
const ListExpr typeInfo,
|
|
Word& value )
|
|
{
|
|
Polygon *p = (Polygon *)value.addr;
|
|
Attribute::Save( valueRecord, offset, typeInfo, p );
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
3.8 ~Close~-function
|
|
|
|
*/
|
|
void Polygon::Close(const ListExpr typeInfo, Word& w)
|
|
{
|
|
Polygon* polygon = (Polygon*)w.addr;
|
|
delete polygon;
|
|
}
|
|
|
|
/*
|
|
3.9 ~Clone~-function
|
|
|
|
*/
|
|
Word Polygon::Clone(const ListExpr typeInfo, const Word& w)
|
|
{
|
|
return SetWord( ((Polygon*)w.addr)->Clone() );
|
|
}
|
|
|
|
/*
|
|
3.9 ~SizeOf~-function
|
|
|
|
*/
|
|
int Polygon::SizeOfObj()
|
|
{
|
|
return sizeof(Polygon);
|
|
}
|
|
|
|
/*
|
|
3.10 ~Cast~-function
|
|
|
|
*/
|
|
void* Polygon::Cast(void* addr)
|
|
{
|
|
return (new (addr) Polygon);
|
|
}
|
|
|
|
/*
|
|
3.11 Creation of the Type Constructor Instance
|
|
|
|
*/
|
|
TypeConstructor polygon(
|
|
Polygon::BasicType(), //name
|
|
Polygon::Property, //property function
|
|
Polygon::Out, Polygon::In, //Out and In functions
|
|
0, 0, //SaveTo and RestoreFrom functions
|
|
Polygon::Create, Polygon::Delete, //object creation and deletion
|
|
Polygon::Open, Polygon::Save, //object open and save
|
|
Polygon::Close, Polygon::Clone, //object close and clone
|
|
Polygon::Cast, //cast function
|
|
Polygon::SizeOfObj, //sizeof function
|
|
Polygon::KindCheck ); //kind checking function
|
|
|
|
/*
|
|
4 PolygonAlgebra
|
|
|
|
*/
|
|
class PolygonAlgebra : public Algebra
|
|
{
|
|
public:
|
|
PolygonAlgebra() : Algebra()
|
|
{
|
|
AddTypeConstructor( &polygon );
|
|
|
|
polygon.AssociateKind( Kind::DATA() );
|
|
}
|
|
~PolygonAlgebra() {};
|
|
};
|
|
|
|
/*
|
|
|
|
5 Initialization
|
|
|
|
*/
|
|
|
|
extern "C"
|
|
Algebra*
|
|
InitializePolygonAlgebra(NestedList *nlRef, QueryProcessor *qpRef)
|
|
{
|
|
nl = nlRef;
|
|
qp = qpRef;
|
|
return (new PolygonAlgebra());
|
|
}
|
|
|
|
} // end of namespace
|