bool WMemoryMap::canMerge(const RowGroup &rg, MemoryMap::NodeIterator mmNode) { ASSERT_not_null(memoryMap_); ASSERT_require(mmNode != memoryMap_->nodes().end()); MemoryMap::NodeIterator mmNext = mmNode; ++mmNext; return mmNext!=memoryMap_->nodes().end() && mmNode->key().greatest()+1 == mmNext->key().least(); }
void WMemoryMap::updateRowGroupDataWidgets(RowGroup &rg, MemoryMap::NodeIterator mmNode) { ASSERT_not_null(memoryMap_); ASSERT_require(mmNode != memoryMap_->nodes().end()); const AddressInterval &interval = mmNode->key(); ASSERT_forbid(interval.isEmpty()); ASSERT_require(rg.segmentVa == interval.least()); rg.wSplit->setHidden(!isEditable_ || rg.editingColumn==SplitColumn || !canSplit(rg, mmNode)); rg.wMerge->setHidden(!isEditable_ || rg.editingColumn==MergeColumn || !canMerge(rg, mmNode)); rg.wLeastVa->setText(StringUtility::addrToString(interval.least())); rg.wGreatestVa->setText(StringUtility::addrToString(interval.greatest())); if (interval.isWhole()) { rg.wSize->setText("whole"); // since size would overflow back to zero } else { rg.wSize->setText(StringUtility::addrToString(interval.size())); } const MemoryMap::Segment &segment = mmNode->value(); rg.wReadable->setChecked(0 != (segment.accessibility() & MemoryMap::READABLE)); rg.wWritable->setChecked(0 != (segment.accessibility() & MemoryMap::WRITABLE)); rg.wExecutable->setChecked(0 != (segment.accessibility() & MemoryMap::EXECUTABLE)); rg.wName->setText(StringUtility::cEscape(segment.name())); }
// Synchronize the RowGroup list and the WTable rows with the MemoryMap void WMemoryMap::synchronize() { ASSERT_not_null(memoryMap_); memoryMap_->checkConsistency(); MemoryMap::NodeIterator mmNode = memoryMap_->nodes().begin(); RowGroups::iterator rg = rowGroups_.begin(); size_t rgIdx = 0; for (/*void*/; mmNode != memoryMap_->nodes().end(); ++mmNode, ++rg, ++rgIdx) { size_t tableIdx = rowGroupTableIndex(rgIdx); if (rg == rowGroups_.end()) { // Append a RowGroup and the corresponding table rows rg = rowGroups_.insert(rg, RowGroup(mmNode->key().least())); instantiateTableWidgets(*rg, tableIdx); } else { // Make sure the existing RowGroup is linked to the correct MemoryMap node. Since MemoryMap::NodeIterator is not // stable over insert and erase, we need to store a lookup key rather than an iterator. ASSERT_require2(rowGroupTableIndex(rgIdx+1)-1 < (size_t)wTable_->rowCount(), "table rows must already exist"); rg->segmentVa = mmNode->key().least(); } // Make sure the table is showing correct data. rg->editingColumn = ZeroColumn; rg->wId->setText(StringUtility::numberToString(rgIdx+1)); updateRowGroupWidgets(*rg, mmNode); } // Remove extra RowGroup entries and their corresponding WTable rows. rowGroups_.erase(rg, rowGroups_.end()); size_t tableIdx = rowGroupTableIndex(rgIdx); while ((size_t)wTable_->rowCount() > tableIdx) wTable_->deleteRow(wTable_->rowCount()-1); }
MemoryMap::NodeIterator WMemoryMap::findMapNode(const RowGroup &rg) { MemoryMap::NodeIterator mmNode = memoryMap_.at(rg.segmentVa).findNode(); ASSERT_require(mmNode != memoryMap_.nodes().end()); ASSERT_require(mmNode->key().least() == rg.segmentVa); return mmNode; }
// Synchronize edit rows of the table with the RowGroups void WMemoryMap::synchronizeEdits(RowGroup &rg, ColumnNumber toEdit) { rg.editingColumn = toEdit; MemoryMap::NodeIterator mmNode = memoryMap_.nodes().begin(); RowGroups::iterator rgIter = rowGroups_.begin(); for (/*void*/; mmNode != memoryMap_.nodes().end(); ++mmNode, ++rgIter) { ASSERT_require(rgIter != rowGroups_.end()); ASSERT_require(mmNode->key().least() == rgIter->segmentVa); if (rgIter->wId != rg.wId || !isEditable_) rgIter->editingColumn = ZeroColumn; updateRowGroupEditWidgets(*rgIter, mmNode); } }
bool WMemoryMap::canSplit(const RowGroup &rg, MemoryMap::NodeIterator mmNode) { ASSERT_not_null(memoryMap_); ASSERT_require(mmNode != memoryMap_->nodes().end()); return !mmNode->key().isEmpty() && mmNode->key().size() > 1; }