ckarrayindex: Move to new header
[charm.git] / src / ck-core / ckarrayindex.h
1 #include "pup.h"
2
3 #ifndef CKARRAYINDEX_H
4 #define CKARRAYINDEX_H
5
6
7 /// Max number of integers in an array index
8 #ifndef CK_ARRAYINDEX_MAXLEN
9     #define CK_ARRAYINDEX_MAXLEN 3
10 #endif
11
12 /**
13  * Base class for array index objects used in charm.
14  *
15  * An array index is just a hash key; a run of integers
16  * used to look up an object in a hash table.
17  *
18  * @note: Should define *all* data members that make up an index object.
19  * @warning: Do not instantiate! Always create and use a child class
20  * @warning: Do not add constructors / destructors. Class participates in unions
21  *
22  * @note: Should be completely invisible to most client code except those that directly
23  * need to put index objects in unions. This happens only in a few entities in the charm
24  * codebase and should not happen at all in user codes.
25  */
26 struct CkArrayIndexBase
27 {
28     public:
29         ///Length of index in *integers*
30         short int nInts;
31         ///Number of dimensions in this index, not valid for user-defined indices
32         short int dimension;
33         /// The actual index data
34         union {
35             int index[CK_ARRAYINDEX_MAXLEN];
36             short int indexShorts[2 * CK_ARRAYINDEX_MAXLEN];
37         };
38
39         /// Obtain usable object from base object. @warning: Dangerous pointer cast to child class!!!
40         inline CkArrayIndex& asChild() const { return *(CkArrayIndex*)this; }
41
42         /// Permit serialization
43         void pup(PUP::er &p)
44         {
45             p|nInts;
46             p|dimension;
47             for (int i=0;i<nInts;i++) p|index[i];
48         }
49 };
50
51
52
53 /**
54  * Actual array index class intended for regular use
55  *
56  * @warning: Put all data members in base class or they may not be transmitted
57  * in envelopes or callbacks (basically in any entity that stores indices in a
58  * union). Only add behaviors to this class.
59  */
60 class CkArrayIndex: public CkArrayIndexBase
61 {
62     public:
63         /// Default
64         CkArrayIndex() { nInts=0; dimension=0; for (int i=0; i<CK_ARRAYINDEX_MAXLEN; i++) index[i] = 0; }
65         /// Return a pointer to the actual index data
66         int *data(void)             {return index; }
67         /// Return a const pointer to the actual index data
68         const int *data(void) const {return index; }
69
70         /// Return the total number of elements (assuming a dense chare array)
71         int getCombinedCount(void) const
72         {
73             if      (dimension == 1) return data()[0];
74             else if (dimension == 2) return data()[0] * data()[1];
75             else if (dimension == 3) return data()[0] * data()[1] * data()[2];
76             else return 0;
77         }
78
79         /// Used for debug prints elsewhere
80         void print() { CmiPrintf("%d: %d %d %d\n", nInts, index[0], index[1], index[2]); }
81
82         /// Equality comparison
83         CmiBool operator==(const CkArrayIndex& idx) const
84         {
85             if (nInts != idx.nInts) return CmiFalse;
86             for (int i=0; i<nInts; i++)
87                 if (index[i] != idx.index[i]) return CmiFalse;
88             return CmiTrue;
89         }
90
91         /// These routines allow CkArrayIndex to be used in a CkHashtableT
92         inline CkHashCode hash(void) const
93         {
94             register int i;
95             register const int *d=data();
96             register CkHashCode ret=d[0];
97             for (i=1;i<nInts;i++)
98                 ret +=circleShift(d[i],10+11*i)+circleShift(d[i],9+7*i);
99             return ret;
100         }
101         ///
102         static CkHashCode staticHash(const void *a,size_t) { return ((const CkArrayIndex *)a)->hash(); }
103         ///
104         inline int compare(const CkArrayIndex &idx) const { return (idx == *this); }
105         ///
106         static int staticCompare(const void *a,const void *b, size_t)
107         { return (*(const CkArrayIndex *)a == *(const CkArrayIndex *)b); }
108
109         /**
110          * @note: input arrayID is ignored
111          * @todo: Chee Wai Lee had a FIXME note attached to this method because he
112          * felt it was a temporary solution
113          */
114         CmiObjId *getProjectionID(int arrayID)
115         {
116             CmiObjId *ret = new CmiObjId;
117             int i;
118             const int *data=this->data();
119             if (OBJ_ID_SZ>=this->nInts)
120             {
121                 for (i=0;i<this->nInts;i++)
122                     ret->id[i]=data[i];
123                 for (i=this->nInts;i<OBJ_ID_SZ;i++)
124                     ret->id[i]=0;
125             }
126             else
127             {
128                 //Must hash array index into LBObjid
129                 int j;
130                 for (j=0;j<OBJ_ID_SZ;j++)
131                     ret->id[j]=data[j];
132                 for (i=0;i<this->nInts;i++)
133                     for (j=0;j<OBJ_ID_SZ;j++)
134                         ret->id[j]+=circleShift(data[i],22+11*i*(j+1))+
135                             circleShift(data[i],21-9*i*(j+1));
136             }
137             return ret;
138         }
139
140     protected:
141         inline void init(const short num, const short dims, const int x, const int y=0, const int z=0)
142         {
143             nInts = num;
144             dimension = dims;
145             index[0] = x;
146             index[1] = y;
147             index[2] = z;
148             for (int i=3; i < CK_ARRAYINDEX_MAXLEN; i++)
149                 index[i] = 0;
150         }
151
152         inline void init(const short num, const short dims,
153                          const short u, const short v, const short w,
154                          const short x, const short y=0, const short z=0)
155         {
156             nInts = num;
157             dimension = dims;
158             indexShorts[0] = u;
159             indexShorts[1] = v;
160             indexShorts[2] = w;
161             indexShorts[3] = x;
162             indexShorts[4] = y;
163             indexShorts[5] = z;
164             for (int i=6; i < 2 * CK_ARRAYINDEX_MAXLEN; i++)
165                 indexShorts[i] = 0;
166         }
167 };
168
169
170 /**
171  * Support applications and other charm codes that still use the (now dead)
172  * CkArrayIndexMax class to manipulate array indices. All the functionality is
173  * now incorporated into the CkArrayIndex base class itself.
174  *
175  * It is recommended that newer code directly use the base class when there is
176  * need to handle an array index.
177  *
178  * @todo: After at least one minor release announcing the deprecation,
179  * CkArrayIndexMax should no longer be supported.
180  */
181 typedef CkArrayIndex CkArrayIndexMax;
182
183 #endif // CKARRAYINDEX_H
184