📄 invlib.c
字号:
/* check that room for the offset as well */ /* FIXME HBB: magic number alert (10) */ if ((numlogblk + 10) > supintsize) { i = supint - SUPINT; supintsize += SUPERINC; if ((SUPINT = realloc(SUPINT, supintsize * sizeof(long))) == NULL) { invcannotalloc(supintsize * sizeof(long)); return(0); } supint = i + SUPINT;#if DEBUG (void) printf("reallocated superfinger offset to %d, totpost = %ld\n", supintsize * sizeof(long), totpost);#endif } /* See if backup is efficatious */ backupflag = 0; maxback = (int) strlen(thisterm) / 10; holditems = numinvitems; if (maxback > numinvitems) maxback = numinvitems - 2; howfar = 0; while (--maxback > 0) { howfar++; iteminfo.packword[0] = logicalblk.invblk[--holditems * 2+(sizeof(long) - 1)]; if ((i = iteminfo.e.size / 10) < maxback) { maxback = i; backupflag = howfar; gooditems = holditems; tptr2 = logicalblk.chrblk + iteminfo.e.offset; } } /* see if backup will occur */ if (backupflag) { numinvitems = gooditems; } logicalblk.invblk[0] = numinvitems; /* set forward pointer pointing to next */ logicalblk.invblk[1] = numlogblk + 1; /* set back pointer to last block */ logicalblk.invblk[2] = numlogblk - 1; if (fwrite(logicalblk.chrblk, 1, sizeof(t_logicalblk), outfile) == 0) { invcannotwrite(indexfile); return(0); } amtused = 16; numlogblk++; /* check if had to back up, if so do it */ if (backupflag) { /* find out where the end of the new block is */ iteminfo.packword[0] = logicalblk.invblk[numinvitems*2+1]; tptr3 = logicalblk.chrblk + iteminfo.e.offset; /* move the index for this block */ for (i = 3; i <= (backupflag * 2 + 2); i++) logicalblk.invblk[i] = logicalblk.invblk[numinvitems*2+i]; /* move the word into the super index */ iteminfo.packword[0] = logicalblk.invblk[3]; iteminfo.packword[1] = logicalblk.invblk[4]; tptr2 = logicalblk.chrblk + iteminfo.e.offset; (void) strncpy(supfing, tptr2, (int) iteminfo.e.size); *(supfing + iteminfo.e.size) = '\0';#if DEBUG (void) printf("backup %d at term=%s to term=%s\n", backupflag, thisterm, supfing);#endif *supint++ = nextsupfing; nextsupfing += strlen(supfing) + 1; supfing += strlen(supfing) + 1; /* now fix up the logical block */ tptr = logicalblk.chrblk + lastinblk; lastinblk = sizeof(t_logicalblk); tptr2 = logicalblk.chrblk + lastinblk; j = tptr3 - tptr; while (tptr3 > tptr) *--tptr2 = *--tptr3; lastinblk -= j; amtused += (8 * backupflag + j); for (i = 3; i < (backupflag * 2 + 2); i += 2) { iteminfo.packword[0] = logicalblk.invblk[i]; iteminfo.e.offset += (tptr2 - tptr3); logicalblk.invblk[i] = iteminfo.packword[0]; } numinvitems = backupflag; } else { /* no backup needed */ numinvitems = 0; lastinblk = sizeof(t_logicalblk); /* add new term to superindex */ (void) strcpy(supfing, thisterm); supfing += strlen(thisterm) + 1; *supint++ = nextsupfing; nextsupfing += strlen(thisterm) + 1; } } /* HBB 20010501: Fixed bug by replacing magic number '8' by * what it actually represents. */ lastinblk -= (numwilluse - 2 * sizeof(long)); iteminfo.e.offset = lastinblk; iteminfo.e.size = len; iteminfo.e.space = 0; iteminfo.e.post = numpost; (void) strncpy(logicalblk.chrblk + lastinblk, thisterm, len); amtused += numwilluse; logicalblk.invblk[(lastinblk/sizeof(long))+wdlen] = nextpost; if ((i = postptr - POST) > 0) { if (fwrite(POST, sizeof(POSTING), i, fpost) == 0) { invcannotwrite(postingfile); return(0); } nextpost += i * sizeof(POSTING); } logicalblk.invblk[3+2*numinvitems++] = iteminfo.packword[0]; logicalblk.invblk[2+2*numinvitems] = iteminfo.packword[1]; return(1);}/* * If 'invname' ends with the 'from' substring, it is replaced inline with the * 'to' substring (which must be of the exact same length), and the function * returns 0. Otherwise, returns -1. */static int invflipname(char * invname, const char *from, const char *to){ char *temp, *i = NULL; assert(strlen(from) == strlen(to)); temp = invname - 1; while( (temp = strstr(temp + 1, from))) i = temp; if (!i || i[strlen(from)] != '\0') return -1; while(*to) *i++ = *to++; return 0;}intinvopen(INVCONTROL *invcntl, char *invname, char *invpost, int stat){ int read_index; if ((invcntl->invfile = vpfopen(invname, ((stat == 0) ? "rb" : "r+b"))) == NULL) { /* If db created without '-f', but now invoked with '-f cscope.out', * we need to check for 'cscope.in.out', rather than 'cscope.out.in': * I.e, hack around our own violation of the inverse db naming convention */ if (!invflipname(invname, INVNAME2, INVNAME)) { if ((invcntl->invfile = vpfopen(invname, ((stat == 0) ? "rb" : "r+b")))) goto openedinvname; invflipname(invname, INVNAME, INVNAME2); /* change back for err msg */ } /* more silliness: if you create the db with '-f cscope', then try to open * it without '-f cscope', you'll fail unless we check for 'cscope.out.in' * here. */ else if (!invflipname(invname, INVNAME, INVNAME2)) { if ((invcntl->invfile = vpfopen(invname, ((stat == 0) ? "rb" : "r+b")))) goto openedinvname; invflipname(invname, INVNAME2, INVNAME); /* change back for err msg */ } invcannotopen(invname); return(-1); }openedinvname: if (fread(&invcntl->param, sizeof(invcntl->param), 1, invcntl->invfile) == 0) { (void) fprintf(stderr, "%s: empty inverted file\n", argv0); goto closeinv; } if (invcntl->param.version != FMTVERSION) { (void) fprintf(stderr, "%s: cannot read old index format; use -U option to force database to rebuild\n", argv0); goto closeinv; } assert(invcntl->param.sizeblk == sizeof(t_logicalblk)); if (stat == 0 && invcntl->param.filestat == INVALONE) { (void) fprintf(stderr, "%s: inverted file is locked\n", argv0); goto closeinv; } if ((invcntl->postfile = vpfopen(invpost, ((stat == 0) ? "rb" : "r+b"))) == NULL) { /* exact same naming convention hacks as above for invname */ if (!invflipname(invpost, INVPOST2, INVPOST)) { if ((invcntl->postfile = vpfopen(invpost, ((stat == 0) ? "rb" : "r+b")))) goto openedinvpost; invflipname(invpost, INVPOST, INVPOST2); /* change back for err msg */ } else if (!invflipname(invpost, INVPOST, INVPOST2)) { if ((invcntl->postfile = vpfopen(invpost,((stat == 0)?"rb":"r+b")))) goto openedinvpost; invflipname(invpost, INVPOST2, INVPOST); /* change back for err msg */ } invcannotopen(invpost); goto closeinv; }openedinvpost: /* allocate core for a logical block */ if ((invcntl->logblk = malloc((unsigned) invcntl->param.sizeblk)) == NULL) { invcannotalloc((unsigned) invcntl->param.sizeblk); goto closeboth; } /* allocate for and read in superfinger */ read_index = 1; invcntl->iindex = NULL;#if SHARE if (invcntl->param.share == 1) { key_t shm_key; struct shmid_ds shm_buf; int shm_id; /* see if the shared segment exists */ shm_key = ftok(invname, 2); shm_id = shmget(shm_key, 0, 0); /* Failure simply means (hopefully) that segment doesn't exists */ if (shm_id == -1) { /* Have to give general write permission due to AMdahl not having protected segments */ shm_id = shmget(shm_key, invcntl->param.supsize + sizeof(long), IPC_CREAT | 0666); if (shm_id == -1) perror("Could not create shared memory segment"); } else read_index = 0; if (shm_id != -1) { invcntl->iindex = shmat(shm_id, 0, ((read_index) ? 0 : SHM_RDONLY)); if (invcntl->iindex == (char *)ERR) { (void) fprintf(stderr, "%s: shared memory link failed\n", argv0); invcntl->iindex = NULL; read_index = 1; } } }#endif if (invcntl->iindex == NULL) /* FIXME HBB: magic number alert (4) */ invcntl->iindex = malloc((unsigned) invcntl->param.supsize + 4 *sizeof(long)); if (invcntl->iindex == NULL) { invcannotalloc((unsigned) invcntl->param.supsize); free(invcntl->logblk); goto closeboth; } if (read_index) { (void) fseek(invcntl->invfile, invcntl->param.startbyte, 0); (void) fread(invcntl->iindex, (int) invcntl->param.supsize, 1, invcntl->invfile); } invcntl->numblk = -1; if (boolready() == -1) { closeboth: (void) fclose(invcntl->postfile); closeinv: (void) fclose(invcntl->invfile); return(-1); } /* write back out the control block if anything changed */ invcntl->param.filestat = stat; if (stat > invcntl->param.filestat ) { rewind(invcntl->invfile); (void) fwrite(&invcntl->param, sizeof(invcntl->param), 1, invcntl->invfile); } return(1);}/** invclose must be called to wrap things up and deallocate core **/voidinvclose(INVCONTROL *invcntl){ /* write out the control block in case anything changed */ if (invcntl->param.filestat > 0) { invcntl->param.filestat = 0; rewind(invcntl->invfile); (void) fwrite(&invcntl->param, 1, sizeof(invcntl->param), invcntl->invfile); } if (invcntl->param.filestat == INVALONE) { /* write out the super finger */ (void) fseek(invcntl->invfile, invcntl->param.startbyte, 0); (void) fwrite(invcntl->iindex, 1, (int) invcntl->param.supsize, invcntl->invfile); } (void) fclose(invcntl->invfile); (void) fclose(invcntl->postfile);#if SHARE if (invcntl->param.share > 0) { shmdt(invcntl->iindex); invcntl->iindex = NULL; }#endif if (invcntl->iindex != NULL) free(invcntl->iindex); free(invcntl->logblk);}/** invstep steps the inverted file forward one item **/static voidinvstep(INVCONTROL *invcntl){ if (invcntl->keypnt < (invcntl->logblk->invblk[0] - 1)) { invcntl->keypnt++; return; } /* move forward a block else wrap */ invcntl->numblk = invcntl->logblk->invblk[1]; /* was: *(int *)(invcntl->logblk + sizeof(long))*/ /* now read in the block */ (void) fseek(invcntl->invfile, invcntl->numblk * invcntl->param.sizeblk + invcntl->param.cntlsize, 0); (void) fread(invcntl->logblk, (int) invcntl->param.sizeblk, 1, invcntl->invfile); invcntl->keypnt = 0; }/** invforward moves forward one term in the inverted file **/intinvforward(INVCONTROL *invcntl){ invstep(invcntl); /* skip things with 0 postings */ /* FIXME HBB: magic number alert! (3) */ while (((ENTRY * )(invcntl->logblk->invblk + 3) + invcntl->keypnt)->post == 0) { invstep(invcntl); } /* Check for having wrapped - reached start of inverted file! */ if ((invcntl->numblk == 0) && (invcntl->keypnt == 0)) return(0); return(1);}/** invterm gets the present term from the present logical block **/longinvterm(INVCONTROL *invcntl, char *term){ ENTRY * entryptr; /* FIXME HBB: magic number alert! (3) */ entryptr = (ENTRY *)(invcntl->logblk->invblk + 3) + invcntl->keypnt; (void) strncpy(term, invcntl->logblk->chrblk + entryptr->offset, (int) entryptr->size); *(term + entryptr->size) = '\0'; return(entryptr->post);}/** invfind searches for an individual item in the inverted file **/longinvfind(INVCONTROL *invcntl, char *searchterm) /* term being searched for */{ int imid, ilow, ihigh; long num; int i; unsigned long *intptr, *intptr2; ENTRY *entryptr; /* make sure it is initialized via invready */ if (invcntl->invfile == 0) return(-1L); /* now search for the appropriate finger block */ intptr = (unsigned long *)invcntl->iindex; ilow = 0; ihigh = *intptr++ - 1; while (ilow <= ihigh) { imid = (ilow + ihigh) / 2; intptr2 = intptr + imid; i = strcmp(searchterm, (invcntl->iindex + *intptr2)); if (i < 0) ihigh = imid - 1; else if (i > 0) ilow = ++imid; else { ilow = imid + 1; break; } } /* be careful about case where searchterm is after last in this block */ imid = (ilow) ? ilow - 1 : 0; /* fetch the appropriate logical block if not in core */ /* note always fetch it if the file is busy */ if ((imid != invcntl->numblk) || (invcntl->param.filestat >= INVBUSY)) { (void) fseek(invcntl->invfile, (imid * invcntl->param.sizeblk) + invcntl->param.cntlsize, 0); invcntl->numblk = imid; (void) fread(invcntl->logblk, (int)invcntl->param.sizeblk, 1, invcntl->invfile); }srch_ext: /* now find the term in this block. tricky this */ intptr = (unsigned long *) invcntl->logblk->invblk; ilow = 0; ihigh = *intptr - 1; intptr += 3; num = 0; while (ilow <= ihigh) { imid = (ilow + ihigh) / 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -