IMD 1.17: 19/01/2010 21:21:10 node file check programs 3-24-87 node file check programs, 3-24-87 O UniFLEX BackupAX_BLOCK_GROUP_SIZE (BLOCK_SIZE * MAX_NUM_BLOCKS) #define ADDR_SIZE 4 #define GUTS_SIZE (BLOCK_SIZE - ADDR_SIZE) #define MAX_AVAIL_BYTES (MAX_BLOCK_GROUP_SIZE - ADDR_SIZE) #define COUNT_MASK (BLOCK_SIZE - 1) #define ADDR_MASK (-BLOCK_SIZE) #define packAddrCount(x, y) (((x) - HEADER_SIZE) | ((y) - 1)) #define extractCount(x) (((x) & COUNT_MASK) + 1) #define extractAddr(x) (((x) & ADDR_MASK) + HEADER_SIZE) #define bytesAvail(x) ((x) * BLOCK_SIZE - ADDR_SIZE) #define numBlocksNeede jTektronix 44002  !"#$%&'()*+,-./01234('&%$#"! d(x) ((((x) + ADDR_SIZE - 1) / BLOCK_SIZE) + 1) static nodeFile(nodeIndex) /* returns the index of the file that contains contents of `nodeIndex' */ int nodeIndex; { return nodeIndex / NUM_NODES; } openNodeFile(nodeIndex) /* returns a fileDescriptor for file that contains contents of `nodeIndex' */ int nodeIndex; { char name[50]; int f, key, m; struct headPtrs ptrs; key = nodeFile(nodeIndex); /* first check cache of open node files */ computeNodePath(key, name); if (access(nam)  ) ,(nodeCheck.c.ʌSҀ ҔҜ-z lR>8node file chBc"e, F_OK) != 0) { /* does not exist yet, create it */ if (checkPath(key, name) == -1) return -1; #ifdef mag if ((f = open(name, O_CREAT|O_TRUNC|O_RDWR, 0666)) < 0) return -1; #else if ((f = creat(name, 27)) < 0) return -1; /* close and open again to establish read/write access */ close(f); if ((f = open(name, 2)) < 0) return -1; #endif ptrs.firstFree = -1; ptrs.lastFree = -1; ptrs.fileEnd = -1; if (write(f, &ptrs, sizeof(ptrs)) != sizeof(ptrs)) return 0; } else { #ifdef mag if ((f = #include #include #include #include #include "machine.h" #include "directory.h" int thisHostId; struct graphContext project; FILE *trace; extern char *ctime(); #define NUM_NODES 512 typedef struct headPtrs { int firstFree; int lastFree; int fileEnd; } HEADER; #define HEADER_SIZE sizeof(HEADER) /* BLOCK_SIZE must be a power of 2, MAX_NUM_BLOCKS must be <= BLOCK_SIZE */ #define BLOCK_SIZE 128 #define MAX_NUM_BLOCKS 32 #define Mopen(name, O_RDWR, 0)) < 0) return -1; #else if ((f = open(name, 2)) < 0) return -1; #endif } return f; } /**************************************************************/ static computeNodePath(nodeFile, p) int nodeFile; char *p; /* nodes are stored in unix sub-directories within the directory storing the node's context. This routine computes a string that is a path name, relative to the context directory for a node. Here, we store 64 nodeFiles and 64 node sub-directories per unix sub-directory. */ { int i, j, c, set, t; char s[4]; c = 0; set = 0; i = nodeFile; for (j = 0; j < 4; j++) { t = (i >> 24) & 0x3F; set |= (t != 0); if (set) { p[c++] = 'd'; sprintf(s, "%d", t); p[c] = 0; strcat(p, s); c += strlen(s); p[c++] = '/'; } i = i << 6; /* shift next 6 bits */ } p[c++] = 'n'; p[c] = 0; sprintf(s, "%d", nodeFile % 64); strcat(p, s); } static checkPath(m, n) /* make sure we can access path `n' which is for nodeFile `m' */ int m; char *n; { intfprintf(stderr, "error seeking to %x\n", endAddr); break; } if (read(fd, &next, 4) != 4) { fprintf(stderr, "error reading at %x\n", endAddr); break; } } fprintf(stderr, "\nchecking nodes: "); for (c = 1; c <= numNodes; c++) { fprintf(stderr, "."); lseek(f, sizeof(fh) + (c - 1) * sizeof(ne), L_SET); read(f, &ne, sizeof(ne)); thisNode = 0; next = ne.start; while (next != -1) { start = extractAddr(next); count = extractCount(next); for (i = 0; i < count; i++) { n  l; if (m < 64) return 1; /* first 63 are in context's directory */ /* make directory name by truncating file name */ l = strlen(n) - 3; /* index of last `/' char */ n[l] = 0; if (access(n, F_OK) != 0) #ifdef mag if (mkdir(n, 0777) != 0) return -1; #else {char command[100]; strcpy(command, "crdir "); strcat(command, n); system(command); } #endif n[l] = '/'; /* fix n */ } main(argc, argv) int argc; char *argv[]; { int c, i, f; struct fileHeader fh; struct nodeEntry ne; struct head= start + (BLOCK_SIZE * i); if (isNodeChecked(n)) fprintf(stderr, "\n*** multiply used block: %d", n); else addNodeToMap(n, 1, 1); numUsed += 1; } thisNode += 1; numClusters += 1; endAddr = start + bytesAvail(count); if (lseek(fd, endAddr, L_SET) == -1) { fprintf(stderr, "error seeking to %x\n", endAddr); break; } if (read(fd, &next, 4) != 4) { fprintf(stderr, "error reading at %x\n", endAddr); break; } } if (thisNode > maxPerNode) maxPPtrs ptrs; int fd; int n, numNodes, start, count, endAddr, next; int numUsed, numEmpty; int maxPerNode, thisNode; int numClusters; struct stat statBuf; initializeMap(); numEmpty = 0; numUsed = 0; maxPerNode = 0; numClusters = 0; f = open("hm", O_RDONLY, 0); read(f, &fh, sizeof(fh)); numNodes = fh.size; fd = openNodeFile(1); fstat(fd, &statBuf); fprintf(stderr, "checking free blocks: "); if (lseek(fd, 0, L_SET) == -1) fprintf(stderr, "error seeking to headPtrs\n"); if (read(fd, &ptrs, sizerNode = thisNode; } fprintf(stderr, "\nnumUsed = %d, numEmpty = %d\n", numUsed, numEmpty); fprintf(stderr, "total allocated = %d\n", statBuf.st_size / BLOCK_SIZE); fprintf(stderr, "maxPerNode = %d, avgCount = %f\n", maxPerNode, ((numUsed + numEmpty) / (float ) numClusters)); } /************************************************************************/ /* operations that support the bit map */ /************************************************************************/ /* the bitMap is a data structeof(ptrs)) != sizeof(ptrs)) fprintf(stderr, "error reading headPtrs\n"); next = ptrs.firstFree; while (next != -1) { start = extractAddr(next); count = extractCount(next); for (i = 0; i < count; i++) { n = start + (BLOCK_SIZE * i); if (isNodeChecked(n)) fprintf(stderr, "\n*** multiply used block: %d", n); else addNodeToMap(n, 1, 0); numEmpty += 1; } fprintf(stderr, "."); numClusters += 1; endAddr = start + bytesAvail(count); if (lseek(fd, endAddr, L_SET) == -1) { ure used to build a list of nodes or links. This data structure requires rapid access indexed by an entityIndex, is probably sparse, and could be very large. The internal representation chosen here for the entityMap is an ordered binary tree of bitmaps. Note: only one instance of this bit map exists in a HAM precess. Be sure to `initializeMap' before each use. */ #define BUFSIZE 124 #define MAPSIZE (BUFSIZE*32) static struct nmap { int firstNode; int checked[BUFSIZE]; int passed[BUFSIZE]; struct nmap *lesser; struct nmap *greater; } nMapSample; static struct nmap *mapRoot = (struct nmap *) -1; static int maskTable[32]; initializeMap() { int i; disposeMapR(mapRoot); mapRoot = (struct nmap *) -1; maskTable[0] = 1; for (i = 1; i < 32; i++) maskTable[i] = maskTable[i - 1] * 2; } #define mask(i) (maskTable[(i)]) addNodeToMap(index, checked, passed) /* adds the entity `index' to the bitMap with state `checked'/`passed' */ int index, checked, passed; { int r, nt index; { int element, bit; struct nmap *m; if ((m = findNode(index)) == (struct nmap *)-1) return 0; else { element = (index % MAPSIZE) >> 5; bit = mask(index % 32); return (m->checked[element] & bit) != 0; } } isNodePassed(index) /* return passed state of entity `index' */ int index; { int element, bit; struct nmap *m; if ((m = findNode(index)) == (struct nmap *)-1) return 0; else { element = (index % MAPSIZE) >> 5; bit = mask(index % 32); return (m->passed[element] & bit) != 0; } } pi, element, bit; struct nmap *p, *m; /* traverse map-tree to find the chunk that should contain `index' */ p = (struct nmap *) -1; m = mapRoot; while (m != (struct nmap *)-1) { r = m->firstNode; if ((r <= index) && (index <= r + MAPSIZE)) { element = (index % MAPSIZE) >> 5; bit = mask(index % 32); if (checked) m->checked[element] |= bit; if (passed) m->passed[element] |= bit; return; } else { p = m; if (r < index) m = m->greater; else m = m->lesser; } } /* chunkrintBitMap(output) /* for debugging, prints the map tree on file `output' */ FILE *output; { printBitMapR(mapRoot, output); } static printBitMapR(root, output) /* recursively does the work of printBitMap */ struct nmap *root; FILE *output; { int b, i, j, r, index; /* inorder traversal of map tree */ if (root != (struct nmap *)-1) { printBitMapR(root->lesser, output); /* visit lesser */ r = root->firstNode; fprintf(output, "\nfirst = %d: \npassed: ", r); for (i = 0; i < BUFSIZE; i++) { for `index' not in tree, need to make a new tree node */ m = (struct nmap *)malloc(sizeof(nMapSample)); for (i = 0; i < BUFSIZE; i++) m->passed[i] = 0; for (i = 0; i < BUFSIZE; i++) m->checked[i] = 0; m->firstNode = (index / MAPSIZE) * MAPSIZE; element = (index % MAPSIZE) >> 5; bit = mask(index % 32); if (checked) m->checked[element] = bit; if (passed) m->passed[element] = bit; m->lesser = (struct nmap *) -1; m->greater = (struct nmap *) -1; if (p != (struct nmap *)-1) { if (p->firstNode < in b = root->passed[i]; fprintf(output,"(%x)", b); for (j = 0; j < 32; j++) { if (b & 1) fprintf(output,"%d,", r + i * 32 + j); b = b >> 1; } } fprintf(output, "\nchecked: "); for (i = 0; i < BUFSIZE; i++) { b = root->checked[i]; fprintf(output,"(%x)", b); for (j = 0; j < 32; j++) { if (b & 1) fprintf(output,"%d,", r + i * 32 + j); b = b >> 1; } } printBitMapR(root->greater, output); /* visit greater */ } } disposeMap() /* frees the strorage spacdex) p->greater = m; else p->lesser = m; } else mapRoot = m; } static struct nmap *findNode(index) /* traverse map-tree to find the chunk that should contain `index' */ int index; { int r; struct nmap *m; m = mapRoot; while (m != (struct nmap *)-1) { r = m->firstNode; if ((r <= index) && (index <= r + MAPSIZE)) return m; else if (r < index) m = m->greater; else m = m->lesser; } return (struct nmap *)-1; } isNodeChecked(index) /* return checked state of entity `index' */ ie used by the map tree */ { disposeMapR(mapRoot); mapRoot = (struct nmap *) -1; } static disposeMapR(r) /* recursively does the work for disposeMap */ struct nmap *r; { if (r != (struct nmap *)-1) { disposeMapR(r->lesser); disposeMapR(r->greater); free(r); } } one instance of this bit map exists in a HAM precess. Be sure to `initializeMap' before each use. */ #define BUFSIZE 124 #define MAPSIZE (BUFSIZE*32) static struct nmap { int firstNode; int checked[BUFSIZE]; int passed[BUFSE   ( nodeContents.c.ʌSҀ ҔҜ-z-z lR>8node file chBc"e, F_OK) != 0) { /* does not exist yet, create it */ if (checkPath(key, name) == -1) return -1; #ifdef mag if ((f = open(name, O_CREAT|O_TRUNC|O_RDWR, 0666)) < 0) return -1; #else if ((f = creat(name, 27)) < 0) return -1; /* close and open again to establish read/write access */ close(f); if ((f = open(name, 2)) < 0) return -1; #endif ptrs.firstFree = -1; ptrs.lastFree = -1; ptrs.fileEnd = -1; if (write(f, &ptrs, sizeof(ptrs)) != sizeof(ptrs)) return 0; } else { #ifdef mag if ((f = #include #include #include #include #include "machine.h" #include "directory.h" int thisHostId; struct graphContext project; FILE *trace; extern char *ctime(); #define NUM_NODES 512 typedef struct headPtrs { int firstFree; int lastFree; int fileEnd; } HEADER; #define HEADER_SIZE sizeof(HEADER) /* BLOCK_SIZE must be a power of 2, MAX_NUM_BLOCKS must be <= BLOCK_SIZE */ #define BLOCK_SIZE 128 #define MAX_NUM_BLOCKS 32 #define Mopen(name, O_RDWR, 0)) < 0) return -1; #else if ((f = open(name, 2)) < 0) return -1; #endif } return f; } /**************************************************************/ static computeNodePath(nodeFile, p) int nodeFile; char *p; /* nodes are stored in unix sub-directories within the directory storing the node's context. This routine computes a string that is a path name, relative to the context directory for a node. Here, we store 64 nodeFiles and 64 node sub-directories per unix sub-direAX_BLOCK_GROUP_SIZE (BLOCK_SIZE * MAX_NUM_BLOCKS) #define ADDR_SIZE 4 #define GUTS_SIZE (BLOCK_SIZE - ADDR_SIZE) #define MAX_AVAIL_BYTES (MAX_BLOCK_GROUP_SIZE - ADDR_SIZE) #define COUNT_MASK (BLOCK_SIZE - 1) #define ADDR_MASK (-BLOCK_SIZE) #define packAddrCount(x, y) (((x) - HEADER_SIZE) | ((y) - 1)) #define extractCount(x) (((x) & COUNT_MASK) + 1) #define extractAddr(x) (((x) & ADDR_MASK) + HEADER_SIZE) #define bytesAvail(x) ((x) * BLOCK_SIZE - ADDR_SIZE) #define numBlocksNeedectory. */ { int i, j, c, set, t; char s[4]; c = 0; set = 0; i = nodeFile; for (j = 0; j < 4; j++) { t = (i >> 24) & 0x3F; set |= (t != 0); if (set) { p[c++] = 'd'; sprintf(s, "%d", t); p[c] = 0; strcat(p, s); c += strlen(s); p[c++] = '/'; } i = i << 6; /* shift next 6 bits */ } p[c++] = 'n'; p[c] = 0; sprintf(s, "%d", nodeFile % 64); strcat(p, s); } static checkPath(m, n) /* make sure we can access path `n' which is for nodeFile `m' */ int m; char *n; { intd(x) ((((x) + ADDR_SIZE - 1) / BLOCK_SIZE) + 1) static nodeFile(nodeIndex) /* returns the index of the file that contains contents of `nodeIndex' */ int nodeIndex; { return nodeIndex / NUM_NODES; } openNodeFile(nodeIndex) /* returns a fileDescriptor for file that contains contents of `nodeIndex' */ int nodeIndex; { char name[50]; int f, key, m; struct headPtrs ptrs; key = nodeFile(nodeIndex); /* first check cache of open node files */ computeNodePath(key, name); if (access(nam l; if (m < 64) return 1; /* first 63 are in context's directory */ /* make directory name by truncating file name */ l = strlen(n) - 3; /* index of last `/' char */ n[l] = 0; if (access(n, F_OK) != 0) #ifdef mag if (mkdir(n, 0777) != 0) return -1; #else {char command[100]; strcpy(command, "crdir "); strcat(command, n); system(command); } #endif n[l] = '/'; /* fix n */ } main(argc, argv) int argc; char *argv[]; { int c, i, f; struct fileHeader fh; struct nodeEntry ne; struct headPtrs ptrs; int fd; int start, count, endAddr, next; f = open("hm", O_RDONLY, 0); read(f, &fh, sizeof(fh)); printf("command: "); scanf("%d", &c); while (c != -1) { if (c == 0) { /* format file header */ printf("size: %d, nextEmpty: %d\n", fh.size, fh.nextEmpty); fd = openNodeFile(1); if (lseek(fd, 0, L_SET) == -1) printf("error seeking to headPtrs\n"); if (read(fd, &ptrs, sizeof(ptrs)) != sizeof(ptrs)) printf("error reading headPtrs\n"); printf("fileEnd: %x\n", ptrs.fileEnd); n; printf(" addr: %x, count: %d\n", start,count); endAddr = start + bytesAvail(count); if (lseek(fd, endAddr, L_SET) == -1) { printf("error seeking to %x\n", endAddr); break; } if (read(fd, &next, 4) != 4) { printf("error reading at %x\n", endAddr); break; } } } else printf("no such node\n"); printf("command: "); scanf("%d", &c); } } Free = -1; ptrs.fileEnd = -1; if (write(f, &ptrs, sizeof(ptrs)) != sizeof(ptrs)) return 0; } else { #ifdef mag if ((f = ext = ptrs.firstFree; printf("checking free blocks .... "); printf("addr: %x, count: %d\n", extractAddr(ptrs.firstFree),extractCount(ptrs.firstFree)); while (next != -1) { start = extractAddr(next); count = extractCount(next); printf(" addr: %x, count: %d\n", start,count); endAddr = start + bytesAvail(count); if (lseek(fd, endAddr, L_SET) == -1) { printf("error seeking to %x\n", endAddr); break; } if (read(fd, &next, 4) != 4) { printf("error reading at %x\n", endA#F" DbeR E   ( nodeContents.c.deContents.cnodeContents.cddr); break; } } next = ptrs.lastFree; printf("checking last free blocks .... "); printf("addr: %x, count: %d\n", extractAddr(ptrs.lastFree),extractCount(ptrs.lastFree)); while (next != -1) { start = extractAddr(next); count = extractCount(next); printf(" addr: %x, count: %d\n", start,count); endAddr = start + bytesAvail(count); if (lseek(fd, endAddr, L_SET) == -1) { printf("error seeking to %x\n", endAddr); break; } if (read(fd, &next, 4) != 4) { printf("error reading at %x\n", endAddr); break; } } } else if (c <= fh.size) { /* format node entry */ printf("node entry %d\n", c); lseek(f, sizeof(fh) + (c - 1) * sizeof(ne), L_SET); read(f, &ne, sizeof(ne)); fd = openNodeFile(c); next = ne.start; printf("checking content blocks .... "); printf("addr: %x, count: %d, length: %d\n", extractAddr(ne.start),extractCount(ne.start),ne.length); while (next != -1) { start = extractAddr(next); count = extractCount(next)~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)          TSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$#"!      ~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVU       !!~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$#"! ""##$$%%&&''