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

800 lines
17 KiB
C++

/*
----
This file is part of SECONDO.
Copyright (C) 2015,
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
----
//[$][\$]
*/
#ifndef DARRAY_H
#define DARRAY_H
#include "DArrayElement.h"
#include "ArrayTypes.h"
#include <string>
#include <boost/thread/recursive_mutex.hpp>
#include "NestedList.h"
#include "Algebras/Relation-C++/RelationAlgebra.h"
#include "SecondoSMI.h"
#include "Dist2Helper.h"
namespace distributed2{
/*
3 Class ~DArray~
This class represents the Secondo type ~darray~. It just stores the information
about a connection to a remote server. The actual connections are stored within
the algebra instance.
*/
std::string getName(const arrayType a);
ListExpr wrapType(const arrayType a, ListExpr subType);
std::string getPName(const arrayType a);
ListExpr wrapPType(const arrayType a, ListExpr subType);
template<class A, bool isKill>
void deleteRemoteObjects(A* array);
class DistTypeBase{
public:
DistTypeBase(const std::vector<DArrayElement>& worker,
const std::string& _name);
DistTypeBase( const std::string& _name);
DistTypeBase( const DistTypeBase& src);
// DistTypeBase() {}
explicit DistTypeBase(const int __attribute__((unused)) dummy) {}
DistTypeBase& operator=(const DistTypeBase& src);
virtual ~DistTypeBase(){}
virtual arrayType getType() const = 0;
bool IsDefined() const{ return defined; }
/*
3.6 ~set~
This sets the size, the name, and the worker for a
darray. The map from index to workers is the
standard map.
*/
virtual void set(const std::string& name,
const std::vector<DArrayElement>& worker);
size_t numOfWorkers() const;
virtual size_t getSize() const = 0;
const DArrayElement& getWorker(int i) const;
const std::vector<DArrayElement>& getWorker(){
return worker;
}
std::string getName() const;
bool setName( const std::string& n);
virtual void makeUndefined();
bool equalWorkers(const DistTypeBase& a) const;
const std::vector<DArrayElement>& getWorkers() const{
return worker;
}
std::string getFilePath(const size_t slot){
std::string home = SmiEnvironment::GetSecondoHome();
std::string db = SecondoSystem::GetInstance()->GetDatabaseName();
return getFilePath(home,db,slot);
}
/*
3.22 ~getFilePath~
*/
std::string getFilePath(const std::string& home, const std::string& dbname,
const size_t slot){
std::stringstream ss;
ss << home << "/dfarrays/" << dbname << "/" << name << "/"
<< name << "_" << slot << ".bin";
ss.flush();
return ss.str();
}
inline bool getKeepRemoteObjects(){
return keepRemoteObjects;
}
inline void setKeepRemoteObjects(bool enable){
keepRemoteObjects = enable;
}
protected:
std::vector<DArrayElement> worker; // connection information
std::string name; // the basic name used on workers
bool defined; // defined state of this array
bool keepRemoteObjects;
/*
3.24 ~equalWorker~
Check for equaliness of workers.
*/
bool equalWorkers(const std::vector<DArrayElement>& w) const;
};
class SDArray : public DistTypeBase {
public:
SDArray(const std::vector<DArrayElement>& worker,
const std::string& _name): DistTypeBase(worker,_name){}
SDArray( const std::string& _name): DistTypeBase(_name){}
SDArray( const DistTypeBase& src):DistTypeBase(src){}
explicit SDArray(const int __attribute__((unused)) dummy)
:DistTypeBase(dummy) {}
SDArray& operator=(const DistTypeBase& src) {
DistTypeBase::operator=(src);
return *this;
}
virtual size_t getSize() const {
return worker.size();
}
virtual arrayType getType() const{
return SDARRAY;
}
const DArrayElement& getWorkerForSlot(int i)const{
return worker[i];
}
const int getWorkerIndexForSlot(int slot){
return slot;
}
virtual bool isSlotUsed(int slot) const{
return IsDefined() && slot >=0 && (size_t)slot < worker.size();
}
void setUsedSlots(const std::set<int>& dummy) {}
std::string getObjectNameForSlot(int i) const{
return name;
}
inline static std::string BasicType(){
return "sdarray";
}
inline static bool checkType(ListExpr list){
return nl->HasLength(list,2) &&
listutils::isSymbol(nl->First(list),BasicType());
}
static ListExpr Property();
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 ) {
SDArray* res = new SDArray("");
res->makeUndefined();
return SetWord(res);
}
static void Delete( const ListExpr typeInfo, Word& w ){
SDArray* victim = (SDArray*) w.addr;
deleteRemoteObjects<SDArray,false>(victim);
delete victim;
w.addr = 0;
}
static bool Open( SmiRecord& valueRecord,
size_t& offset, const ListExpr typeInfo,
Word& value );
static bool Save( SmiRecord& valueRecord, size_t& offset,
const ListExpr typeInfo, Word& value );
static void Close( const ListExpr typeInfo, Word& w ){
SDArray* victim = (SDArray*) w.addr;
delete victim;
w.addr = 0;
}
static Word Clone( const ListExpr typeInfo, const Word& w ) {
SDArray* a = (SDArray*) w.addr;
return SetWord(new SDArray(*a));
}
static void* Cast( void* addr ) {
return (new (addr) SDArray(23));
}
static bool TypeCheck(ListExpr type, ListExpr& errorInfo){
return checkType(type);
}
static int SizeOf(){
return 85; // size depends on an object, not clear what to return here
}
static ListExpr wrapType(ListExpr subtype){
return nl->TwoElemList( nl->SymbolAtom(BasicType()), subtype);
}
private:
// privacy is unknown to this class
};
class DArrayBase: public DistTypeBase{
public:
/*
3.1 Constructors
The constructors create a darray from predefined values.
*/
DArrayBase(const std::vector<uint32_t>& _map, const std::string& _name);
DArrayBase(const size_t _size , const std::string& _name);
DArrayBase(const std::vector<uint32_t>& _map, const std::string& _name,
const std::vector<DArrayElement>& _worker);
DArrayBase(const size_t _size, const std::string& _name,
const std::vector<DArrayElement>& _worker);
explicit DArrayBase(int dummy):DistTypeBase(dummy) {}
// only for cast function
DArrayBase(const DArrayBase& src);
/*
3.2 Assignment Operator
*/
DArrayBase& operator=(const DArrayBase& src);
virtual bool isSlotUsed(int slot) const{
return IsDefined() && slot >=0 && (size_t) slot < getSize();
}
void copyFrom(const DArrayBase& src){
*this = src;
}
void copyFrom(const DistTypeBase& src){
DistTypeBase::operator=(src);
setStdMap(src.getSize());
}
/*
3.3 Destructor
*/
virtual ~DArrayBase() {}
/*
3.4 ~getWorkerNum~
This fucntion returns the worker that is responsible for
the given index.
*/
uint32_t getWorkerNum(uint32_t index);
/*
3.5 ~getType~
*/
arrayType getType() const = 0;
const std::vector<uint32_t> getMap()const{
return map;
}
size_t getSize() const {
boost::lock_guard<boost::recursive_mutex> guard(mapmtx);
return map.size();
}
/*
3.7 ~equalMapping~
Checks whether the mappings from indexes to the workers
are equal for two darray types.
*/
bool equalMapping(DistTypeBase& a, bool ignoreSize )const;
/*
3.8 ~set~
Sets size, name and workers. Set to a standard map.
*/
void set(const std::string& name,
const std::vector<DArrayElement>& worker);
virtual void set(const size_t size, const std::string& name,
const std::vector<DArrayElement>& worker);
/*
3.9 ~set~
Sets the mapping, the workers and the name for a darray.
The size is extracted from the mapping.
*/
void set(const std::vector<uint32_t>& m, const std::string& name,
const std::vector<DArrayElement>& worker);
/*
3.14 Some setters and getters
*/
virtual void makeUndefined();
void setStdMap(size_t size);
const DArrayElement& getWorkerForSlot(int i) const;
size_t getWorkerIndexForSlot(int i);
void setResponsible(size_t slot, size_t _worker);
/*
3.15 ~toListExpr~
Returns the list representation for this darray.
*/
ListExpr toListExpr() const;
/*
3.16 ~readFrom~
Read a darray value from a list. If the list is not a valid
description, null is returned. The caller is responsible for
deleting the return value, if the is one.
*/
template<class R>
static R* readFrom(ListExpr list, bool partially);
/*
3.17 ~open~
Reads the content of darray from a SmiRecord.
*/
template<class R, bool partially>
static bool open(SmiRecord& valueRecord, size_t& offset,
const ListExpr typeInfo, Word& result);
virtual void setUsedSlots(const std::set<int>& dummy) {}
virtual std::set<int> getUsedSlots(){
std::set<int> res;
for (size_t i=0;i<this->getSize(); i++){
res.insert(i);
}
return res;
}
virtual bool isPartially() const{
return false;
}
/*
3.18 ~save~
Saves a darray to an SmiRecord.
*/
template<bool partially>
static bool save(SmiRecord& valueRecord, size_t& offset,
const ListExpr typeInfo, Word& value);
/*
3.19 ~createStdMap~
Returns a vector representing the standard mapping from index to
worker.
*/
static std::vector<uint32_t> createStdMap(const uint32_t size,
const int numWorkers);
/*
3.20 ~print~
Writes the content to an output stream.
*/
void print(std::ostream& out)const;
/*
3.21 ~getObjectNameForSlot~
Returns the name of the remote object
*/
std::string getObjectNameForSlot(const size_t slot) const{
std::stringstream ss;
ss << name << "_" << slot;
return ss.str();
}
/*
3.22 ~getFilePath~
*/
std::string getPath(const std::string& home, const std::string& dbname){
std::stringstream ss;
ss << home << "/dfarrays/" << dbname << "/" << name << "/";
return ss.str();
}
/*
3.22 ~createFromRel ~
Reads the content of a darray from a relation defining
the workers. The name and the size are explicitely given.
The relation must have at least 3 attributes. The attribute
at position hostPos must be of type H (CcString or FText) and
describes the host of the worker. At potPos, a ~CcInt~ describes
the port of the SecondoMonitor. At position configPos, an attribute
of type C (CcString of FText) describes the configuration file
for connecting with the worker.
*/
template<class H, class C, class R>
static R createFromRel(Relation* rel, int size,
std::string name,
int hostPos, int portPos, int configPos);
bool equalMapping(DArrayBase& a, bool ignoreSize ) const;
protected:
std::vector<uint32_t> map; // map from index to worker
mutable boost::recursive_mutex mapmtx;
/*
3.23 ~checkMap~
Checks whether the contained map is valid.
*/
bool checkMap();
/*
3.24 ~isStdMap~
Checks whether the contained map is a standard map.
*/
bool isStdMap() const;
};
std::ostream& operator<<(std::ostream& o, const DArrayBase& a);
template<class H, class C, class R>
R DArrayBase::createFromRel(Relation* rel, int size,
std::string name, int hostPos, int portPos, int
configPos){
std::vector<uint32_t> m;
R result(m,"");
if(size<=0){
result.makeUndefined();
return result;
}
if(!stringutils::isIdent(name)){
result.makeUndefined();
return result;
}
result.defined = true;
result.name = name;
GenericRelationIterator* it = rel->MakeScan();
Tuple* tuple;
while((tuple = it->GetNextTuple())){
DArrayElement* elem =
DArrayElement::createFromTuple<H,C>(tuple,
result.worker.size(),hostPos,
portPos, configPos);
tuple->DeleteIfAllowed();
if(elem){
result.worker.push_back(*elem);
delete elem;
}
}
delete it;
result.setStdMap(size);
return result;
}
template<arrayType type>
class DArrayT: public DArrayBase{
public:
DArrayT(const std::vector<uint32_t>&v, const std::string& name):
DArrayBase(v,name) {}
DArrayT(const int dummy):DArrayBase(dummy) {}
DArrayT(const DArrayBase& src) : DArrayBase(src) {}
DArrayT& operator=(const DArrayBase& src){
DArrayBase::operator=(src);
return *this;
}
DArrayT& operator=(const SDArray& src){
set(src.getSize(),src.getName(),src.getWorkers());
if(!src.IsDefined()){
makeUndefined();
}
return *this;
}
static const std::string BasicType(){
return distributed2::getName(type);;
}
static ListExpr wrapType(ListExpr subtype){
return distributed2::wrapType(type, subtype);
}
static DArrayT* readFrom(ListExpr list){
return DArrayBase::readFrom<DArrayT<type> >(list, false);
}
arrayType getType()const override{ return type; }
static bool checkType(const ListExpr list);
};
typedef DArrayT<DARRAY> DArray;
typedef DArrayT<DFARRAY> DFArray;
template<arrayType T>
class PDArrayT: public DArrayT<T> {
public:
PDArrayT(const std::vector<uint32_t>&v, const std::string& name):
DArrayT<T>(v,name),usedSlots() {}
PDArrayT(const int dummy):DArrayT<T>(dummy) {}
PDArrayT(const DArrayBase& src) : DArrayBase(src) {
for(size_t i=0;i<src.getSize();i++){
if(isSlotUsed(i)){
usedSlots.insert(i);
}
}
}
PDArrayT& operator=(const DArrayBase& src){
DArrayBase::operator=(src);
usedSlots.clear();
for(size_t i=0;i<src.getSize(); i++){
if(src.isSlotUsed(i)){
usedSlots.insert(i);
}
}
return *this;
}
bool isSlotUsed(int i) const override{
if(!this->IsDefined()) {
return false;
}
if(i<0 || (size_t)i>=this->getSize()) {
return false;
}
return usedSlots.find(i) != usedSlots.end();
}
PDArrayT& operator=(const SDArray& src){
this->set(src.getSize(),src.getName(),src.getWorkers());
if(!src.IsDefined()){
this->makeUndefined();
} else {
usedSlots.clear();
for(size_t i=0;i<src.getSize(); i++){
usedSlots.insert(i);
}
}
return *this;
}
static const std::string BasicType(){
return distributed2::getPName(T);;
}
static ListExpr wrapType(ListExpr subtype){
return distributed2::wrapPType(T, subtype);
}
static PDArrayT* readFrom(ListExpr list){
return DArrayBase::readFrom<PDArrayT<T> >(list, true);
}
arrayType getType()const override{
return T;
}
static bool checkType(const ListExpr list);
void setUsedSlots(const std::set<int>& us) override{
usedSlots = us;
}
bool isPartially() const override{
return true;
}
std::set<int> getUsedSlots() override{
return usedSlots;
}
private:
std::set<int> usedSlots;
};
typedef PDArrayT<DARRAY> PDArray;
typedef PDArrayT<DFARRAY> PDFArray;
class DFMatrix: public DistTypeBase{
public:
DFMatrix(const size_t _size, const std::string& _name);
DFMatrix(const size_t _size, const std::string& _name,
const std::vector<DArrayElement>& _worker);
explicit DFMatrix(int dummy):DistTypeBase(dummy) {}
// only for cast function
void setSize(size_t newSize);
static const std::string BasicType();
static bool open(SmiRecord& valueRecord, size_t& offset,
const ListExpr typeInfo, Word& result);
virtual arrayType getType() const {
return DFMATRIX;
}
static bool save(SmiRecord& valueRecord, size_t& offset,
const ListExpr typeInfo, Word& value);
static bool checkType(ListExpr e);
ListExpr toListExpr() const;
static DFMatrix* readFrom(ListExpr list);
size_t getSize() const{
return size;
}
void copyFrom(const DFMatrix& M){
*this = M;
}
void copyFrom(const DArrayBase& A){
DistTypeBase::operator=(A);
size = A.getSize();
}
private:
size_t size;
};
} // end of namespace distributed2
#endif