//--------------------------------------------------------------------------- // Distribute records from parent paritition to child partitions. //--------------------------------------------------------------------------- bool CTDPartitioner::testDistributeRecords(CTDPartition* pParentPartition, CTDAttrib* pSplitAttrib, CTDConcept* pSplitConcept, CTDPartitions& childPartitions) { childPartitions.RemoveAll(); // Construct a partition for each child concept. for (int childIdx = 0; childIdx < pSplitConcept->getNumChildConcepts(); ++childIdx) childPartitions.AddTail(new CTDPartition( gTestPartitionIndex++, m_pAttribMgr->getAttributes())); // Scan through each record in the parent partition and // add records to the corresponding child partition based // on the child concept. CTDRecord* pRec = NULL; CTDValue* pSplitValue = NULL; POSITION childPartitionPos = NULL; int childConceptIdx = -1; int splitIdx = pSplitAttrib->m_attribIdx; int nRecs = pParentPartition->getNumRecords(); ASSERT(nRecs > 0); for (int r = 0; r < nRecs; ++r) { pRec = pParentPartition->getRecord(r); pSplitValue = pRec->getValue(splitIdx); // Lower the concept by one level. if (!pSplitValue->lowerCurrentConcept()) { cerr << _T("CTDPartition: Should not specialize on this concept."); childPartitions.cleanup(); ASSERT(false); return false; } // Get the child concept of the current concept in this record. childConceptIdx = pSplitValue->getCurrentConcept()->m_childIdx; ASSERT(childConceptIdx != -1); childPartitionPos = childPartitions.FindIndex(childConceptIdx); ASSERT(childPartitionPos); // Add the record to this child partition. if (!childPartitions.GetAt(childPartitionPos)->addRecord(pRec)) { childPartitions.cleanup(); ASSERT(false); return false; } } // Delete empty child partitions. childPartitions.deleteEmptyPartitions(); return true; }