bool SchemaUtil::IndexIterator::hasMatchingOldFields(const Schema &oldSchema, bool phrases) const { assert(isValid()); const Schema::IndexField &newField = getSchema().getIndexField(getIndex()); const vespalib::string &fieldName = newField.getName(); uint32_t oldFieldId = oldSchema.getIndexFieldId(fieldName); if (oldFieldId == Schema::UNKNOWN_FIELD_ID) return false; if (phrases) { IndexIterator oldIterator(oldSchema, oldFieldId); IndexSettings settings = oldIterator.getIndexSettings(); if (!settings.hasPhrases()) return false; } const Schema::IndexField &oldField = oldSchema.getIndexField(oldFieldId); if (oldField.getDataType() != newField.getDataType() || oldField.getCollectionType() != newField.getCollectionType()) return false; return true; }
BlockStreamIteratorBase* EqualJoin::getIteratorTree(const unsigned& block_size){ if(dataflow_==0){ getDataflow(); } BlockStreamJoinIterator* join_iterator; BlockStreamIteratorBase* child_iterator_left=left_child_->getIteratorTree(block_size); BlockStreamIteratorBase* child_iterator_right=right_child_->getIteratorTree(block_size); Dataflow dataflow_left=left_child_->getDataflow(); Dataflow dataflow_right=right_child_->getDataflow(); BlockStreamJoinIterator::State state; state.block_size_=block_size; state.ht_nbuckets=1024*1024; // state.ht_nbuckets=1024; state.input_schema_left=getSchema(dataflow_left.attribute_list_); state.input_schema_right=getSchema(dataflow_right.attribute_list_); state.ht_schema=getSchema(dataflow_left.attribute_list_); /* the bucket size is 64-byte-aligned */ // state.ht_bucketsize=((state.input_schema_left->getTupleMaxSize()-1)/64+1)*64; /* * In the initial implementation, I set the bucket size to be up round to cache line * size, e.g., 64Bytes. Finally, I realized that different from aggregation, the hash * table bucket in the build phase of hash join is filled very quickly and hence a * a relatively large bucket size could reduce the number of overflowing buckets and * avoid the random memory access caused by acceesing overflowing buckets. */ state.ht_bucketsize=128; state.output_schema=getSchema(dataflow_->attribute_list_); state.joinIndex_left=getLeftJoinKeyIndexList(); state.joinIndex_right=getRightJoinKeyIndexList(); state.payload_left=getLeftPayloadIndexList(); state.payload_right=getRightPayloadIndexList(); switch(join_police_){ case no_repartition:{ state.child_left=child_iterator_left; state.child_right=child_iterator_right; join_iterator=new BlockStreamJoinIterator(state); break; } case left_repartition:{ // state.child_left BlockStreamExpander::State expander_state; expander_state.block_count_in_buffer_=EXPANDER_BUFFER_SIZE; expander_state.block_size_=block_size; expander_state.init_thread_count_=Config::initial_degree_of_parallelism; expander_state.child_=child_iterator_left; expander_state.schema_=getSchema(dataflow_left.attribute_list_); BlockStreamIteratorBase* expander=new BlockStreamExpander(expander_state); NodeTracker* node_tracker=NodeTracker::getInstance(); ExpandableBlockStreamExchangeEpoll::State exchange_state; exchange_state.block_size_=block_size; exchange_state.child_=expander;//child_iterator_left; exchange_state.exchange_id_=IDsGenerator::getInstance()->generateUniqueExchangeID(); std::vector<NodeID> upper_id_list=getInvolvedNodeID(dataflow_->property_.partitioner); exchange_state.upper_ip_list_=convertNodeIDListToNodeIPList(upper_id_list); std::vector<NodeID> lower_id_list=getInvolvedNodeID(dataflow_left.property_.partitioner); exchange_state.lower_ip_list_=convertNodeIDListToNodeIPList(lower_id_list); const Attribute right_partition_key=dataflow_->property_.partitioner.getPartitionKey(); /* get the left attribute that is corresponding to the partition key.*/ Attribute left_partition_key=joinkey_pair_list_[getIndexInRightJoinKeyList(right_partition_key)].first; exchange_state.partition_schema_=partition_schema::set_hash_partition(getIndexInAttributeList(dataflow_left.attribute_list_,left_partition_key)); // exchange_state.schema=getSchema(dataflow_left.attribute_list_,dataflow_right.attribute_list_); exchange_state.schema_=getSchema(dataflow_left.attribute_list_); BlockStreamIteratorBase* exchange=new ExpandableBlockStreamExchangeEpoll(exchange_state); state.child_left=exchange; state.child_right=child_iterator_right; join_iterator=new BlockStreamJoinIterator(state); break; } case right_repartition:{ BlockStreamExpander::State expander_state; expander_state.block_count_in_buffer_=EXPANDER_BUFFER_SIZE; expander_state.block_size_=block_size; expander_state.init_thread_count_=Config::initial_degree_of_parallelism; expander_state.child_=child_iterator_right; expander_state.schema_=getSchema(dataflow_right.attribute_list_); BlockStreamIteratorBase* expander=new BlockStreamExpander(expander_state); NodeTracker* node_tracker=NodeTracker::getInstance(); ExpandableBlockStreamExchangeEpoll::State exchange_state; exchange_state.block_size_=block_size; exchange_state.child_=expander; exchange_state.exchange_id_=IDsGenerator::getInstance()->generateUniqueExchangeID(); std::vector<NodeID> upper_id_list=getInvolvedNodeID(dataflow_->property_.partitioner); exchange_state.upper_ip_list_=convertNodeIDListToNodeIPList(upper_id_list); std::vector<NodeID> lower_id_list=getInvolvedNodeID(dataflow_right.property_.partitioner); exchange_state.lower_ip_list_=convertNodeIDListToNodeIPList(lower_id_list); const Attribute output_partition_key=dataflow_->property_.partitioner.getPartitionKey(); /* get the right attribute that is corresponding to the partition key.*/ Attribute right_repartition_key; if(dataflow_->property_.partitioner.hasShadowPartitionKey()){ right_repartition_key=joinkey_pair_list_[getIndexInLeftJoinKeyList(output_partition_key,dataflow_->property_.partitioner.getShadowAttributeList())].second; } else{ right_repartition_key=joinkey_pair_list_[getIndexInLeftJoinKeyList(output_partition_key)].second; } exchange_state.partition_schema_=partition_schema::set_hash_partition(getIndexInAttributeList(dataflow_right.attribute_list_,right_repartition_key)); exchange_state.schema_=getSchema(dataflow_right.attribute_list_); BlockStreamIteratorBase* exchange=new ExpandableBlockStreamExchangeEpoll(exchange_state); state.child_left=child_iterator_left; state.child_right=exchange; join_iterator=new BlockStreamJoinIterator(state); break; } case complete_repartition:{ /* build left input*/ BlockStreamExpander::State expander_state_l; expander_state_l.block_count_in_buffer_=EXPANDER_BUFFER_SIZE; expander_state_l.block_size_=block_size; expander_state_l.init_thread_count_=Config::initial_degree_of_parallelism; expander_state_l.child_=child_iterator_left; expander_state_l.schema_=getSchema(dataflow_left.attribute_list_); BlockStreamIteratorBase* expander_l=new BlockStreamExpander(expander_state_l); ExpandableBlockStreamExchangeEpoll::State l_exchange_state; l_exchange_state.block_size_=block_size; l_exchange_state.child_=expander_l; l_exchange_state.exchange_id_=IDsGenerator::getInstance()->generateUniqueExchangeID(); std::vector<NodeID> lower_id_list=getInvolvedNodeID(dataflow_left.property_.partitioner); l_exchange_state.lower_ip_list_=convertNodeIDListToNodeIPList(lower_id_list); std::vector<NodeID> upper_id_list=getInvolvedNodeID(dataflow_->property_.partitioner); l_exchange_state.upper_ip_list_=convertNodeIDListToNodeIPList(upper_id_list); const Attribute left_partition_key=dataflow_->property_.partitioner.getPartitionKey(); l_exchange_state.partition_schema_=partition_schema::set_hash_partition(getIndexInAttributeList(dataflow_left.attribute_list_,left_partition_key)); l_exchange_state.schema_=getSchema(dataflow_left.attribute_list_); BlockStreamIteratorBase* l_exchange=new ExpandableBlockStreamExchangeEpoll(l_exchange_state); /*build right input*/ BlockStreamExpander::State expander_state_r; expander_state_r.block_count_in_buffer_=EXPANDER_BUFFER_SIZE; expander_state_r.block_size_=block_size; expander_state_r.init_thread_count_=Config::initial_degree_of_parallelism; expander_state_r.child_=child_iterator_right; expander_state_r.schema_=getSchema(dataflow_right.attribute_list_); BlockStreamIteratorBase* expander_r=new BlockStreamExpander(expander_state_r); ExpandableBlockStreamExchangeEpoll::State r_exchange_state; r_exchange_state.block_size_=block_size; r_exchange_state.child_=expander_r; r_exchange_state.exchange_id_=IDsGenerator::getInstance()->generateUniqueExchangeID(); lower_id_list=getInvolvedNodeID(dataflow_right.property_.partitioner); r_exchange_state.lower_ip_list_=convertNodeIDListToNodeIPList(lower_id_list); upper_id_list=getInvolvedNodeID(dataflow_->property_.partitioner); r_exchange_state.upper_ip_list_=convertNodeIDListToNodeIPList(upper_id_list); const Attribute right_partition_key=joinkey_pair_list_[getIndexInLeftJoinKeyList(left_partition_key)].second; r_exchange_state.partition_schema_=partition_schema::set_hash_partition(getIndexInAttributeList(dataflow_right.attribute_list_,right_partition_key)); r_exchange_state.schema_=getSchema(dataflow_right.attribute_list_); BlockStreamIteratorBase* r_exchange=new ExpandableBlockStreamExchangeEpoll(r_exchange_state); /* finally build the join iterator itself*/ state.child_left=l_exchange; state.child_right=r_exchange; join_iterator=new BlockStreamJoinIterator(state); break; } default:{ break; } } return join_iterator; }
bool LogicalScan::GetOptimalPhysicalPlan(Requirement requirement,PhysicalPlanDescriptor& physical_plan_descriptor, const unsigned & block_size){ Dataflow dataflow=getDataflow(); NetworkTransfer transfer=requirement.requireNetworkTransfer(dataflow); ExpandableBlockStreamProjectionScan::State state; state.block_size_=block_size; state.projection_id_=target_projection_->getProjectionID(); state.schema_=getSchema(dataflow_->attribute_list_); state.sample_rate_=sample_rate_; PhysicalPlan scan=new ExpandableBlockStreamProjectionScan(state); if(transfer==NONE){ physical_plan_descriptor.plan=scan; physical_plan_descriptor.dataflow=dataflow; physical_plan_descriptor.cost+=0; } else{ physical_plan_descriptor.cost+=dataflow.getAggregatedDatasize(); ExpandableBlockStreamExchangeEpoll::State state; state.block_size_=block_size; state.child_=scan;//child_iterator; state.exchange_id_=IDsGenerator::getInstance()->generateUniqueExchangeID(); state.schema_=getSchema(dataflow.attribute_list_); std::vector<NodeID> lower_id_list=getInvolvedNodeID(dataflow.property_.partitioner); state.lower_id_list_=lower_id_list; std::vector<NodeID> upper_id_list; if(requirement.hasRequiredLocations()){ upper_id_list=requirement.getRequiredLocations(); } else{ if(requirement.hasRequiredPartitionFunction()){ /* partition function contains the number of partitions*/ PartitionFunction* partitoin_function=requirement.getPartitionFunction(); upper_id_list=std::vector<NodeID>(NodeTracker::getInstance()->getNodeIDList().begin(),NodeTracker::getInstance()->getNodeIDList().begin()+partitoin_function->getNumberOfPartitions()-1); } else{ //TODO: decide the degree of parallelism upper_id_list=NodeTracker::getInstance()->getNodeIDList(); } } state.upper_id_list_=upper_id_list; state.partition_schema_=partition_schema::set_hash_partition(getIndexInAttributeList(dataflow.attribute_list_,requirement.getPartitionKey())); assert(state.partition_schema_.partition_key_index>=0); BlockStreamIteratorBase* exchange=new ExpandableBlockStreamExchangeEpoll(state); Dataflow new_dataflow; new_dataflow.attribute_list_=dataflow.attribute_list_; new_dataflow.property_.partitioner.setPartitionKey(requirement.getPartitionKey()); new_dataflow.property_.partitioner.setPartitionFunction(PartitionFunctionFactory::createBoostHashFunction(state.upper_id_list_.size())); const unsigned total_size=dataflow.getAggregatedDatasize(); const unsigned degree_of_parallelism=state.upper_id_list_.size(); std::vector<DataflowPartition> dataflow_partition_list; for(unsigned i=0;i<degree_of_parallelism;i++){ const NodeID location=upper_id_list[i]; /* Currently, the join output size cannot be predicted due to the absence of data statistics. * We just use the magic number as following */ const unsigned datasize=total_size/degree_of_parallelism; DataflowPartition dfp(i,datasize,location); dataflow_partition_list.push_back(dfp); } new_dataflow.property_.partitioner.setPartitionList(dataflow_partition_list); physical_plan_descriptor.plan=exchange; physical_plan_descriptor.dataflow=new_dataflow; physical_plan_descriptor.cost+=new_dataflow.getAggregatedDatasize(); } if(requirement.passLimits(physical_plan_descriptor.cost)) return true; else return false; }
bool Filter::GetOptimalPhysicalPlan(Requirement requirement,PhysicalPlanDescriptor& physical_plan_descriptor, const unsigned & block_size){ PhysicalPlanDescriptor physical_plan; std::vector<PhysicalPlanDescriptor> candidate_physical_plans; /* no requirement to the child*/ if(child_->GetOptimalPhysicalPlan(Requirement(),physical_plan)){ NetworkTransfer transfer=requirement.requireNetworkTransfer(physical_plan.dataflow); if(transfer==NONE){ ExpandableBlockStreamFilter::State state; state.block_size_=block_size; state.child_=physical_plan.plan; state.qual_=qual_; state.colindex_=colindex_; state.comparator_list_=comparator_list_; state.v_ei_=exprArray_; Dataflow dataflow=getDataflow(); state.schema_=getSchema(dataflow.attribute_list_); BlockStreamIteratorBase* filter=new ExpandableBlockStreamFilter(state); physical_plan.plan=filter; candidate_physical_plans.push_back(physical_plan); } else if((transfer==OneToOne)||(transfer==Shuffle)){ /* the input data flow should be transfered in the network to meet the requirement * TODO: implement OneToOne Exchange * */ ExpandableBlockStreamFilter::State state_f; state_f.block_size_=block_size; state_f.child_=physical_plan.plan; state_f.v_ei_=exprArray_; state_f.qual_=qual_; state_f.colindex_=colindex_; state_f.comparator_list_=comparator_list_; Dataflow dataflow=getDataflow(); state_f.schema_=getSchema(dataflow.attribute_list_); BlockStreamIteratorBase* filter=new ExpandableBlockStreamFilter(state_f); physical_plan.plan=filter; physical_plan.cost+=physical_plan.dataflow.getAggregatedDatasize(); ExpandableBlockStreamExchangeEpoll::State state; state.block_size_=block_size; state.child_=physical_plan.plan;//child_iterator; state.exchange_id_=IDsGenerator::getInstance()->generateUniqueExchangeID(); state.schema_=getSchema(physical_plan.dataflow.attribute_list_); std::vector<NodeID> upper_id_list; if(requirement.hasRequiredLocations()){ upper_id_list=requirement.getRequiredLocations(); } else{ if(requirement.hasRequiredPartitionFunction()){ /* partition function contains the number of partitions*/ PartitionFunction* partitoin_function=requirement.getPartitionFunction(); upper_id_list=std::vector<NodeID>(NodeTracker::getInstance()->getNodeIDList().begin(),NodeTracker::getInstance()->getNodeIDList().begin()+partitoin_function->getNumberOfPartitions()-1); } else{ //TODO: decide the degree of parallelism upper_id_list=NodeTracker::getInstance()->getNodeIDList(); } } state.upper_ip_list_=convertNodeIDListToNodeIPList(upper_id_list); assert(requirement.hasReuiredPartitionKey()); state.partition_schema_=partition_schema::set_hash_partition(this->getIndexInAttributeList(physical_plan.dataflow.attribute_list_,requirement.getPartitionKey())); assert(state.partition_schema_.partition_key_index>=0); std::vector<NodeID> lower_id_list=getInvolvedNodeID(physical_plan.dataflow.property_.partitioner); state.lower_ip_list_=convertNodeIDListToNodeIPList(lower_id_list); BlockStreamIteratorBase* exchange=new ExpandableBlockStreamExchangeEpoll(state); physical_plan.plan=exchange; } candidate_physical_plans.push_back(physical_plan); } if(child_->GetOptimalPhysicalPlan(requirement,physical_plan)){ ExpandableBlockStreamFilter::State state; state.block_size_=block_size; state.child_=physical_plan.plan; state.v_ei_=exprArray_; state.qual_=qual_; state.colindex_=colindex_; state.comparator_list_=comparator_list_; Dataflow dataflow=getDataflow(); state.schema_=getSchema(dataflow.attribute_list_); BlockStreamIteratorBase* filter=new ExpandableBlockStreamFilter(state); physical_plan.plan=filter; candidate_physical_plans.push_back(physical_plan); } physical_plan_descriptor=getBestPhysicalPlanDescriptor(candidate_physical_plans); if(requirement.passLimits(physical_plan_descriptor.cost)) return true; else return false; }
PointBuffer* PointBuffer::flipOrientation() const { // Creates a new buffer that has the ignored dimensions removed from // it. pdal::Schema schema = getSchema(); schema::Orientation orientation = getSchema().getOrientation(); if (orientation == schema::POINT_INTERLEAVED) schema.setOrientation(schema::DIMENSION_INTERLEAVED); else if (orientation == schema::DIMENSION_INTERLEAVED) schema.setOrientation(schema::POINT_INTERLEAVED); else throw pdal_error("schema orientation is not recognized for PointBuffer::flipOrientation!"); schema::index_by_index const& idx = schema.getDimensions().get<schema::index>(); pdal::PointBuffer* output = new PointBuffer(schema, getCapacity()); if (orientation == schema::POINT_INTERLEAVED) { for (boost::uint32_t d = 0; d < idx.size(); ++d) { boost::uint8_t* write_position = output->getData(d); schema::size_type dimSize(idx[d].getByteSize()); std::size_t offset(idx[d].getByteOffset()); for (boost::uint32_t i = 0; i < getNumPoints(); ++i) { boost::uint8_t* point_start = getData(i); boost::uint8_t* read_position = point_start + offset; std::copy(read_position, read_position + dimSize, write_position); // memcpy(write_position, read_position, dimSize); write_position = write_position + dimSize; } } } else if (orientation == schema::DIMENSION_INTERLEAVED) { for (boost::uint32_t d = 0; d < idx.size(); ++d) { schema::size_type dimSize(idx[d].getByteSize()); std::size_t offset(idx[d].getByteOffset()); boost::uint8_t* read_start = getData(d); for (boost::uint32_t i = 0; i < getNumPoints(); ++i) { boost::uint8_t* write_position = output->getData(i)+offset; boost::uint8_t* read_position = read_start + i*dimSize; std::copy(read_position, read_position + dimSize, write_position); } } } output->setNumPoints(getNumPoints()); return output; }
boost::property_tree::ptree PointBuffer::toPTree() const { boost::property_tree::ptree tree; const Schema& schema = getSchema(); schema::index_by_index const& dimensions = schema.getDimensions().get<schema::index>(); const boost::uint32_t numPoints = getNumPoints(); for (boost::uint32_t pointIndex=0; pointIndex<numPoints; pointIndex++) { const std::string pointstring = boost::lexical_cast<std::string>(pointIndex) + "."; boost::uint32_t i = 0; for (i=0; i<dimensions.size(); i++) { const Dimension& dimension = dimensions[i]; boost::uint32_t const& size = dimension.getByteSize(); const std::string key = pointstring + dimension.getName(); std::string output = ""; double scale = dimension.getNumericScale(); double offset = dimension.getNumericOffset(); bool applyScaling(false); if (!Utils::compare_distance(scale, 0.0) || !Utils::compare_distance(offset, 0.0) ) { applyScaling = true; } switch (dimension.getInterpretation()) { #define GETFIELDAS(T) getField<T>(dimension, pointIndex) #define STRINGIFY(T,x) boost::lexical_cast<std::string>(boost::numeric_cast<T>(x)) // note we convert 8-bit fields to ints, so they aren't treated as chars case dimension::SignedInteger: case dimension::SignedByte: if (size == 1) { if (!applyScaling) output += STRINGIFY(boost::int32_t, GETFIELDAS(boost::int8_t)); else { boost::int8_t v = GETFIELDAS(boost::int8_t); double d = dimension.applyScaling<boost::int8_t>(v); output += STRINGIFY(double, d); } } if (size == 2) { if (!applyScaling) output += STRINGIFY(boost::int16_t, GETFIELDAS(boost::int16_t)); else { boost::int16_t v = GETFIELDAS(boost::int16_t); double d = dimension.applyScaling<boost::int16_t>(v); output += STRINGIFY(double, d); } } if (size == 4) { if (!applyScaling) output += STRINGIFY(boost::int32_t, GETFIELDAS(boost::int32_t)); else { boost::int32_t v = GETFIELDAS(boost::int32_t); double d = dimension.applyScaling<boost::int32_t>(v); output += STRINGIFY(double, d); } } if (size == 8) { if (!applyScaling) output += STRINGIFY(boost::int64_t, GETFIELDAS(boost::int64_t)); else { boost::int64_t v = GETFIELDAS(boost::int64_t); double d = dimension.applyScaling<boost::int64_t>(v); output += STRINGIFY(double, d); } } break; case dimension::UnsignedInteger: case dimension::UnsignedByte: if (size == 1) { if (!applyScaling) output += STRINGIFY(boost::uint32_t, GETFIELDAS(boost::uint8_t)); else { boost::uint8_t v = GETFIELDAS(boost::uint8_t); double d = dimension.applyScaling<boost::uint8_t>(v); output += STRINGIFY(double, d); } } if (size == 2) { if (!applyScaling) output += STRINGIFY(boost::uint16_t, GETFIELDAS(boost::uint16_t)); else { boost::uint16_t v = GETFIELDAS(boost::uint16_t); double d = dimension.applyScaling<boost::uint16_t>(v); output += STRINGIFY(double, d); } } if (size == 4) { if (!applyScaling) output += STRINGIFY(boost::uint32_t, GETFIELDAS(boost::uint32_t)); else { boost::uint32_t v = GETFIELDAS(boost::uint32_t); double d = dimension.applyScaling<boost::uint32_t>(v); output += STRINGIFY(double, d); } } if (size == 8) { if (!applyScaling) output += STRINGIFY(double, GETFIELDAS(boost::uint64_t)); else { boost::uint64_t v = GETFIELDAS(boost::uint64_t); double d = dimension.applyScaling<boost::uint64_t>(v); output += STRINGIFY(double, d); } } break; case dimension::Float: if (size == 4) { if (!applyScaling) output += STRINGIFY(float, GETFIELDAS(float)); else { float v = GETFIELDAS(float); double d = dimension.applyScaling<float>(v); output += STRINGIFY(float, d); } } else if (size == 8) { if (!applyScaling) output += STRINGIFY(double, GETFIELDAS(double)); else { double v = GETFIELDAS(double); double d = dimension.applyScaling<double>(v); output += STRINGIFY(double, d); } }
Schema *decryptSchema(char *schema, char temp, int count, int index) { index = 0; int i = 0, size = 0, j, numOfAttr; bool isSchema; char *string1; char *string2; char *string3; int len = strlen(schema); char dataSchema[len]; Schema *s = NULL; s = getSchema(); memcpy(dataSchema, schema, len); modifySchema(&string1, dataSchema); numOfAttr = getNumbOfAttributes(&string1, &string2); char* attr[numOfAttr]; char* str[numOfAttr]; populSchema(s, numOfAttr); string1 = strtok(NULL, "("); for (; i < s->numAttr; i++) { string1 = strtok(NULL, ": "); schemaAttrName(s, &string1, i); str[i] = initStringRef(string1,0); populateTableWithDataTypes(s, &string1, i); memcpy(str[i], string1, strlen(string1)); } isSchema = false; if ((string1 = strtok(NULL, "("))) { isSchema = true; char *tempExtractedData=NULL; tempExtractedData = extractData(&string1); i = 0; while (tempExtractedData) { attr[size] = initStringRef(tempExtractedData,0); strcpy(attr[size], tempExtractedData); tempExtractedData = strtok(NULL, ", "); size =size+ 1; i++; } } for (i = 0; i < numOfAttr; i++) { len = strlen(str[i]); if (len > 0) { s->dataTypes[i] = DT_STRING; string3 = initStringRef((str[i]),0); strncpy(string3, str[i], len); extractDataString(&string1, &string3); s->typeLength[i] = getNumbOfAttributes(&string1, &string2); } } if (isSchema) { s->keyAttrs = (int *) calloc(size, sizeof(int));; s->keySize = size; for (i = 0; i < size; i++) { for (j = 0; j < s->numAttr; j++) { if (strcmp(attr[i], s->attrNames[j]) == 0) s->keyAttrs[i] = j; } } } return s; }