bool SstGlobalTypes::LoadTypes( Retriever& retriever, const module mod ) /**********************************************************************/ { char* buffer; unsigned_32 length; if ( ! retriever.ReadSubsection(buffer,length,sstTypes,mod) ) { return FALSE; } char* end = &buffer[length]; if ( * (unsigned_32 *) buffer != CV4_HEADER ) { ::Warning("invalid header dectected in types."); } // skip the header. buffer += LONG_WORD; // if it is the first module, just load the types into the global // table without packing. if ( mod == 1 ) { while ( buffer < end ) { _globalTypingInfo.Insert( new LFGlobalTypeRecord(ToTypeIndex(_globalTypingInfo.Entries()),buffer)); buffer += WORD + * (unsigned_16 *) buffer; } TypeMap.Set( CV_FIRST_NONPRIM + _globalTypingInfo.Entries() ); return TRUE; } else { while ( buffer < end ) { _localTypingInfo.Insert( new LFLocalTypeRecord(ToTypeIndex(_localTypingInfo.Entries()),buffer)); buffer += WORD + * (unsigned_16 *) buffer; } TypeMap.Reset(_localTypingInfo.Entries()); } uint oldCount = _globalTypingInfo.Entries(); // Full type packing is not implemented due to its long running time // when input is relatively big. Here only packs records that can be // hashed, these records are structs, unions, enums, class. And they // will likely reference a lot of other records, so partial packing // is not that bad after all. WCPtrSListIter<LFTypeRecord> iter(_localTypingInfo._hashRecords); while ( ++iter ) { if ( ! TypeMap.IsDone( iter.current() -> TypeIndex() ) ) { ProcessTypes( iter.current() ); } } // Anything that is left will be inserted as a new type into the global // table. iter.reset(_localTypingInfo._otherRecords); while ( ++iter ) { if ( ! TypeMap.IsDone( iter.current() -> TypeIndex() ) ) { InsertNewType( iter.current() ); } } FixUpTypes(ToTypeIndex(oldCount)); // Selectively destruct the types in the local table. If the type is // a new type, then only release the memory of a bare LFLocalTypeRecord. // Otherwise, release the memory of a bare record plus the pointer to // LFLeafStruct. This is bad style, but can boost performance by not // having to create a constructor and do a pointer copy only when // transfer types from the local table to the global table. See the // LFGlobalTypeRecord declaration for more details. for ( uint i = CV_FIRST_NONPRIM; i < ToTypeIndex(_localTypingInfo.Entries()); i++ ) { if ( ! TypeMap.IsNewType(i) ) { // If not a new type, release pointer memory as well. _localTypingInfo[i]->ManualDestruct(); } // release bare LFLocalTypeRecord memory. /* if (_localTypingInfo[i]) { delete _localTypingInfo[i]; _localTypingInfo[i]=NULL; } */ } _localTypingInfo.Clear(); return TRUE; }
/* * Routine: ProcessSet * Purpose: Read distribution settings * Algorithm: * Data Structures: * * Params: * Returns: * Called By: * Calls: * Assumptions: * Side Effects: * TODO: None * * NOTE: if QERR_SYNTAX can be a valid return value, we have a problem. */ int ProcessSet (char *stmt, token_t * tokens) { int nRetCode = 0, i; char *cp = NULL; cp = SafeStrtok (NULL, " \t="); switch (i = FindToken (cp)) { case TKN_WEIGHTS: cp = SafeStrtok (NULL, " \t"); /* discard = */ pCurrentIndexEntry->w_width = ProcessInt (stmt, tokens); if (pCurrentIndexEntry->w_width == QERR_SYNTAX) nRetCode = QERR_RANGE_ERROR; else { if (pCurrentIndexEntry->w_width > nMaxWeightWidth) { arWeights = (int *) REALLOC (arWeights, pCurrentIndexEntry->w_width * sizeof (int)); if (arWeights == NULL) nRetCode = QERR_NO_MEMORY; } else nMaxWeightWidth = pCurrentIndexEntry->w_width; } pCurrentIndexEntry->dist->weight_sets = (int **) MALLOC (pCurrentIndexEntry->w_width * sizeof (int *)); if (pCurrentIndexEntry->dist->weight_sets == NULL) nRetCode = QERR_NO_MEMORY; memset(pCurrentIndexEntry->dist->weight_sets, 0, pCurrentIndexEntry->w_width * sizeof(int *)); break; case TKN_TYPES: pCurrentIndexEntry->v_width = ProcessTypes (stmt, tokens); if (pCurrentIndexEntry->v_width == QERR_SYNTAX) nRetCode = QERR_RANGE_ERROR; else { if (pCurrentIndexEntry->v_width > nMaxValueWidth) { arValues = (char **) REALLOC (arValues, pCurrentIndexEntry->v_width * sizeof (char *)); arValueLengths = (int *) REALLOC (arValueLengths, pCurrentIndexEntry->v_width * sizeof (int)); } if (arValues == NULL || arValueLengths == NULL) nRetCode = QERR_NO_MEMORY; else { for (i=nMaxValueWidth; i < pCurrentIndexEntry->v_width; i++) { arValueLengths[i] = 0; arValues[i] = NULL; } nMaxValueWidth = pCurrentIndexEntry->v_width; } } pCurrentIndexEntry->dist->value_sets = (int **) MALLOC (pCurrentIndexEntry->v_width * sizeof (int *)); if (pCurrentIndexEntry->dist->value_sets == NULL) nRetCode = QERR_NO_MEMORY; memset(pCurrentIndexEntry->dist->value_sets, 0, pCurrentIndexEntry->v_width * sizeof(int *)); break; case TKN_NAMES: if ((pCurrentIndexEntry->v_width <= 0) || (pCurrentIndexEntry->w_width <= 0)) return(QERR_NAMES_EARLY); pCurrentIndexEntry->name_space = ProcessNames(stmt, tokens); break; default: nRetCode = QERR_SYNTAX; } return (nRetCode); }