00001
00002 #include <stdlib.h>
00003 #include <converse.h>
00004
00005 #define CmiAlloc malloc
00006 #define CmiFree free
00007
00008 typedef struct CmmEntryStruct *CmmEntry;
00009
00010 struct CmmEntryStruct
00011 {
00012 CmmEntry next;
00013 void *msg;
00014 int ntags;
00015 int tags[1];
00016 };
00017
00018 struct CmmTableStruct
00019 {
00020 CmmEntry first;
00021 CmmEntry *lasth;
00022 };
00023
00024
00025 CmmTable CmmNew()
00026 {
00027 CmmTable result = (CmmTable)CmiAlloc(sizeof(struct CmmTableStruct));
00028 result->first = 0;
00029 result->lasth = &(result->first);
00030 return result;
00031 }
00032
00033 void CmmFree(t)
00034 CmmTable t;
00035 {
00036 if (t==NULL) return;
00037 #if (!defined(_FAULT_MLOG_) && !defined(_FAULT_CAUSAL_))
00038 if (t->first!=NULL) CmiAbort("Cannot free a non-empty message table!");
00039 #endif
00040 CmiFree(t);
00041 }
00042
00043
00044 void CmmFreeAll(CmmTable t){
00045 CmmEntry cur;
00046 if(t==NULL) return;
00047 cur = t->first;
00048 while(cur){
00049 CmmEntry toDel = cur;
00050 cur = cur->next;
00051 CmiFree(toDel);
00052 }
00053 }
00054
00055 void CmmPut(t, ntags, tags, msg)
00056 CmmTable t;
00057 int ntags;
00058 int *tags;
00059 void *msg;
00060 {
00061 int i;
00062 CmmEntry e=(CmmEntry)CmiAlloc(sizeof(struct CmmEntryStruct)+(ntags*sizeof(int)));
00063 e->next = 0;
00064 e->msg = msg;
00065 e->ntags = ntags;
00066 for (i=0; i<ntags; i++) e->tags[i] = tags[i];
00067 *(t->lasth) = e;
00068 t->lasth = &(e->next);
00069 }
00070
00071 static int CmmTagsMatch(ntags1, tags1, ntags2, tags2)
00072 int ntags1; int *tags1; int ntags2; int *tags2;
00073 {
00074 int ntags = ntags1;
00075 if (ntags1 != ntags2) return 0;
00076 while (1) {
00077 int tag1, tag2;
00078 if (ntags == 0) return 1;
00079 ntags--;
00080 tag1 = *tags1++;
00081 tag2 = *tags2++;
00082 if (tag1==tag2) continue;
00083 if (tag1==CmmWildCard) continue;
00084 if (tag2==CmmWildCard) continue;
00085 return 0;
00086 }
00087 }
00088
00089 void *CmmFind(t, ntags, tags, rtags, del)
00090 CmmTable t;
00091 int ntags;
00092 int *tags;
00093 int *rtags;
00094 int del;
00095 {
00096 CmmEntry *enth; CmmEntry ent; void *msg; int i;
00097
00098
00099 if(t==NULL) return NULL;
00100
00101 enth = &(t->first);
00102 while (1) {
00103 ent = (*enth);
00104 if (ent==0) return 0;
00105 if (CmmTagsMatch(ntags, tags, ent->ntags, ent->tags)) {
00106 if (rtags) for (i=0; i<ntags; i++) rtags[i] = ent->tags[i];
00107 msg = ent->msg;
00108 if (del) {
00109 CmmEntry next = ent->next;
00110 (*enth) = next;
00111 if (next == 0) t->lasth = enth;
00112 CmiFree(ent);
00113 }
00114 return msg;
00115 }
00116 enth = &(ent->next);
00117 }
00118 }
00119
00120
00121 int CmmGetLastTag(t,ntags,tags)
00122 CmmTable t;
00123 int ntags;
00124 int* tags;
00125 {
00126 CmmEntry *enth; CmmEntry ent;
00127 enth = &(t->first);
00128 while (1) {
00129 ent = (*enth);
00130 if (ent==0) return -1;
00131 if (CmmTagsMatch(ntags, tags, ntags, ent->tags)) {
00132 return (ent->tags[ent->ntags-1]);
00133 }
00134 enth = &(ent->next);
00135 }
00136 return -1;
00137 }
00138
00139 int CmmEntries(t)
00140 CmmTable t;
00141 {
00142 int n = 0;
00143 CmmEntry e = t->first;
00144 while (e) {
00145 e = e->next;
00146 n++;
00147 }
00148 return n;
00149 }
00150
00151
00152 CmmTable CmmPup(pup_er p, CmmTable t, CmmPupMessageFn msgpup)
00153 {
00154 int nentries;
00155
00156 if(!pup_isUnpacking(p))
00157 {
00158 CmmEntry e = t->first, doomed;
00159 nentries = CmmEntries(t);
00160 pup_int(p, &nentries);
00161 while(e) {
00162 pup_int(p, &(e->ntags));
00163 pup_ints(p, e->tags, e->ntags);
00164 msgpup(p,&e->msg);
00165 doomed=e;
00166 e = e->next;
00167 if (pup_isDeleting(p))
00168 CmiFree(doomed);
00169 }
00170 if(pup_isDeleting(p))
00171 {
00172 t->first=NULL;
00173 CmmFree(t);
00174 return 0;
00175 } else
00176 return t;
00177 }
00178 if(pup_isUnpacking(p))
00179 {
00180 int i;
00181 t = CmmNew();
00182 pup_int(p, &nentries);
00183 for(i=0;i<nentries;i++)
00184 {
00185 int ntags, *tags;
00186 void *msg;
00187 pup_int(p, &ntags);
00188 tags = (int*) malloc(ntags*sizeof(int));
00189 pup_ints(p, tags, ntags);
00190 msgpup(p,&msg);
00191 CmmPut(t, ntags, tags, msg);
00192 free(tags);
00193 }
00194 return t;
00195 }
00196 return NULL;
00197 }
00198