//# DataManInfo.cc: Class with static functions to manipulate a datamanager info record //# Copyright (C) 2001,2002,2003,2009 //# Associated Universities, Inc. Washington DC, USA. //# //# This library is free software; you can redistribute it and/or modify it //# under the terms of the GNU Library General Public License as published by //# the Free Software Foundation; either version 2 of the License, or (at your //# option) any later version. //# //# This library is distributed in the hope that it will be useful, but WITHOUT //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public //# License for more details. //# //# You should have received a copy of the GNU Library General Public License //# along with this library; if not, write to the Free Software Foundation, //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. //# //# Correspondence concerning AIPS++ should be addressed as follows: //# Internet email: aips2-request@nrao.edu. //# Postal address: AIPS++ Project Office //# National Radio Astronomy Observatory //# 520 Edgemont Road //# Charlottesville, VA 22903-2475 USA //# //# $Id$ //# Includes #include #include #include #include #include #include #include #include #include #include namespace casacore { //# NAMESPACE CASACORE - BEGIN void DataManInfo::removeHypercolumns (TableDesc& tabDesc) { tabDesc.adjustHypercolumns (std::map()); } void DataManInfo::adjustDesc (TableDesc& tdesc, const Record& dminfo) { // Find out the columns and data manager groups of the fields. std::map dmTypeMap; std::map dmGroupMap; for (uInt i=0; i cols = sub.asArrayString ("COLUMNS"); for (uInt j=0; j::iterator iter1 = dmTypeMap.find (name); if (iter1 != dmTypeMap.end()) { String v = iter1->second; if (! v.empty()) { cdesc.dataManagerType() = v; } } std::map::iterator iter2 = dmGroupMap.find (name); if (iter2 != dmTypeMap.end()) { String v = iter2->second; if (! v.empty()) { cdesc.dataManagerGroup() = v; } } } // Remove hypercolumn definitions which are different from // data manager group in the column descriptions. Vector hcNames = tdesc.hypercolumnNames(); for (uInt i=0; i dataNames, coordNames, idNames; tdesc.hypercolumnDesc (hcNames[i], dataNames, coordNames, idNames); Bool same = True; for (uInt j=0; j dataNames, coordNames, idNames; // Keep track of hypercolumns to be changed. Vector hcChange; uInt nrhc = 0; // Loop through all hypercolumn descriptions. Vector hcNames = tabDesc.hypercolumnNames(); for (uInt i=0; i 0) { // The hypercolumn definition contains ID columns, so it // has to be changed later in the TableDesc. hcChange.resize (nrhc+1, True); hcChange(nrhc++) = hcNames(i); // Keep the dminfo columns which are not an ID column. Vector colNames = rec.asArrayString("COLUMNS"); Vector colsout(colNames.nelements()); uInt nrout = 0; for (uInt k=0; k 0) { tabDesc.removeIDhypercolumns (hcChange); } } Record DataManInfo::adjustStMan (const Record& dminfo, const String& dmType, Bool replaceMSM) { Record newdm; for (uInt j=0; jisStorageManager() && !(dmptr->canAddRow() || dmptr->isRegular())) || (replaceMSM && exType == "MemoryStMan")) { // A non-writable storage manager; use given storage manager instead. rec.define ("TYPE", dmType); rec.define ("NAME", exName); } delete dmptr; newdm.defineRecord (j, rec); } return newdm; } void DataManInfo::mergeInfo (Record& dminfo1, const Record& dminfo2) { // See for each new data manager what to do. for (uInt i2=0; i2 cols; if (dm.isDefined("COLUMNS")) { cols.reference (dm.asArrayString("COLUMNS")); } if (! cols.empty()) { // Iterate over all dm-s to find the ones containing columns of the new dm. for (uInt i=0; i cols2(dm2.asArrayString("COLUMNS")); if (! cols2.empty()) { std::vector colsnew; // Keep columns not equal to a column in the new dm. for (auto col2 : cols2) { if (std::find (cols.begin(), cols.end(), col2) == cols.end()) { colsnew.push_back (col2); } } if (i != dmindex) { // dm is not the new one, so update the COLUMNS in it (if changed). if (colsnew.size() != cols2.size()) { dm2.define ("COLUMNS", Vector(colsnew)); dminfo.defineRecord (i, dm2); } } else { // dm is the new one. So add its columns and redefine them. colsnew.insert (colsnew.end(), cols.begin(), cols.end()); dm.define ("COLUMNS", Vector(colsnew)); } } } } } } Record DataManInfo::finalizeMerge (const TableDesc& desc, const Record& dminfo) { // Make a map of the data managers in the dminfo record, so possible // specifications can be used. // Also make a map of column to dminfo index. std::map, uInt> dmMap; std::map colMap; for (uInt i=0; i cols(dm.asArrayString("COLUMNS")); for (auto col : cols) { colMap[col] = i; } } } } // Find out which columns share the same data manager by making a map // of data manager type/name to columns in the Table Description. std::map, std::vector> descMap; for (uInt i=0; isecond); if (dm.isDefined("TYPE")) { type = dm.asString("TYPE"); } if (dm.isDefined("NAME")) { name = dm.asString("NAME"); } } if (type.empty()) { type = "StandardStMan"; } // Add the column to the vector. descMap[std::make_pair(type, name)].push_back (cd.name()); } // Create a dminfo entry for each column set found above. // Use dm parameters if found. Record newdm; for (auto desc : descMap) { String type = desc.first.first; String name = desc.first.second; Record dm; // Try to find this type/name in the dminfo map to copy its specs. // Define the columns. auto iter = dmMap.find (std::make_pair(type, name)); if (iter != dmMap.end()) { dm = dminfo.subRecord(iter->second); } dm.define ("COLUMNS", Vector(desc.second)); // Use the first column name one for a dm entry without a name. if (name.empty()) { name = desc.second[0]; } // Ensure the name is unique. dm.define ("TYPE", type); dm.define ("NAME", uniqueName (newdm, name)); // Add the the overall dminfo record. newdm.defineRecord (newdm.size(), dm); } return newdm; } void DataManInfo::makeUniqueNames (Record& dminfo) { // Ensure that data manager names are unique by adding a suffix if needed. // First set empty names to the name of the first column. for (uInt i=0; i cols(dm.asArrayString("COLUMNS")); if (! cols.empty()) { name = cols[0]; } } dm.define ("NAME", name); } } // Now make the names unique if needed. // The first instance is kept as is, others get suffix _1, _2, etc. std::set firstNames; for (uInt i=0; i cols(subinfo.asArrayString("COLUMNS")); if (! cols.empty()) { String name = subinfo.asString(i); for (uInt j=0; j DataManInfo::removeDminfoColumns (Record& dminfo, const Vector& columns, const String& keepType) { Record newdm; // Find the given columns and remove them. // Keep track which columns are removed. Vector remCols(columns.size()); uInt ncols = 0; for (uInt j=0; j dmcols (rec.asArrayString("COLUMNS")); uInt ndmcol = dmcols.size(); const String& dmtype = rec.asString ("TYPE"); if (keepType.empty() || dmtype.substr(0,keepType.size()) != keepType) { // This dmtype does not need to be kept, so columns can be removed. for (uInt i=0; i 0) { if (ndmcol != dmcols.size()) { dmcols.resize (ndmcol, True); rec.define ("COLUMNS", dmcols); } newdm.defineRecord (j, rec); } } dminfo = newdm; remCols.resize (ncols, True); return remCols; } void DataManInfo::setTiledStMan (Record& dminfo, const Vector& columns, const String& dmType, const String& dmName, const IPosition& defaultTileShape) { // Remove the columns. Vector remCols (removeDminfoColumns (dminfo, columns, "Tiled")); // Add removed columns with a TiledStMan. if (remCols.size() > 0) { Record dm; dm.define("TYPE", dmType); dm.define("NAME", dmName); dm.define ("COLUMNS", remCols); Record spec; spec.define("DEFAULTTILESHAPE", defaultTileShape.asVector()); dm.defineRecord ("SPEC", spec); dminfo.defineRecord (dminfo.nfields(), dm); } } void DataManInfo::showDataManStats (const Table& tab, ostream& os) { Record dmInfo = tab.dataManagerInfo(); // Loop through all data managers. // Not all of them might have a name, so use the first column in // each of them to construct the Accessor object. for (uInt i=0; i