📄 ssi.c
字号:
if (g->nprimary % SSI_KEY_BLOCK == 0) { g->pkeys = realloc(g->pkeys, sizeof(struct ssipkey_s) * (g->nprimary+SSI_KEY_BLOCK)); if (g->pkeys == NULL) return SSI_ERR_MALLOC; } return 0;}/* Function: SSIAddSecondaryKeyToIndex() * Date: SRE, Tue Jan 2 12:44:40 2001 [St. Louis] * * Purpose: Puts secondary key {key} in the index {g}, associating * it with primary key {pkey} that was previously * registered by SSIAddPrimaryKeyToIndex(). * * Args: g - active index * key - secondary key to add * pkey - primary key to associate this key with * * Returns: 0 on success, 1 on failure. */intSSIAddSecondaryKeyToIndex(SSIINDEX *g, char *key, char *pkey){ int n; /* a string length */ if (g->nsecondary >= SSI_MAXKEYS) return SSI_ERR_TOOMANY_KEYS; n = strlen(key); if ((n+1) > g->slen) g->slen = n+1; if ((g->skeys[g->nsecondary].key = sre_strdup(key, n)) == NULL) return SSI_ERR_MALLOC; if ((g->skeys[g->nsecondary].pkey = sre_strdup(pkey, -1)) == NULL) return SSI_ERR_MALLOC; g->nsecondary++; if (g->nsecondary % SSI_KEY_BLOCK == 0) { g->skeys = realloc(g->skeys, sizeof(struct ssiskey_s) * (g->nsecondary+SSI_KEY_BLOCK)); if (g->skeys == NULL) return SSI_ERR_MALLOC; } return 0;}/* Function: SSIWriteIndex() * Date: SRE, Tue Jan 2 13:55:56 2001 [St. Louis] * * Purpose: Writes complete index {g} in SSI format to a * binary file {file}. Does all * the overhead of sorting the primary and secondary keys, * and maintaining the association of secondary keys * with primary keys during and after the sort. * * Args: file - file to write to * g - index to sort & write out. * * Returns: 0 on success, nonzero on error. *//* needed for qsort() */static int pkeysort(const void *k1, const void *k2){ struct ssipkey_s *key1; struct ssipkey_s *key2; key1 = (struct ssipkey_s *) k1; key2 = (struct ssipkey_s *) k2; return strcmp(key1->key, key2->key);}static int skeysort(const void *k1, const void *k2){ struct ssiskey_s *key1; struct ssiskey_s *key2; key1 = (struct ssiskey_s *) k1; key2 = (struct ssiskey_s *) k2; return strcmp(key1->key, key2->key);}intSSIWriteIndex(char *file, SSIINDEX *g){ FILE *fp; int status; /* Case 1. Simple: the whole index fit in memory; write it to disk, * we're done. */ if (g->t1 == NULL) { if ((fp = fopen(file,"wb")) == NULL) return SSI_ERR_NOFILE; status = write_index(fp, g); fclose(fp); g->tot_primary = g->nprimary; g->tot_secondary = g->nsecondary; return status; } /* Case 2. Ugly: the index is big (and possibly *really* big, necessitating * 64-bit offsets in the index itself!); we had to write the index to a tmp * file on disk. Flush the last chunk to disk; then mergesort the chunks * until we have one chunk to rule them all, one chunk to bind them. */ write_index_chunk(g); /* flush the last chunk. */ fclose(g->t1); Die("oi, you haven't IMPLEMENTED the mergesort yet, dumbass."); return 0;}static int write_index(FILE *fp, SSIINDEX *g){ int i; sqd_uint32 header_flags, file_flags; sqd_uint32 frecsize, precsize, srecsize; sqd_uint64 foffset, poffset, soffset; char *s, *s2; /* Magic-looking numbers come from adding up sizes * of things in bytes */ frecsize = 16 + g->flen; precsize = (g->smode == SSI_OFFSET_I64) ? 22+g->plen : 14+g->plen; srecsize = g->slen + g->plen; header_flags = 0; if (g->smode == SSI_OFFSET_I64) header_flags |= SSI_USE64; if (g->imode == SSI_OFFSET_I64) header_flags |= SSI_USE64_INDEX; /* Magic-looking numbers again come from adding up sizes * of things in bytes */ foffset = (header_flags & SSI_USE64_INDEX) ? 66 : 54; poffset = foffset + frecsize*g->nfiles; soffset = poffset + precsize*g->nprimary; /* Sort the keys */ qsort((void *) g->pkeys, g->nprimary, sizeof(struct ssipkey_s), pkeysort); qsort((void *) g->skeys, g->nsecondary, sizeof(struct ssiskey_s), skeysort); /* Write the header */ if (! write_i32(fp, v20magic)) return SSI_ERR_FWRITE; if (! write_i32(fp, header_flags)) return SSI_ERR_FWRITE; if (! write_i16(fp, g->nfiles)) return SSI_ERR_FWRITE; if (! write_i32(fp, g->nprimary)) return SSI_ERR_FWRITE; if (! write_i32(fp, g->nsecondary)) return SSI_ERR_FWRITE; if (! write_i32(fp, g->flen)) return SSI_ERR_FWRITE; if (! write_i32(fp, g->plen)) return SSI_ERR_FWRITE; if (! write_i32(fp, g->slen)) return SSI_ERR_FWRITE; if (! write_i32(fp, frecsize)) return SSI_ERR_FWRITE; if (! write_i32(fp, precsize)) return SSI_ERR_FWRITE; if (! write_i32(fp, srecsize)) return SSI_ERR_FWRITE; if (g->imode == SSI_OFFSET_I32) { if (! write_i32(fp, foffset)) return SSI_ERR_FWRITE; if (! write_i32(fp, poffset)) return SSI_ERR_FWRITE; if (! write_i32(fp, soffset)) return SSI_ERR_FWRITE; } else { if (! write_i64(fp, foffset)) return SSI_ERR_FWRITE; if (! write_i64(fp, poffset)) return SSI_ERR_FWRITE; if (! write_i64(fp, soffset)) return SSI_ERR_FWRITE; } /* The file section */ if ((s = malloc(sizeof(char) * g->flen)) == NULL) return SSI_ERR_MALLOC; for (i = 0; i < g->nfiles; i++) { file_flags = 0; if (g->bpl[i] > 0 && g->rpl[i] > 0) file_flags |= SSI_FAST_SUBSEQ; strcpy(s, g->filenames[i]); if (fwrite(s, sizeof(char), g->flen, fp) != g->flen) return SSI_ERR_FWRITE; if (! write_i32(fp, g->fileformat[i])) return SSI_ERR_FWRITE; if (! write_i32(fp, file_flags)) return SSI_ERR_FWRITE; if (! write_i32(fp, g->bpl[i])) return SSI_ERR_FWRITE; if (! write_i32(fp, g->rpl[i])) return SSI_ERR_FWRITE; } free(s); /* The primary key section */ if ((s = malloc(sizeof(char) * g->plen)) == NULL) return SSI_ERR_MALLOC; for (i = 0; i < g->nprimary; i++) { strcpy(s, g->pkeys[i].key); if (fwrite(s, sizeof(char), g->plen, fp) != g->plen) return SSI_ERR_FWRITE; if (! write_i16( fp, g->pkeys[i].fnum)) return SSI_ERR_FWRITE; if (! write_offset(fp, &(g->pkeys[i].r_off))) return SSI_ERR_FWRITE; if (! write_offset(fp, &(g->pkeys[i].d_off))) return SSI_ERR_FWRITE; if (! write_i32( fp, g->pkeys[i].len)) return SSI_ERR_FWRITE; } /* The secondary key section */ if (g->nsecondary > 0) { if ((s2 = malloc(sizeof(char) * g->slen)) == NULL) return SSI_ERR_MALLOC; for (i = 0; i < g->nsecondary; i++) { strcpy(s2, g->skeys[i].key); strcpy(s, g->skeys[i].pkey); if (fwrite(s2, sizeof(char), g->slen, fp) != g->slen) return SSI_ERR_FWRITE; if (fwrite(s, sizeof(char), g->plen, fp) != g->plen) return SSI_ERR_FWRITE; } free(s2); } free(s); return 0;}static intwrite_index_chunk(SSIINDEX *g){ int status; int i; SQD_DPRINTF1(("Writing index chunk %d to disk... \n", g->nchunks)); /* Save the offset for each chunk in an array; remember how many * chunks we put into the tmp file t1. */ if (g->t1 == NULL) { char *t1file = NULL; if ((t1file = sre_strdup(g->tmpbase, -1)) == NULL) goto FAILURE; if (sre_strcat(&t1file, -1, ".t1", 3) < 0) goto FAILURE; if ((g->t1 = fopen(t1file, "wb")) == NULL) return SSI_ERR_NOFILE; free(t1file); if ((g->chunkoffset = malloc(sizeof(fpos_t))) == NULL) goto FAILURE; } else { if ((g->chunkoffset = realloc(g->chunkoffset, sizeof(fpos_t) * (g->nchunks+1))) == NULL) goto FAILURE; } if (fgetpos(g->t1, &(g->chunkoffset[g->nchunks])) != 0) Die("Index file size has apparently exceeded system limitations, sorry."); g->nchunks++; /* Sort and append this chunk of the index to the open tmp file t1 */ if ((status = write_index(g->t1, g)) != 0) return status; g->tot_primary += g->nprimary; g->tot_secondary += g->nsecondary; /* Now, a partial free'ing of the index - clear the keys, but leave the files */ for (i = 0; i < g->nprimary; i++) free(g->pkeys[i].key); for (i = 0; i < g->nsecondary; i++) free(g->skeys[i].key); for (i = 0; i < g->nsecondary; i++) free(g->skeys[i].pkey); free(g->pkeys); free(g->skeys); /* Reset the primary and secondary keys sections, in preparation * for accumulating more */ g->pkeys = NULL; g->plen = 0; g->nprimary = 0; g->skeys = NULL; g->slen = 0; g->nsecondary = 0; if ((g->pkeys = malloc(sizeof(struct ssipkey_s)* SSI_KEY_BLOCK))== NULL) goto FAILURE; if ((g->skeys = malloc(sizeof(struct ssipkey_s)* SSI_KEY_BLOCK))== NULL) goto FAILURE; return 0; FAILURE: SSIFreeIndex(g); return SSI_ERR_MALLOC;} /* Function: SSIFreeIndex() * Date: SRE, Tue Jan 2 11:44:08 2001 [St. Louis] * * Purpose: Free an index structure {g}. * * Args: g - ptr to an open index. * * Returns: (void) */voidSSIFreeIndex(SSIINDEX *g) { int i; if (g != NULL) { for (i = 0; i < g->nfiles; i++) free(g->filenames[i]); for (i = 0; i < g->nprimary; i++) free(g->pkeys[i].key); for (i = 0; i < g->nsecondary; i++) free(g->skeys[i].key); for (i = 0; i < g->nsecondary; i++) free(g->skeys[i].pkey); if (g->filenames != NULL) free(g->filenames); if (g->fileformat != NULL) free(g->fileformat); if (g->bpl != NULL) free(g->bpl); if (g->rpl != NULL) free(g->rpl); if (g->pkeys != NULL) free(g->pkeys); if (g->skeys != NULL) free(g->skeys); if (g->tmpbase != NULL) free(g->tmpbase); if (g->chunkoffset != NULL) free(g->chunkoffset); if (g->t1 != NULL) fclose(g->t1); free(g); }}/* Function: SSIErrorString() * Date: SRE, Tue Jan 2 10:38:10 2001 [St. Louis] * * Purpose: Returns a ptr to an internal string corresponding * to error {n}, a code returned from any of the * functions in the API that return non-zero on error. * * Args: n - error code * * Returns: ptr to an internal string. */char *SSIErrorString(int n){ switch (n) { case SSI_ERR_OK: return "ok (no error)"; case SSI_ERR_NODATA: return "no data, fread() failed"; case SSI_ERR_NO_SUCH_KEY: return "no such key"; case SSI_ERR_MALLOC: return "out of memory, malloc() failed"; case SSI_ERR_NOFILE: return "file not found, fopen() failed"; case SSI_ERR_BADMAGIC: return "not a SSI file? (bad magic)"; case SSI_ERR_BADFORMAT: return "corrupt format? unexpected data"; case SSI_ERR_NO64BIT: return "no large file support for this system"; case SSI_ERR_SEEK_FAILED: return "failed to reposition on disk"; case SSI_ERR_TELL_FAILED: return "failed to get file position on disk"; case SSI_ERR_NO_SUBSEQS: return "no fast subseq support for this seqfile"; case SSI_ERR_RANGE: return "subseq start is out of range"; case SSI_ERR_BADARG: return "an argument is out of range"; default: return "unrecognized code"; } /*NOTREACHED*/}static intread_i16(FILE *fp, sqd_uint16 *ret_result){ sqd_uint16 result; if (fread(&result, sizeof(sqd_uint16), 1, fp) != 1) return 0; *ret_result = sre_ntoh16(result); return 1;}static intwrite_i16(FILE *fp, sqd_uint16 n){ n = sre_hton16(n); if (fwrite(&n, sizeof(sqd_uint16), 1, fp) != 1) return 0; return 1;}static intread_i32(FILE *fp, sqd_uint32 *ret_result){ sqd_uint32 result; if (fread(&result, sizeof(sqd_uint32), 1, fp) != 1) return 0; *ret_result = sre_ntoh32(result); return 1;}static intwrite_i32(FILE *fp, sqd_uint32 n){ n = sre_hton32(n); if (fwrite(&n, sizeof(sqd_uint32), 1, fp) != 1) return 0; return 1;}static intread_i64(FILE *fp, sqd_uint64 *ret_result){ sqd_uint64 result; if (fread(&result, sizeof(sqd_uint64), 1, fp) != 1) return 0; *ret_result = sre_ntoh64(result); return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -