#ident "$URL: svn://elmer/devel/SVN/SDDAS/trunk/libdB/CreateNdx.c $ %D% SwRI" #include #include #include #include #include #include #include #include #include #include "dbf.h" /********************* ** >FILE: CreateNdx.c *********************/ /******************************************************************** ** Function: int CreateNdx(int dbf, char *fname, va_list, int *ndx, int silent) ** ** int dbf database structure ** char *fn file name of the index file to create ** va_alist variable list of key fields to index ** silent whether or not we want output ** ** Description: ** Call this procedure with the full pathname of the index file that you ** want to create (fn), the number of fields in a record (n), and a pointer ** to an array of FieldRecord_t (flds). The procedure will initialize all ** the data structures in the dbfRecord (D). ** ** Return Values: ** ***************** *****************/ #define INDEX_INC 50 dbRet_t CreateNdx(SDDAS_INT dbf, char *fn, FieldRecord_t *FieldNames[], SDDAS_INT NumFields, SDDAS_INT *ndx, int silent) { dbfRecord_t *D; ndxRecord_t *N; char *cptr, iHeader[96]; SDDAS_INT i, j, k, nbytes, size; FieldRecord_t *field; dbRet_t rval; if ((D = GetOldDbfHandle(dbf)) == NULL) return FAILURE; if ((N = GetNewNdxHandle(dbf, ndx)) == NULL) return FAILURE; /* | initialize the header information */ memset(iHeader, 0, sizeof(iHeader)); /* | store the number of fields in the key into the database structure, | and allocate memory for the indexed fields */ N->NumIndexFields = NumFields; if ((N->IndexFields = (FieldRecord_t *)calloc(NumFields, sizeof(FieldRecord_t))) == NULL) { dbf_code = errno; dbf_msg_clr; return FAILURE; } /* | set the number of index fields in the header info */ *((SDDAS_INT *)&iHeader[sizeof (SDDAS_INT) * 3]) = N->NumIndexFields; /* | set the index fields */ cptr = &iHeader[sizeof (SDDAS_INT) * 4]; N->KeyLen = 0; nbytes = 0; for (i=0; iName)) == NULL) { return FAILURE; } N->IndexFields[i] = *field; *((FieldRecord_t *)cptr) = *(N->IndexFields+i); *(cptr+15) = '\0'; cptr += 16; N->KeyLen += N->IndexFields[i].Len; } /* | allocate the needed memory for the index */ nbytes += N->KeyLen + DB_ALIGN(N->KeyLen) + sizeof(SDDAS_INT); N->MAXIndexRecs = ((D->NumRecs / INDEX_INC) * INDEX_INC) + INDEX_INC; if ((N->Index = calloc(N->MAXIndexRecs, nbytes)) == NULL) { dbf_code = errno; dbf_msg_clr; return FAILURE; } /* | read the records from the database file to generate the index file */ cptr = N->Index; N->NextFreeIndexRec = 0; for (i=1; i<=D->NumRecs; i++) { if ((rval = GetDbfRecord(dbf, i)) != SUCCESS) { return rval; } if (D->CurRecord[0][0] == '*') continue; for (k=0; kNumIndexFields; k++) { for (j=0; jIndexFields[k].Len; j++) { char c; c = (char )N->IndexFields[k].Parm[j]; /**** if (N->IndexFields[k].Typ == NUMERIC && c == ' ') c = '0'; ***/ *(cptr++) = c; } } cptr += DB_ALIGN(N->KeyLen); *((SDDAS_INT *)cptr) = i; cptr += sizeof(SDDAS_INT); N->NextFreeIndexRec++; if (!silent) PercentDone(i, D->NumRecs); } if (!silent) { PercentDone(1, 1); fprintf(stderr, "\n"); } /* | preform the index */ size = N->KeyLen + DB_ALIGN(N->KeyLen) + sizeof(SDDAS_INT); db_Qsort(N->Index, D->NumRecs, size, N->KeyLen); *((SDDAS_INT *)&iHeader[sizeof (SDDAS_INT)]) = N->NextFreeIndexRec; *((SDDAS_INT *)&iHeader[sizeof (SDDAS_INT) * 2]) = N->MAXIndexRecs; /* | open the index file and write out the header and index array */ (void)strcpy((char *)N->IndexName, fn); N->iStatus = Updated; N->IndexRec = 1; GoTo(dbf, ItoR(N, 1)); return SUCCESS; }