623 lines
12 KiB
C++
623 lines
12 KiB
C++
/*
|
|
This file is part of SECONDO.
|
|
|
|
Copyright (C) 2011, 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
|
|
|
|
2013, May Simone Jandt
|
|
|
|
1 Includes and defines
|
|
|
|
*/
|
|
|
|
#include "JPath.h"
|
|
#include "Symbols.h"
|
|
#include "StandardTypes.h"
|
|
#include "ManageJNet.h"
|
|
|
|
using namespace jnetwork;
|
|
using namespace std;
|
|
/*
|
|
1 Implementation of class JPath
|
|
|
|
1.1 Constructors and Deconstructor
|
|
|
|
*/
|
|
JPath::JPath() : Attribute()
|
|
{}
|
|
|
|
JPath::JPath(const bool def) :
|
|
Attribute(def), path(0), activBulkload(false)
|
|
{
|
|
strcpy(nid, "");
|
|
}
|
|
|
|
JPath::JPath(const string netId, const DbArray<JRouteInterval>& inList,
|
|
const bool check /* = true*/) :
|
|
Attribute(true), path(0), activBulkload(false)
|
|
{
|
|
strcpy(nid, netId.c_str());
|
|
if (check)
|
|
{
|
|
CheckAndFillIntervallList(&inList, 0);
|
|
}
|
|
else
|
|
{
|
|
path.copyFrom(inList);
|
|
}
|
|
path.TrimToSize();
|
|
}
|
|
|
|
JPath::JPath(const JPath& other) :
|
|
Attribute(other.IsDefined()), path(other.GetPath()), activBulkload(false)
|
|
{
|
|
if (other.IsDefined())
|
|
{
|
|
strcpy(nid, *other.GetNetworkId());
|
|
}
|
|
else
|
|
strcpy(nid, "");
|
|
}
|
|
|
|
JPath::~JPath()
|
|
{}
|
|
|
|
/*
|
|
1.1 Getter and Setter for private attributes
|
|
|
|
*/
|
|
|
|
const STRING_T* JPath::GetNetworkId() const
|
|
{
|
|
return &nid;
|
|
}
|
|
|
|
const DbArray<JRouteInterval>& JPath::GetPath() const
|
|
{
|
|
return path;
|
|
}
|
|
|
|
void JPath::SetNetworkId(const STRING_T& id)
|
|
{
|
|
strcpy(nid, id);
|
|
}
|
|
|
|
void JPath::SetPath(const DbArray<JRouteInterval>& in,
|
|
const bool check /*=true*/,
|
|
const JNetwork* jnet /*=0*/)
|
|
{
|
|
if (check)
|
|
{
|
|
CheckAndFillIntervallList (&in, jnet);
|
|
}
|
|
else
|
|
{
|
|
path.clean();
|
|
path.copyFrom(in);
|
|
Simplify();
|
|
}
|
|
path.TrimToSize();
|
|
}
|
|
|
|
/*
|
|
1.1 Override Methods from Attribute
|
|
|
|
*/
|
|
|
|
void JPath::CopyFrom(const Attribute* right)
|
|
{
|
|
*this = *((JPath*)right);
|
|
}
|
|
|
|
size_t JPath::HashValue() const
|
|
{
|
|
size_t res = 0;
|
|
if (IsDefined())
|
|
{
|
|
res += strlen(nid);
|
|
JRouteInterval pe(false);
|
|
for (int i = 0; i < path.Size(); i++)
|
|
{
|
|
Get(i,pe);
|
|
res += pe.HashValue();
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
JPath* JPath::Clone() const
|
|
{
|
|
return new JPath(*this);
|
|
}
|
|
|
|
bool JPath::Adjacent(const Attribute* attrib) const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
int JPath::Compare(const void* ls, const void* rs)
|
|
{
|
|
JPath lhs(*((JPath*) ls));
|
|
JPath rhs(*((JPath*) rs));
|
|
return lhs.Compare(rhs);
|
|
}
|
|
|
|
int JPath::Compare(const Attribute* rhs) const
|
|
{
|
|
JPath in(*((JPath*) rhs));
|
|
return Compare(in);
|
|
}
|
|
|
|
int JPath::Compare(const JPath& rhs) const
|
|
{
|
|
if (!IsDefined() && !rhs.IsDefined()) return 0;
|
|
if (!IsDefined() && rhs.IsDefined()) return -1;
|
|
if (IsDefined() && !rhs.IsDefined()) return 1;
|
|
int aux = strcmp(nid,*rhs.GetNetworkId());
|
|
if (aux != 0) return aux;
|
|
if (path.Size() < rhs.GetNoComponents()) return -1;
|
|
if (path.Size() > rhs.GetNoComponents()) return 1;
|
|
JRouteInterval lri(false);
|
|
JRouteInterval rri(false);
|
|
for (int i = 0; i < path.Size(); i++)
|
|
{
|
|
path.Get(i, lri);
|
|
rhs.Get(i, rri);
|
|
aux = lri.Compare(&rri);
|
|
if (aux != 0) return aux;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
size_t JPath::Sizeof() const
|
|
{
|
|
return sizeof(JPath);
|
|
}
|
|
|
|
int JPath::NumOfFLOBs() const
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
Flob* JPath::GetFLOB(const int i)
|
|
{
|
|
if (i == 0) return &path;
|
|
return 0;
|
|
}
|
|
|
|
ostream& JPath::Print(ostream& os) const
|
|
{
|
|
os << "JPath: ";
|
|
if(IsDefined())
|
|
{
|
|
os << " NetworkId: " << nid << endl;
|
|
JRouteInterval pe(false);
|
|
for (int i = 0; i < path.Size(); i++)
|
|
{
|
|
path.Get(i,pe);
|
|
os << i+1 << ". ";
|
|
pe.Print(os);
|
|
}
|
|
}
|
|
else
|
|
os << Symbol::UNDEFINED() << endl;
|
|
os << endl;
|
|
return os;
|
|
}
|
|
|
|
void JPath::Destroy()
|
|
{
|
|
path.Destroy();
|
|
}
|
|
|
|
void JPath::Clear()
|
|
{
|
|
path.clean();
|
|
SetDefined(true);
|
|
path.TrimToSize();
|
|
}
|
|
|
|
Attribute::StorageType JPath::GetStorageType() const
|
|
{
|
|
return Default;
|
|
}
|
|
|
|
const string JPath::BasicType()
|
|
{
|
|
return "jpath";
|
|
}
|
|
|
|
const bool JPath::checkType(const ListExpr type)
|
|
{
|
|
return listutils::isSymbol(type, BasicType());
|
|
}
|
|
|
|
/*
|
|
1.1 Standard Operators
|
|
|
|
*/
|
|
|
|
JPath& JPath::operator=(const JPath& other)
|
|
{
|
|
SetDefined(other.IsDefined());
|
|
if (other.IsDefined())
|
|
{
|
|
strcpy(nid, *other.GetNetworkId());
|
|
path.copyFrom(other.GetPath());
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
bool JPath::operator==(const JPath& other) const
|
|
{
|
|
return Compare(&other) == 0;
|
|
}
|
|
|
|
bool JPath::operator!=(const JPath& other) const
|
|
{
|
|
return Compare(&other) != 0;
|
|
}
|
|
|
|
bool JPath::operator<(const JPath& other) const
|
|
{
|
|
return Compare(&other) < 0;
|
|
}
|
|
|
|
bool JPath::operator<=(const JPath& other) const
|
|
{
|
|
return Compare(&other) < 1;
|
|
}
|
|
|
|
bool JPath::operator>(const JPath& other) const
|
|
{
|
|
return Compare(&other) > 0;
|
|
}
|
|
|
|
bool JPath::operator>=(const JPath& other) const
|
|
{
|
|
return Compare(&other) >= 0;
|
|
}
|
|
|
|
/*
|
|
1.1 Operators for Secondo Integration
|
|
|
|
*/
|
|
|
|
ListExpr JPath::Out(ListExpr typeInfo, Word value)
|
|
{
|
|
JPath* out = (JPath*) value.addr;
|
|
|
|
if (!out->IsDefined())
|
|
return nl->SymbolAtom(Symbol::UNDEFINED());
|
|
else
|
|
{
|
|
NList nList(*out->GetNetworkId(),true, false);
|
|
|
|
NList entryList(nl->TheEmptyList());
|
|
JRouteInterval pe(false);
|
|
bool first = true;
|
|
for (int i = 0; i < out->GetNoComponents(); i++)
|
|
{
|
|
out->Get(i,pe);
|
|
NList actRIntList(JRouteInterval::Out(nl->TheEmptyList(),
|
|
SetWord((void*) &pe)));
|
|
if (first)
|
|
{
|
|
first = false;
|
|
entryList = actRIntList.enclose();
|
|
}
|
|
else
|
|
entryList.append(actRIntList);
|
|
}
|
|
ListExpr test = nl->TwoElemList(nList.listExpr(), entryList.listExpr());
|
|
return test;
|
|
}
|
|
}
|
|
|
|
Word JPath::In(const ListExpr typeInfo, const ListExpr instance,
|
|
const int errorPos, ListExpr& errorInfo, bool& correct)
|
|
{
|
|
if(nl->ListLength(instance) == 1 && nl->IsEqual(instance,Symbol::UNDEFINED()))
|
|
{
|
|
correct = true;
|
|
return SetWord(new JPath(false));
|
|
}
|
|
else
|
|
{
|
|
if (nl->ListLength(instance) == 2)
|
|
{
|
|
ListExpr netId = nl->First(instance);
|
|
ListExpr entryList = nl->Second(instance);
|
|
ListExpr actEntry = nl->TheEmptyList();
|
|
correct = true;
|
|
DbArray<JRouteInterval>* tmp = new DbArray<JRouteInterval>(0);
|
|
while( !nl->IsEmpty( entryList ) && correct)
|
|
{
|
|
actEntry = nl->First( entryList );
|
|
Word w = JRouteInterval::In(nl->TheEmptyList(), actEntry, errorPos,
|
|
errorInfo, correct);
|
|
if (correct)
|
|
{
|
|
JRouteInterval* actInt = (JRouteInterval*) w.addr;
|
|
tmp->Append(*actInt);
|
|
actInt->DeleteIfAllowed();
|
|
actInt = 0;
|
|
}
|
|
else
|
|
{
|
|
cmsg.inFunError("Error in list of " + JRouteInterval::BasicType() +
|
|
" at " + nl->ToString(actEntry));
|
|
}
|
|
entryList = nl->Rest( entryList );
|
|
}
|
|
JPath* res = 0;
|
|
if (correct)
|
|
{
|
|
res = new JPath(nl->StringValue(netId), *tmp);
|
|
}
|
|
tmp->Destroy();
|
|
delete tmp;
|
|
return SetWord(res);
|
|
}
|
|
}
|
|
correct = false;
|
|
cmsg.inFunError("Expected List of length 1 or 2.");
|
|
return SetWord(Address(0));
|
|
}
|
|
|
|
Word JPath::Create(const ListExpr typeInfo)
|
|
{
|
|
return SetWord(new JPath(false));
|
|
}
|
|
|
|
void JPath::Delete( const ListExpr typeInfo, Word& w )
|
|
{
|
|
((JPath*) w.addr)->Destroy();
|
|
delete ((JPath*)w.addr);
|
|
w.addr = 0;
|
|
}
|
|
|
|
void JPath::Close( const ListExpr typeInfo, Word& w )
|
|
{
|
|
delete ((JPath*)w.addr);
|
|
w.addr = 0;
|
|
}
|
|
|
|
Word JPath::Clone( const ListExpr typeInfo, const Word& w )
|
|
{
|
|
return (new JPath(*((JPath*) w.addr)));
|
|
}
|
|
|
|
void* JPath::Cast( void* addr )
|
|
{
|
|
return (new (addr) JPath);
|
|
}
|
|
|
|
bool JPath::KindCheck ( ListExpr type, ListExpr& errorInfo )
|
|
{
|
|
return checkType(type);
|
|
}
|
|
|
|
int JPath::SizeOf()
|
|
{
|
|
return sizeof(JPath);
|
|
}
|
|
|
|
ListExpr JPath::Property()
|
|
{
|
|
return nl->TwoElemList(
|
|
nl->FourElemList(
|
|
nl->StringAtom("Signature"),
|
|
nl->StringAtom("Example Type List"),
|
|
nl->StringAtom("List Rep"),
|
|
nl->StringAtom("Example List")),
|
|
nl->FourElemList(
|
|
nl->StringAtom("-> " + Kind::DATA()),
|
|
nl->StringAtom(BasicType()),
|
|
nl->TextAtom("("+ CcString::BasicType() + " ((" +
|
|
JRouteInterval::BasicType() + ") ...("+ JRouteInterval::BasicType() +
|
|
"))), describes a path in the jnetwork, named by string, by a "+
|
|
"set of "+ JRouteInterval::BasicType() + "."),
|
|
nl->TextAtom(Example())));
|
|
}
|
|
|
|
/*
|
|
1.1 Manage Bulkload of Routeintervals
|
|
|
|
*/
|
|
|
|
void JPath::StartBulkload()
|
|
{
|
|
SetDefined(true);
|
|
path.clean();
|
|
path.TrimToSize();
|
|
activBulkload = true;
|
|
}
|
|
|
|
void JPath::EndBulkload()
|
|
{
|
|
activBulkload = false;
|
|
Simplify();
|
|
path.TrimToSize();
|
|
}
|
|
|
|
void JPath::Simplify()
|
|
{
|
|
if (path.Size() > 1)
|
|
{
|
|
JRouteInterval curRint(false);
|
|
JRouteInterval lastRint(false);
|
|
DbArray<JRouteInterval>* tmp = new DbArray<JRouteInterval>(0);
|
|
path.Get(0,lastRint);
|
|
for (int i = 1; i < path.Size(); i++)
|
|
{
|
|
path.Get(i, curRint);
|
|
if (lastRint.Adjacent(curRint))
|
|
{
|
|
lastRint.SetInterval(min(lastRint.GetFirstPosition(),
|
|
curRint.GetFirstPosition()),
|
|
max(lastRint.GetLastPosition(),
|
|
curRint.GetLastPosition()));
|
|
}
|
|
else
|
|
{
|
|
tmp->Append(lastRint);
|
|
lastRint = curRint;
|
|
}
|
|
}
|
|
tmp->Append(lastRint);
|
|
path.clean();
|
|
path.copyFrom(*tmp);
|
|
tmp->Destroy();
|
|
delete tmp;
|
|
}
|
|
}
|
|
|
|
JPath& JPath::Add(const JRouteInterval& pe)
|
|
{
|
|
assert(activBulkload);
|
|
if (IsDefined() && pe.IsDefined() && activBulkload)
|
|
{
|
|
path.Append(pe);
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
/*
|
|
1.1 Other helpful operators
|
|
|
|
1.1.1 Example
|
|
|
|
*/
|
|
|
|
string JPath::Example()
|
|
{
|
|
return "(netname ("+ JRouteInterval::Example() + "))";
|
|
}
|
|
|
|
/*
|
|
1.1.1 GetNoComponents
|
|
|
|
*/
|
|
|
|
int JPath::GetNoComponents() const
|
|
{
|
|
return path.Size();
|
|
}
|
|
|
|
/*
|
|
1.1.1 IsEmpty
|
|
|
|
*/
|
|
|
|
bool JPath::IsEmpty() const {
|
|
return (IsDefined() && GetNoComponents() == 0);
|
|
}
|
|
|
|
/*
|
|
1.1.1 Get
|
|
|
|
*/
|
|
|
|
void JPath::Get(const int i, JRouteInterval& ri) const
|
|
{
|
|
assert (IsDefined() && 0 <= i && i < path.Size());
|
|
path.Get(i, ri);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
1.1.1 ToJLine
|
|
|
|
*/
|
|
|
|
void JPath::ToJLine(JLine* result)
|
|
{
|
|
result->Clear();
|
|
if (IsDefined())
|
|
{
|
|
result->SetNetworkId(nid);
|
|
result->SetRouteIntervals(path, false);
|
|
}
|
|
}
|
|
|
|
double JPath::Length() const
|
|
{
|
|
double result = 0.0;
|
|
JRouteInterval rint;
|
|
for (int i = 0 ; i < path.Size(); i++)
|
|
{
|
|
path.Get(i,rint);
|
|
result = result + rint.GetLength();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
1.1 private Methods
|
|
|
|
1.1.1 FillIntervalList
|
|
|
|
*/
|
|
|
|
void JPath::FillIntervalList(const DbArray<JRouteInterval>* inList,
|
|
const JNetwork* jnet)
|
|
{
|
|
if (inList != NULL && inList->Size() > 0)
|
|
{
|
|
JRouteInterval actEntry;
|
|
StartBulkload();
|
|
for (int i = 0; i < inList->Size(); i++)
|
|
{
|
|
inList->Get(i,actEntry);
|
|
if (jnet->Contains(actEntry))
|
|
{
|
|
Add(actEntry);
|
|
}
|
|
}
|
|
EndBulkload();
|
|
}
|
|
}
|
|
|
|
void JPath::CheckAndFillIntervallList(const DbArray<JRouteInterval>* in,
|
|
const JNetwork* jnet /*= 0*/)
|
|
{
|
|
if (jnet != 0)
|
|
FillIntervalList(in, jnet);
|
|
else
|
|
{
|
|
JNetwork* net = ManageJNet::GetNetwork(nid);
|
|
if (net != 0)
|
|
{
|
|
FillIntervalList(in, net);
|
|
ManageJNet::CloseNetwork(net);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
1 Overwrite output operator
|
|
|
|
*/
|
|
|
|
ostream& operator<<(ostream& os, const JPath& jp)
|
|
{
|
|
jp.Print(os);
|
|
return os;
|
|
}
|