afs_int32 AddToNameHash(struct ubik_trans *tt, char *aname, afs_int32 loc) { /* add to name hash */ afs_int32 code; afs_int32 i; struct prentry tentry; i = NameHash(aname); memset(&tentry, 0, sizeof(tentry)); code = pr_ReadEntry(tt, 0, loc, &tentry); if (code) return PRDBFAIL; tentry.nextName = ntohl(cheader.nameHash[i]); cheader.nameHash[i] = htonl(loc); code = pr_WriteEntry(tt, 0, loc, &tentry); if (code) return PRDBFAIL; code = pr_Write(tt, 0, 72 + i * 4, (char *)&cheader.nameHash[i], sizeof(cheader.nameHash[i])); if (code) return PRDBFAIL; return PRSUCCESS; }
afs_int32 FindByName(struct ubik_trans *at, char aname[PR_MAXNAMELEN], struct prentry *tentryp) { /* ditto */ afs_int32 code; afs_int32 i; afs_int32 entry; i = NameHash(aname); entry = ntohl(cheader.nameHash[i]); if (entry == 0) return entry; memset(tentryp, 0, sizeof(struct prentry)); code = pr_ReadEntry(at, 0, entry, tentryp); if (code != 0) return 0; if ((strncmp(aname, tentryp->name, PR_MAXNAMELEN)) == 0) return entry; osi_Assert(entry != tentryp->nextName); entry = tentryp->nextName; while (entry != 0) { memset(tentryp, 0, sizeof(struct prentry)); code = pr_ReadEntry(at, 0, entry, tentryp); if (code != 0) return 0; if ((strncmp(aname, tentryp->name, PR_MAXNAMELEN)) == 0) return entry; osi_Assert(entry != tentryp->nextName); entry = tentryp->nextName; } return 0; }
SC_FUNC symbol * FindTaggedInHashTable(HashTable *ht, const char *name, int fnumber, int *cmptag) { int count=0; symbol *firstmatch=NULL; uint32_t hash = NameHash(name); uint32_t bucket = hash & ht->bucketmask; HashEntry *he = ht->buckets[bucket]; assert(cmptag!=NULL); while (he != NULL) { symbol *sym = he->sym; if ((sym->parent==NULL || sym->ident==iCONSTEXPR) && (sym->fnumber<0 || sym->fnumber==fnumber) && (strcmp(sym->name, name) == 0)) { /* return closest match or first match; count number of matches */ if (firstmatch==NULL) firstmatch=sym; if (*cmptag==0) count++; if (*cmptag==sym->tag) { *cmptag=1; /* good match found, set number of matches to 1 */ return sym; } } he = he->next; } if (firstmatch!=NULL) *cmptag=count; return firstmatch; }
int Read_and_Set_Teams( int M ) { /* 读入并初始化朋友圈信息,返回最大朋友圈里的人数 */ int L, MaxL; int i, j; char name[MAXCHAR+1]; /* 首先默认所有人都没有朋友 */ for (i=0; i<MAXNAME; i++) Team[i] = -1; MaxL = 0; /* MaxL记录最大朋友圈里的人数 */ for (i=0; i<M; i++) { scanf("%d ", &L); if (L > MaxL) MaxL = L; /* 更新MaxL */ for (j=0; j<L; j++) { scanf("%s", name); /* 将name转成数字,并记录其所属朋友圈的编号 */ Team[NameHash(name)] = i; } } for (i=0; i<M; i++) /* 初始状态无人在排队 */ TeamInfo[i].Size = 0; return MaxL; }
void AddQ( Queue Q, struct People X ) { /* 向队列Q中插入X */ int i, pos, r; if ( X.P > MaxProc ) X.P = MaxProc; /* 控制最大事务处理时间 */ i = Team[NameHash(X.Name)]; /* 找到X所属的朋友圈 */ if ( (i == -1) || (!TeamInfo[i].Size) ) { /* 如果没有朋友,或者前面没有朋友在排队 */ /* 则新插入一个分支队列到Q中,且将X插入该分支队列 */ Q->rear++; r = ++Q->TeamQ[Q->rear].Trear; Q->TeamQ[Q->rear].Customer[r].T = X.T; Q->TeamQ[Q->rear].Customer[r].P = X.P; strcpy(Q->TeamQ[Q->rear].Customer[r].Name, X.Name); Q->TeamQ[Q->rear].Tsize++; Q->size++; if ( i != -1 ) { /* 如果有朋友圈,但是没有朋友在前面排队 */ TeamInfo[i].Position = Q->rear; /* 记住这个圈子在Q中的位置 */ TeamInfo[i].Size++; /* 当前多了一人在排队 */ } } else { /* 如果可以夹塞 */ pos = TeamInfo[i].Position; /* 获得前面朋友的位置 */ /* 将X插入pos位置的分支队列中 */ r = ++Q->TeamQ[pos].Trear; Q->TeamQ[pos].Customer[r].T = X.T; Q->TeamQ[pos].Customer[r].P = X.P; strcpy(Q->TeamQ[pos].Customer[r].Name, X.Name); Q->TeamQ[pos].Tsize++; TeamInfo[i].Size++; /* 当前多了一人在排队 */ } }
void badEntry(afs_int32 e, afs_int32 i) { int offset; struct kaentry entry; offset = i * sizeof(struct kaentry) + sizeof(struct kaheader); readDB(offset, &entry, sizeof(entry)); fprintf(stderr, "Entry %d, %s, hash index %d, is bad: [", i, EntryName(&entry), NameHash(&entry)); if (e & 0x1) fprintf(stderr, " UserEntry"); if (e & 0x2) fprintf(stderr, " FreeEntry"); if (e & 0x4) fprintf(stderr, " OldkeysEntry"); if (e & 0x8) fprintf(stderr, " PastEOF"); if (!(e & 0xf)) fprintf(stderr, " <NULL>"); fprintf(stderr, " ] ["); if (e & 0x10) fprintf(stderr, " UserChain"); if (e & 0x20) fprintf(stderr, " FreeChain"); if (e & 0x40) fprintf(stderr, " OldkeysChain"); if (!(e & 0xf0)) fprintf(stderr, " <NULL>"); fprintf(stderr, " ]\n"); }
afs_int32 FindBlock(struct ubik_trans *at, char *aname, char *ainstance, afs_int32 *toP, struct kaentry *tentry) { afs_int32 i, code; afs_int32 to; *toP = 0; i = NameHash(aname, ainstance); for (to = ntohl(cheader.nameHash[i]); to != NULLO; to = ntohl(tentry->next)) { code = karead(at, to, (char *)tentry, sizeof(kaentry)); if (code) return code; /* see if the name matches */ if (!strcmp(aname, tentry->userID.name) && (ainstance == (char *)0 || !strcmp(ainstance, tentry->userID.instance))) { *toP = to; /* found it */ return 0; } } *toP = 0; /* no such entry */ return 0; }
afs_int32 RemoveFromNameHash(struct ubik_trans *tt, char *aname, afs_int32 *loc) { /* remove from name hash */ afs_int32 code; afs_int32 current, trail, i; struct prentry tentry; struct prentry bentry; i = NameHash(aname); current = ntohl(cheader.nameHash[i]); memset(&tentry, 0, sizeof(tentry)); memset(&bentry, 0, sizeof(bentry)); trail = 0; if (current == 0) return PRSUCCESS; /* already gone */ code = pr_ReadEntry(tt, 0, current, &tentry); if (code) return PRDBFAIL; while (strcmp(aname, tentry.name)) { osi_Assert(trail != current); trail = current; current = tentry.nextName; if (current == 0) break; code = pr_ReadEntry(tt, 0, current, &tentry); if (code) return PRDBFAIL; } if (current == 0) return PRSUCCESS; /* we didn't find him, already gone */ if (trail == 0) { /* it's the first entry! */ cheader.nameHash[i] = htonl(tentry.nextName); code = pr_Write(tt, 0, 72 + i * 4, (char *)&cheader.nameHash[i], sizeof(cheader.nameHash[i])); if (code) return PRDBFAIL; } else { code = pr_ReadEntry(tt, 0, trail, &bentry); if (code) return PRDBFAIL; bentry.nextName = tentry.nextName; code = pr_WriteEntry(tt, 0, trail, &bentry); if (code) return PRDBFAIL; } *loc = current; return PRSUCCESS; }
void DeleteQ( Queue Q ) { /* 删除Q队首顾客 */ int i, f; /* 从Q->front所指的分支队列中删除 */ f = Q->TeamQ[Q->front].Tfront; Q->TeamQ[Q->front].Tfront++; Q->TeamQ[Q->front].Tsize--; /* 得到该顾客所属的朋友圈 */ i = Team[NameHash(Q->TeamQ[Q->front].Customer[f].Name)]; /* 如果有朋友,则当前该圈排队减少一人 */ if ( i != -1 ) TeamInfo[i].Size--; /* 如果该圈已经没人排队了,则彻底从总队列Q中删除该分支队列 */ if ( !Q->TeamQ[Q->front].Tsize ) { Q->front++; Q->size--; } }
/** Assign indexes to all nodes in the node table. The ground node (with name "0") must be assigned index zero. The rest nodes are assigned indexes from 1, 2, 3 continuously. */ void Index_All_Nodes() { Insert_Index_Entry(0); // For the ground node index. // Go over all the nodes Node_Entry *itr = *NodeTable; while(itr != NULL) { int hash = NameHash(itr->name, NodeTableSize); int index = Insert_Index_Entry(hash); itr->index = index; itr = itr->next; } MatrixSize = IndexTableSize - 1; // number of nodes = matrix size }
afs_int32 ThreadBlock(struct ubik_trans *at, afs_int32 index, struct kaentry *tentry) { int code; int hi; /* hash index */ if (!index_OK(index)) return KABADINDEX; hi = NameHash(tentry->userID.name, tentry->userID.instance); tentry->next = cheader.nameHash[hi]; code = set_header_word(at, nameHash[hi], htonl(index)); if (code) return KAIO; code = kawrite(at, index, (char *)tentry, sizeof(kaentry)); if (code) return KAIO; return 0; }
SC_FUNC symbol * FindInHashTable(HashTable *ht, const char *name, int fnumber) { uint32_t hash = NameHash(name); uint32_t bucket = hash & ht->bucketmask; HashEntry *he = ht->buckets[bucket]; while (he != NULL) { symbol *sym = he->sym; if ((sym->parent==NULL || sym->ident==iCONSTEXPR) && (sym->fnumber<0 || sym->fnumber==fnumber) && (strcmp(sym->name, name) == 0)) { return sym; } he = he->next; } return NULL; }
afs_int32 UnthreadBlock(struct ubik_trans *at, struct kaentry *aentry) { afs_int32 i, code; afs_int32 to; afs_int32 lo; struct kaentry tentry; i = NameHash(aentry->userID.name, aentry->userID.instance); lo = 0; for (to = ntohl(cheader.nameHash[i]); to != NULLO; to = ntohl(tentry.next)) { code = karead(at, to, (char *)&tentry, sizeof(kaentry)); if (code) return KAIO; /* see if the name matches */ if (!strcmp(aentry->userID.name, tentry.userID.name) && !strcmp(aentry->userID.instance, tentry.userID.instance)) { /* found it */ if (lo) { /* unthread from last block */ code = kawrite(at, lo, (char *)&tentry.next, sizeof(afs_int32)); if (code) return KAIO; } else { /* unthread from hash table */ code = set_header_word(at, nameHash[i], tentry.next); if (code) return KAIO; } aentry->next = 0; /* just to be sure */ return 0; } lo = DOFFSET(to, &tentry, &tentry.next); } return KANOENT; }
static int WorkerBee(struct cmd_syndesc *as, void *arock) { afs_int32 code; char *dbFile; char *outFile; afs_int32 index; struct stat info; struct kaheader header; int nentries, i, j, count; int *entrys; struct kaentry entry; dbFile = as->parms[0].items->data; /* -database */ listuheader = (as->parms[1].items ? 1 : 0); /* -uheader */ listkheader = (as->parms[2].items ? 1 : 0); /* -kheader */ listentries = (as->parms[3].items ? 1 : 0); /* -entries */ verbose = (as->parms[4].items ? 1 : 0); /* -verbose */ outFile = (as->parms[5].items ? as->parms[5].items->data : NULL); /* -rebuild */ if (outFile) { out = fopen(outFile, "w"); if (!out) { afs_com_err(whoami, errno, "opening output file %s", outFile); exit(7); } } else out = 0; fd = open(dbFile, O_RDONLY, 0); if (fd < 0) { afs_com_err(whoami, errno, "opening database file %s", dbFile); exit(6); } code = fstat(fd, &info); if (code) { afs_com_err(whoami, errno, "stat'ing file %s", dbFile); exit(6); } if ((info.st_size - UBIK_HEADERSIZE) % UBIK_BUFFERSIZE) fprintf(stderr, "DATABASE SIZE INCONSISTENT: was %d, should be (n*%d + %d), for integral n\n", (int) info.st_size, UBIK_BUFFERSIZE, UBIK_HEADERSIZE); readUbikHeader(); readDB(0, &header, sizeof(header)); code = CheckHeader(&header); if (listkheader) PrintHeader(&header); nentries = (info.st_size - (UBIK_HEADERSIZE + header.headerSize)) / sizeof(struct kaentry); entrys = calloc(nentries, sizeof(int)); for (i = 0, index = sizeof(header); i < nentries; i++, index += sizeof(struct kaentry)) { readDB(index, &entry, sizeof(entry)); if (index >= header.eofPtr) { entrys[i] |= 0x8; } else if (listentries) { PrintEntry(index, &entry); } if (entry.flags & KAFNORMAL) { entrys[i] |= 0x1; /* user entry */ if (strlen(entry.userID.name) == 0) { if (verbose) printf("Entry %d has zero length name\n", i); continue; } if (!DES_check_key_parity(ktc_to_cblock(&entry.key)) || DES_is_weak_key(ktc_to_cblock(&entry.key))) { fprintf(stderr, "Entry %d, %s, has bad key\n", i, EntryName(&entry)); continue; } if (out) { RebuildEntry(&entry); } } else if (entry.flags & KAFFREE) { entrys[i] |= 0x2; /* free entry */ } else if (entry.flags & KAFOLDKEYS) { entrys[i] |= 0x4; /* old keys block */ /* Should check the structure of the oldkeys block? */ } else { if (index < header.eofPtr) { fprintf(stderr, "Entry %d is unrecognizable\n", i); } } } /* Follow the hash chains */ for (j = 0; j < HASHSIZE; j++) { for (index = header.nameHash[j]; index; index = entry.next) { readDB(index, &entry, sizeof(entry)); /* check to see if the name is hashed correctly */ i = NameHash(&entry); if (i != j) { fprintf(stderr, "Entry %" AFS_SIZET_FMT ", %s, found in hash chain %d (should be %d)\n", ((index - sizeof(struct kaheader)) / sizeof(struct kaentry)), EntryName(&entry), j, i); } /* Is it on another hash chain or circular hash chain */ i = (index - header.headerSize) / sizeof(entry); if (entrys[i] & 0x10) { fprintf(stderr, "Entry %d, %s, hash index %d, was found on another hash chain\n", i, EntryName(&entry), j); if (entry.next) fprintf(stderr, "Skipping rest of hash chain %d\n", j); else fprintf(stderr, "No next entry in hash chain %d\n", j); code++; break; } entrys[i] |= 0x10; /* On hash chain */ } } /* Follow the free pointers */ count = 0; for (index = header.freePtr; index; index = entry.next) { readDB(index, &entry, sizeof(entry)); /* Is it on another chain or circular free chain */ i = (index - header.headerSize) / sizeof(entry); if (entrys[i] & 0x20) { fprintf(stderr, "Entry %d, %s, already found on free chain\n", i, EntryName(&entry)); fprintf(stderr, "Skipping rest of free chain\n"); code++; break; } entrys[i] |= 0x20; /* On free chain */ count++; } if (verbose) printf("Found %d free entries\n", count); /* Follow the oldkey blocks */ count = 0; for (index = header.kvnoPtr; index; index = entry.next) { readDB(index, &entry, sizeof(entry)); /* Is it on another chain or circular free chain */ i = (index - header.headerSize) / sizeof(entry); if (entrys[i] & 0x40) { fprintf(stderr, "Entry %d, %s, already found on olkeys chain\n", i, EntryName(&entry)); fprintf(stderr, "Skipping rest of oldkeys chain\n"); code++; break; } entrys[i] |= 0x40; /* On free chain */ count++; } if (verbose) printf("Found %d oldkey blocks\n", count); /* Now recheck all the blocks and see if they are allocated correctly * 0x1 --> User Entry 0x10 --> On hash chain * 0x2 --> Free Entry 0x20 --> On Free chain * 0x4 --> OldKeys Entry 0x40 --> On Oldkeys chain * 0x8 --> Past EOF */ for (i = 0; i < nentries; i++) { j = entrys[i]; if (j & 0x1) { /* user entry */ if (!(j & 0x10)) badEntry(j, i); /* on hash chain? */ else if (j & 0xee) badEntry(j, i); /* anything else? */ } else if (j & 0x2) { /* free entry */ if (!(j & 0x20)) badEntry(j, i); /* on free chain? */ else if (j & 0xdd) badEntry(j, i); /* anything else? */ } else if (j & 0x4) { /* oldkeys entry */ if (!(j & 0x40)) badEntry(j, i); /* on oldkeys chain? */ else if (j & 0xbb) badEntry(j, i); /* anything else? */ } else if (j & 0x8) { /* past eof */ if (j & 0xf7) badEntry(j, i); /* anything else? */ } else badEntry(j, i); /* anything else? */ } exit(code != 0); }