casacore
ColumnSet.h
Go to the documentation of this file.
1 //# ColumnSet.h: Class to manage a set of table columns
2 //# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2001,2002,2003
3 //# Associated Universities, Inc. Washington DC, USA.
4 //#
5 //# This library is free software; you can redistribute it and/or modify it
6 //# under the terms of the GNU Library General Public License as published by
7 //# the Free Software Foundation; either version 2 of the License, or (at your
8 //# option) any later version.
9 //#
10 //# This library is distributed in the hope that it will be useful, but WITHOUT
11 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 //# License for more details.
14 //#
15 //# You should have received a copy of the GNU Library General Public License
16 //# along with this library; if not, write to the Free Software Foundation,
17 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 //#
19 //# Correspondence concerning AIPS++ should be addressed as follows:
20 //# Internet email: aips2-request@nrao.edu.
21 //# Postal address: AIPS++ Project Office
22 //# National Radio Astronomy Observatory
23 //# 520 Edgemont Road
24 //# Charlottesville, VA 22903-2475 USA
25 //#
26 //# $Id$
27 
28 #ifndef TABLES_COLUMNSET_H
29 #define TABLES_COLUMNSET_H
30 
31 
32 //# Includes
33 #include <casacore/casa/aips.h>
34 #include <casacore/tables/Tables/TableLockData.h>
35 #include <casacore/tables/Tables/BaseTable.h>
36 #include <casacore/tables/Tables/StorageOption.h>
37 #include <casacore/casa/BasicSL/String.h>
38 #include <casacore/casa/Arrays/ArrayFwd.h>
39 
40 #include <map>
41 
42 namespace casacore { //# NAMESPACE CASACORE - BEGIN
43 
44 //# Forward Declarations
45 class SetupNewTable;
46 class Table;
47 class TableDesc;
48 class TSMOption;
49 class BaseTable;
50 class TableAttr;
51 class ColumnDesc;
52 class PlainColumn;
53 class DataManager;
54 class MultiFile;
55 class Record;
56 class IPosition;
57 class AipsIO;
58 
59 // <summary>
60 // Class to manage a set of table columns
61 // </summary>
62 
63 // <use visibility=local>
64 
65 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="">
66 // </reviewed>
67 
68 // <prerequisite>
69 //# Classes you should understand before using this one.
70 // <li> PlainTable
71 // <li> DataManager
72 // </prerequisite>
73 
74 // <etymology>
75 // ColumnSet represent the set of columns in a table.
76 // </etymology>
77 
78 // <synopsis>
79 // ColumnSet contains all columns in a plain table (thus not in a RefTable).
80 // Furthermore it contains the set of data managers used by the columns
81 // in the table.
82 //
83 // The main purpose of the class is to deal with constructing, writing
84 // and reading the column objects. It is used by classes SetupNewTable
85 // and Table.
86 // </synopsis>
87 
88 // <todo asof="$DATE:$">
89 //# A List of bugs, limitations, extensions or planned refinements.
90 // </todo>
91 
92 
93 class ColumnSet
94 {
95 public:
96 
97  // Construct from the table description.
98  // This creates all underlying filled and virtual column objects.
100 
102 
103  // Reopen the data managers for read/write.
104  void reopenRW();
105 
106  // Rename the necessary subtables in the column keywords.
107  void renameTables (const String& newName, const String& oldName);
108 
109  // Get the storage option.
111  { return storageOpt_p; }
112 
113  // Are subtables used in other processes.
115 
116  // Get a column by name.
117  PlainColumn* getColumn (const String& columnName) const;
118 
119  // Get a column by index.
120  PlainColumn* getColumn (uInt columnIndex) const;
121 
122  // Add a data manager.
123  // It increments seqCount_p and returns that as a unique sequence number.
124  // This can, for instance, be used to create a unique file name.
126 
127  // Initialize the data managers for a new table.
128  // It creates the data manager column objects for each column
129  // and it allows the data managers to link themselves to the
130  // Table object and to initialize themselves.
131  void initDataManagers (rownr_t nrrow, Bool bigEndian,
132  const TSMOption& tsmOption,
133  Table& tab);
134 
135  // Link the ColumnSet object to the BaseTable object.
136  void linkToTable (BaseTable* baseTableObject);
137 
138  // Link the ColumnSet object to the TableLockData object.
139  void linkToLockObject (TableLockData* lockObject);
140 
141  // Check if the table is locked for read or write.
142  // If manual or permanent locking is in effect, it checks if the
143  // table is properly locked.
144  // If autolocking is in effect, it locks the table when needed.
145  // <group>
146  void checkReadLock (Bool wait);
147  void checkWriteLock (Bool wait);
148  // </group>
149 
150  // Inspect the auto lock when the inspection interval has expired and
151  // release it when another process needs the lock.
152  void autoReleaseLock();
153 
154  // If needed, get a temporary user lock.
155  // It returns False if the lock was already there.
157 
158  // Release a temporary user lock if the given release flag is True.
159  void userUnlock (Bool releaseFlag);
160 
161  // Do all data managers and engines allow to add rows?
162  Bool canAddRow() const;
163 
164  // Do all data managers and engines allow to remove rows?
166 
167  // Can the given columns be removed from the data manager?
168  Bool canRemoveColumn (const Vector<String>& columnNames) const;
169 
170  // Can a column be renamed in the data manager?
171  Bool canRenameColumn (const String& columnName) const;
172 
173  // Add rows to all data managers.
174  void addRow (rownr_t nrrow);
175 
176  // Remove a row from all data managers.
177  // It will throw an exception if not possible.
178  void removeRow (rownr_t rownr);
179 
180  // Remove the columns from the map and the data manager.
181  void removeColumn (const Vector<String>& columnNames);
182 
183  // Rename the column in the map.
184  void renameColumn (const String& newName, const String& oldName);
185 
186  // Add a column to the table.
187  // The default implementation throws an "invalid operation" exception.
188  // <group>
189  void addColumn (const ColumnDesc& columnDesc,
190  Bool bigEndian, const TSMOption& tsmOption, Table& tab);
191  void addColumn (const ColumnDesc& columnDesc,
192  const String& dataManager, Bool byName,
193  Bool bigEndian, const TSMOption& tsmOption, Table& tab);
194  void addColumn (const ColumnDesc& columnDesc,
195  const DataManager& dataManager,
196  Bool bigEndian, const TSMOption& tsmOption, Table& tab);
197  void addColumn (const TableDesc& tableDesc,
198  const DataManager& dataManager,
199  Bool bigEndian, const TSMOption& tsmOption, Table& tab);
200  // </group>
201 
202  // Get nr of rows.
203  rownr_t nrow() const;
204 
205  // Get the actual table description.
207 
208  // Get the data manager info.
209  // Optionally only the virtual engines are retrieved.
210  Record dataManagerInfo (Bool virtualOnly=False) const;
211 
212  // Get the trace-id of the table.
213  int traceId() const
214  { return baseTablePtr_p->traceId(); }
215 
216  // Initialize rows startRownr till endRownr (inclusive).
217  void initialize (rownr_t startRownr, rownr_t endRownr);
218 
219  // Write all the data and let the data managers flush their data.
220  // This function is called when a table gets written (i.e. flushed).
221  // It returns True if any data manager wrote something.
222  Bool putFile (Bool writeTable, AipsIO&, const TableAttr&, Bool fsync);
223 
224  // Read the data, reconstruct the data managers, and link those to
225  // the table object.
226  // This function gets called when an existing table is read back.
227  // It returns the number of rows in case a data manager thinks there are
228  // more. That is in particular used by LofarStMan.
229  rownr_t getFile (AipsIO&, Table& tab, rownr_t nrrow, Bool bigEndian,
230  const TSMOption& tsmOption);
231 
232  // Set the table to being changed.
233  void setTableChanged();
234 
235  // Get the data manager change flags (used by PlainTable).
237 
238  // Synchronize the data managers when data in them have changed.
239  // It returns the number of rows it think it has, which is needed for
240  // storage managers like LofarStMan.
241  // <src>forceSync=True</src> means that the data managers are forced
242  // to do a sync. Otherwise the contents of the lock file tell if a data
243  // manager has to sync.
244  rownr_t resync (rownr_t nrrow, Bool forceSync);
245 
246  // Invalidate the column caches for all columns.
248 
249  // Get the correct data manager.
250  // This is used by the column objects to link themselves to the
251  // correct datamanagers when they are read back.
253 
254  // Check if no double data manager names have been given.
255  void checkDataManagerNames (const String& tableName) const;
256 
257  // Find the data manager with the given name or for the given column.
258  // If the data manager or column is unknown, an exception is thrown.
259  // A blank name means the data manager is unknown.
261  Bool byColumn=False) const;
262 
263  // Make a unique data manager name by appending a suffix _n if needed
264  // where n is a number that makes the name unique.
265  String uniqueDataManagerName (const String& name) const;
266 
267  // Synchronize the columns after it appeared that data in the
268  // main table file have changed.
269  // It cannot deal with changes in number of columns, so it throws an
270  // exception when they have changed.
271  // Keywords in all columns are updated.
272  // The other ColumnSet gives the new data.
273  void syncColumns (const ColumnSet& other, const TableAttr& defaultAttr);
274 
275 private:
276  // Remove the last data manager (used by addColumn after an exception).
277  // It does the opposite of addDataManager.
279 
280  // Let the data managers (from the given index on) initialize themselves.
281  void initSomeDataManagers (uInt from, Table& tab);
282 
283  // Let the data managers (from the given index on) prepare themselves.
285 
286  // Open or create the MultiFile if needed.
287  void openMultiFile (uInt from, const Table& tab,
289 
290  // Check if a data manager name has not already been used.
291  // Start checking at the given index in the array.
292  // It returns False if the name has already been used.
293  // By default an exception is thrown if the name has already been used.
294  Bool checkDataManagerName (const String& name, uInt from,
295  const String& tableName,
296  Bool doTthrow=True) const;
297 
298  // Do the actual addition of a column.
299  void doAddColumn (const ColumnDesc& columnDesc, DataManager* dataManPtr);
300 
301  // Check if columns to be removed can be removed.
302  // It returns a map of DataManager* telling how many columns for
303  // a data manager have to be removed. A count of -1 means that all
304  // columns have to be removed. For such columns the flag in the
305  // returned Block is False, otherwise True.
306  std::map<void*,Int> checkRemoveColumn (const Vector<String>& columnNames);
307 
308  // Check if the table is locked for read or write.
309  // If manual or permanent locking is in effect, it checks if the
310  // table is properly locked.
311  // If autolocking is in effect, it locks the table when needed.
313 
314 
315  //# Declare the variables.
319  rownr_t nrrow_p; //# #rows
321  TableLockData* lockPtr_p; //# lock object
322  std::map<String,void*> colMap_p; //# list of PlainColumns
323  uInt seqCount_p; //# sequence number count
324  //# (used for unique seqnr)
325  Block<void*> blockDataMan_p; //# list of data managers
326  Block<Bool> dataManChanged_p; //# data has changed
327 };
328 
329 
330 
331 inline rownr_t ColumnSet::nrow() const
332 {
333  return nrrow_p;
334 }
335 inline void ColumnSet::linkToTable (BaseTable* baseTableObject)
336 {
337  baseTablePtr_p = baseTableObject;
338 }
340 {
342 }
344 {
345  lockPtr_p = lockObject;
346 }
347 inline void ColumnSet::checkReadLock (Bool wait)
348 {
349  if (lockPtr_p->readLocking()
351  doLock (FileLocker::Read, wait);
352  }
353 }
354 inline void ColumnSet::checkWriteLock (Bool wait)
355 {
357  doLock (FileLocker::Write, wait);
358  }
359 }
360 inline void ColumnSet::userUnlock (Bool releaseFlag)
361 {
362  if (releaseFlag) {
363  lockPtr_p->release();
364  }
365 }
367 {
369 }
371 {
372  return dataManChanged_p;
373 }
374 
375 
376 
377 
378 } //# NAMESPACE CASACORE - END
379 
380 #endif
int traceId() const
Get the table's trace-id.
Definition: BaseTable.h:492
virtual void setTableChanged()
Set the table to being changed.
OpenOption
Define the possible ByteIO open options.
Definition: ByteIO.h:65
void renameTables(const String &newName, const String &oldName)
Rename the necessary subtables in the column keywords.
void removeRow(rownr_t rownr)
Remove a row from all data managers.
Bool canRenameColumn(const String &columnName) const
Can a column be renamed in the data manager?
void autoReleaseLock()
Inspect the auto lock when the inspection interval has expired and release it when another process ne...
Definition: ColumnSet.h:366
Bool canAddRow() const
Do all data managers and engines allow to add rows?
DataManager * getDataManager(uInt seqnr) const
Get the correct data manager.
BaseTable * baseTablePtr_p
Definition: ColumnSet.h:320
void initSomeDataManagers(uInt from, Table &tab)
Let the data managers (from the given index on) initialize themselves.
void linkToTable(BaseTable *baseTableObject)
Link the ColumnSet object to the BaseTable object.
Definition: ColumnSet.h:335
MultiFileBase * multiFile_p
Definition: ColumnSet.h:318
void linkToLockObject(TableLockData *lockObject)
Link the ColumnSet object to the TableLockData object.
Definition: ColumnSet.h:343
DataManager * findDataManager(const String &name, Bool byColumn=False) const
Find the data manager with the given name or for the given column.
void prepareSomeDataManagers(uInt from)
Let the data managers (from the given index on) prepare themselves.
void removeLastDataManager()
Remove the last data manager (used by addColumn after an exception).
Bool userLock(FileLocker::LockType, Bool wait)
If needed, get a temporary user lock.
void addColumn(const TableDesc &tableDesc, const DataManager &dataManager, Bool bigEndian, const TSMOption &tsmOption, Table &tab)
void doAddColumn(const ColumnDesc &columnDesc, DataManager *dataManPtr)
Do the actual addition of a column.
void syncColumns(const ColumnSet &other, const TableAttr &defaultAttr)
Synchronize the columns after it appeared that data in the main table file have changed.
Bool canRemoveColumn(const Vector< String > &columnNames) const
Can the given columns be removed from the data manager?
void invalidateColumnCaches()
Invalidate the column caches for all columns.
void addColumn(const ColumnDesc &columnDesc, const String &dataManager, Bool byName, Bool bigEndian, const TSMOption &tsmOption, Table &tab)
void removeColumn(const Vector< String > &columnNames)
Remove the columns from the map and the data manager.
void setTableChanged()
Set the table to being changed.
Definition: ColumnSet.h:339
void checkReadLock(Bool wait)
Check if the table is locked for read or write.
Definition: ColumnSet.h:347
TableLockData * lockPtr_p
Definition: ColumnSet.h:321
Bool putFile(Bool writeTable, AipsIO &, const TableAttr &, Bool fsync)
Write all the data and let the data managers flush their data.
void initDataManagers(rownr_t nrrow, Bool bigEndian, const TSMOption &tsmOption, Table &tab)
Initialize the data managers for a new table.
ColumnSet(TableDesc *, const StorageOption &=StorageOption())
Construct from the table description.
void renameColumn(const String &newName, const String &oldName)
Rename the column in the map.
void checkDataManagerNames(const String &tableName) const
Check if no double data manager names have been given.
void openMultiFile(uInt from, const Table &tab, ByteIO::OpenOption)
Open or create the MultiFile if needed.
rownr_t nrow() const
Get nr of rows.
Definition: ColumnSet.h:331
StorageOption storageOpt_p
Definition: ColumnSet.h:317
int traceId() const
Get the trace-id of the table.
Definition: ColumnSet.h:213
String uniqueDataManagerName(const String &name) const
Make a unique data manager name by appending a suffix _n if needed where n is a number that makes the...
TableDesc actualTableDesc() const
Get the actual table description.
void addColumn(const ColumnDesc &columnDesc, Bool bigEndian, const TSMOption &tsmOption, Table &tab)
Add a column to the table.
void addDataManager(DataManager *)
Add a data manager.
void checkWriteLock(Bool wait)
Definition: ColumnSet.h:354
Bool checkDataManagerName(const String &name, uInt from, const String &tableName, Bool doTthrow=True) const
Check if a data manager name has not already been used.
void initialize(rownr_t startRownr, rownr_t endRownr)
Initialize rows startRownr till endRownr (inclusive).
Record dataManagerInfo(Bool virtualOnly=False) const
Get the data manager info.
std::map< String, void * > colMap_p
Definition: ColumnSet.h:322
void addColumn(const ColumnDesc &columnDesc, const DataManager &dataManager, Bool bigEndian, const TSMOption &tsmOption, Table &tab)
Block< void * > blockDataMan_p
Definition: ColumnSet.h:325
Bool canRemoveRow() const
Do all data managers and engines allow to remove rows?
Block< Bool > & dataManChanged()
Get the data manager change flags (used by PlainTable).
Definition: ColumnSet.h:370
PlainColumn * getColumn(uInt columnIndex) const
Get a column by index.
Bool areTablesMultiUsed() const
Are subtables used in other processes.
const StorageOption & storageOption() const
Get the storage option.
Definition: ColumnSet.h:110
void doLock(FileLocker::LockType, Bool wait)
Check if the table is locked for read or write.
void reopenRW()
Reopen the data managers for read/write.
PlainColumn * getColumn(const String &columnName) const
Get a column by name.
Block< Bool > dataManChanged_p
Definition: ColumnSet.h:326
std::map< void *, Int > checkRemoveColumn(const Vector< String > &columnNames)
Check if columns to be removed can be removed.
void addRow(rownr_t nrrow)
Add rows to all data managers.
rownr_t getFile(AipsIO &, Table &tab, rownr_t nrrow, Bool bigEndian, const TSMOption &tsmOption)
Read the data, reconstruct the data managers, and link those to the table object.
TableDesc * tdescPtr_p
Definition: ColumnSet.h:316
rownr_t resync(rownr_t nrrow, Bool forceSync)
Synchronize the data managers when data in them have changed.
void userUnlock(Bool releaseFlag)
Release a temporary user lock if the given release flag is True.
Definition: ColumnSet.h:360
Abstract base class for a data manager.
Definition: DataManager.h:221
LockType
Define the possible lock types.
Definition: FileLocker.h:95
@ Write
Acquire a write lock.
Definition: FileLocker.h:99
@ Read
Acquire a read lock.
Definition: FileLocker.h:97
Abstract base class to combine multiple files in a single one.
String: the storage and methods of handling collections of characters.
Definition: String.h:225
void autoRelease(Bool always=False)
When the inspection interval has expired, inspect if another process needs the lock.
void release(Bool always=False)
Release the lock.
Bool hasLock(FileLocker::LockType) const
Has this process the read or write lock, thus can the table be read or written safely?
Bool readLocking() const
Is read locking needed?
Definition: TableLock.h:189
this file contains all the compiler specific defines
Definition: mainpage.dox:28
const Bool False
Definition: aipstype.h:44
unsigned int uInt
Definition: aipstype.h:51
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
const Bool True
Definition: aipstype.h:43
uInt64 rownr_t
Define the type of a row number in a table.
Definition: aipsxtype.h:46