00001 #ifndef MSAHASHTABLE_H
00002 #define MSAHASHTABLE_H
00003
00004 #include "ElemList.h"
00005 #include "msa/msa.h"
00006
00007 class Hashnode{
00008 public:
00009 class tupledata{
00010 public:
00011 enum {MAX_TUPLE = 8};
00012 int nodes[MAX_TUPLE];
00013 tupledata(int _nodes[MAX_TUPLE]){
00014 memcpy(nodes,_nodes,sizeof(int)*MAX_TUPLE);
00015 }
00016 tupledata(tupledata &rhs){
00017 memcpy(nodes,rhs.nodes,sizeof(int)*MAX_TUPLE);
00018 }
00019 tupledata(const tupledata &rhs){
00020 memcpy(nodes,rhs.nodes,sizeof(int)*MAX_TUPLE);
00021 }
00022 tupledata(){};
00023
00024 char *toString(int numnodes,char *str){
00025 str[0]='\0';
00026 for(int i=0;i<numnodes;i++){
00027 sprintf(&str[strlen(str)],"%d ",nodes[i]);
00028 }
00029 return str;
00030 }
00031 inline int &operator[](int i){
00032 return nodes[i];
00033 }
00034 inline const int &operator[](int i) const {
00035 return nodes[i];
00036 }
00037 virtual void pup(PUP::er &p){
00038 p(nodes,MAX_TUPLE);
00039 }
00040 };
00041 int numnodes;
00042
00043 tupledata nodes;
00044 int chunk;
00045 int elementNo;
00046 Hashnode(){
00047 numnodes=0;
00048 };
00049 Hashnode(int _num,int _chunk,int _elNo,int _nodes[tupledata::MAX_TUPLE]): nodes(_nodes){
00050 numnodes = _num;
00051 chunk = _chunk;
00052 elementNo = _elNo;
00053 }
00054 Hashnode(const Hashnode &rhs){
00055 *this = rhs;
00056 }
00057 inline Hashnode &operator=(const Hashnode &rhs){
00058 numnodes = rhs.numnodes;
00059 for(int i=0;i<numnodes;i++){
00060 nodes[i] = rhs.nodes[i];
00061 }
00062 chunk = rhs.chunk;
00063 elementNo = rhs.elementNo;
00064 return *this;
00065 }
00066 inline bool operator==(const Hashnode &rhs){
00067 if(numnodes != rhs.numnodes){
00068 return false;
00069 }
00070 for(int i=0;i<numnodes;i++){
00071 if(nodes[i] != rhs.nodes[i]){
00072 return false;
00073 }
00074 }
00075 if(chunk != rhs.chunk){
00076 return false;
00077 }
00078 if(elementNo != rhs.elementNo){
00079 return false;
00080 }
00081 return true;
00082 }
00083 inline bool operator>=(const Hashnode &rhs){
00084 if(numnodes < rhs.numnodes){
00085 return false;
00086 };
00087 if(numnodes > rhs.numnodes){
00088 return true;
00089 }
00090
00091 for(int i=0;i<numnodes;i++){
00092 if(nodes[i] < rhs.nodes[i]){
00093 return false;
00094 }
00095 if(nodes[i] > rhs.nodes[i]){
00096 return true;
00097 }
00098 }
00099 if(chunk < rhs.chunk){
00100 return false;
00101 }
00102 if(chunk > rhs.chunk){
00103 return true;
00104 }
00105 if(elementNo < rhs.elementNo){
00106 return false;
00107 }
00108 if(elementNo > rhs.elementNo){
00109 return true;
00110 }
00111 return true;
00112 }
00113
00114 inline bool operator<=(const Hashnode &rhs){
00115 if(numnodes < rhs.numnodes){
00116 return true;
00117 };
00118 if(numnodes > rhs.numnodes){
00119 return false;
00120 }
00121
00122 for(int i=0;i<numnodes;i++){
00123 if(nodes[i] < rhs.nodes[i]){
00124 return true;
00125 }
00126 if(nodes[i] > rhs.nodes[i]){
00127 return false;
00128 }
00129 }
00130 if(chunk < rhs.chunk){
00131 return true;
00132 }
00133 if(chunk > rhs.chunk){
00134 return false;
00135 }
00136 if(elementNo < rhs.elementNo){
00137 return true;
00138 }
00139 if(elementNo > rhs.elementNo){
00140 return false;
00141 }
00142 return true;
00143 }
00144
00145 inline bool equals(tupledata &tuple){
00146 for(int i=0;i<numnodes;i++){
00147 if(tuple.nodes[i] != nodes[i]){
00148 return false;
00149 }
00150 }
00151 return true;
00152 }
00153 virtual void pup(PUP::er &p){
00154 p | numnodes;
00155 p | nodes;
00156 p | chunk;
00157 p | elementNo;
00158 }
00159 };
00160
00161 template <class T, bool PUP_EVERY_ELEMENT=true >
00162 class DefaultListEntry {
00163 public:
00164 template<typename U>
00165 static inline void accumulate(T& a, const U& b) { a += b; }
00166
00167 static inline T getIdentity() { return T(); }
00168 static inline bool pupEveryElement(){ return PUP_EVERY_ELEMENT; }
00169 };
00170
00171 typedef UniqElemList<Hashnode> Hashtuple;
00172 typedef MSA::MSA1D<Hashtuple,DefaultListEntry<Hashtuple,true>,MSA_DEFAULT_ENTRIES_PER_PAGE> MSA1DHASH;
00173
00174 class MsaHashtable
00175 {
00176 MSA1DHASH msa;
00177 bool initHandleGiven;
00178
00179 public:
00180 class Read; class Add;
00181 friend class Read; friend class Add;
00182 Add getInitialAdd();
00183 void pup(PUP::er &p) { p|msa; }
00184 void enroll(int n) { msa.enroll(n); }
00185
00186 class Read : private MSA::MSARead<MSA1DHASH>
00187 {
00188 public:
00189 using MSA::MSARead<MSA1DHASH>::get;
00190
00191 friend class MsaHashtable;
00192 friend class MsaHashtable::Add;
00193 void print();
00194 Add syncToAdd();
00195
00196 private:
00197 Read(MSA1DHASH *m) : MSA::MSARead<MSA1DHASH>(m) { }
00198 };
00199
00200 class Add : private MSA::MSAAccum<MSA1DHASH>
00201 {
00202 using MSA::MSAAccum<MSA1DHASH>::accumulate;
00203 friend class MsaHashtable;
00204 friend class MsaHashtable::Read;
00205 Add(MSA1DHASH *m) : MSA::MSAAccum<MSA1DHASH>(m) { }
00206 public:
00207 int addTuple(int *tuple, int nodesPerTuple, int chunk, int elementNo);
00208 Read syncToRead();
00209 };
00210
00211
00212 MsaHashtable(int _numSlots,int numWorkers)
00213 : msa(_numSlots, numWorkers), initHandleGiven(false) { }
00214 MsaHashtable(){};
00215 };
00216
00217
00218
00219 #endif // MSAHASHTABLE_H