00001 #include "AIDA_MemoryStore.h"
00002 #include "AIDA_Dev/IDevManagedObject.h"
00003 #include "AIDA_Dev/ITupleFactoryProvider.h"
00004 #include <typeinfo>
00005 #include <set>
00006 #include "AIDA_Dev/IDevAnalysisFactory.h"
00007 #include <memory>
00008 #include "MemoryHistogramCopier.h"
00009 #include "MemoryFunctionCopier.h"
00010 #include "MemoryDataPointSetCopier.h"
00011 #include "MemoryBackingStore.h"
00012
00013 #ifdef MEMORY_STORE_NO_EXCEPTIONS_TO_USER
00014 #include <iostream>
00015 #define MEMORY_STORE_REPORT_ERROR( XXX ) std::cerr << XXX << std::endl
00016 #else
00017 #include <stdexcept>
00018 #define MEMORY_STORE_REPORT_ERROR( XXX ) throw std::runtime_error( XXX )
00019 #endif
00020
00021
00022 Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::AIDA_StoreMemory( const std::string& name ):
00023 m_name( name ),
00024 m_objectTypes(),
00025 m_backingStore( 0 )
00026 {
00027 std::auto_ptr<AIDA::Dev::IDevAnalysisFactory> af( dynamic_cast<AIDA::Dev::IDevAnalysisFactory*>( AIDA_createAnalysisFactory() ) );
00028 if ( af.get() ) {
00029 AIDA::Dev::ITupleFactoryProvider* provider = af->tupleFactoryProvider();
00030 if ( provider ) {
00031 m_backingStore = new Anaphe::AIDA_MemoryStore::MemoryBackingStore( provider->devTupleFactory() );
00032 }
00033 }
00034 }
00035
00036
00037 Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::~AIDA_StoreMemory()
00038 {
00039 if ( m_backingStore ) delete m_backingStore;
00040 }
00041
00042
00043 const std::string&
00044 Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::name() const
00045 {
00046 return m_name;
00047 }
00048
00049
00050 bool
00051 Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::writeObject( const AIDA::IManagedObject& dataObject,
00052 const std::string& path )
00053 {
00054 try {
00055 const AIDA::Dev::IDevManagedObject& object = dynamic_cast< const AIDA::Dev::IDevManagedObject& >( dataObject );
00056 m_objectTypes[ path ] = object.userLevelClassType();
00057
00058
00059 }
00060 catch ( std::bad_cast ) {
00061 return false;
00062 }
00063 return false;
00064 }
00065
00066
00068 AIDA::IManagedObject*
00069 Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::copyAndWrite( const AIDA::IManagedObject& dataObject,
00070 const std::string& path )
00071 {
00072
00073 std::auto_ptr<AIDA::Dev::IDevAnalysisFactory> af( dynamic_cast<AIDA::Dev::IDevAnalysisFactory*>( AIDA_createAnalysisFactory() ) );
00074 if ( ! af.get() ) {
00075 MEMORY_STORE_REPORT_ERROR( "The tree could not instantiate an analysis factory" );
00076 return 0;
00077 }
00078
00079 AIDA::Dev::IDevManagedObject* newObject = 0;
00080
00081 unsigned int pos = path.size();
00082 for ( unsigned int iChar = path.size() - 1; iChar >= 0; --iChar ) {
00083 if ( path[iChar] == '/' ) break;
00084 --pos;
00085 }
00086 const std::string name = path.substr( pos );
00087
00088
00089 const AIDA::Dev::IDevManagedObject& object = dynamic_cast< const AIDA::Dev::IDevManagedObject& >( dataObject );
00090 const std::string& type = object.userLevelClassType();
00091
00092
00093
00094
00095
00096 if ( type == "IHistogram1D" || type == "IHistogram2D" || type == "IHistogram3D" ||
00097 type == "IProfile1D" || type == "IProfile2D" ||
00098 type == "ICloud1D" || type == "ICloud2D" || type == "ICloud3D" ) {
00099 Anaphe::AIDA_MemoryStore::MemoryHistogramCopier hp( *af );
00100 newObject = hp.createCopy( dataObject, type );
00101 }
00102 else if ( type == "IDataPointSet" ) {
00103 Anaphe::AIDA_MemoryStore::MemoryDataPointSetCopier hp( *af );
00104 newObject = hp.createCopy( dataObject );
00105 }
00106 else if ( type == "IFunction" ) {
00107 Anaphe::AIDA_MemoryStore::MemoryFunctionCopier hp( *af );
00108 newObject = hp.createCopy( dataObject );
00109 }
00110
00111
00112
00113
00114 if ( newObject ) {
00115 newObject->setName( name );
00116 writeObject( *newObject, path );
00117 }
00118 return newObject;
00119 }
00120
00121
00122 AIDA::IManagedObject*
00123 Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::retrieveObject( const std::string & path )
00124 {
00125
00126 return 0;
00127 }
00128
00129
00130 bool
00131 Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::removeObject( const std::string& path )
00132 {
00133 m_objectTypes.erase( path );
00134
00135 return true;
00136 }
00137
00138
00139 bool
00140 Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::moveObject(const std::string& from, const std::string& to )
00141 {
00142 std::map< std::string, std::string >::const_iterator sourceObject = m_objectTypes.find( from );
00143 if ( sourceObject == m_objectTypes.end() ) return false;
00144 std::string type = sourceObject->second;
00145 if ( type == "ITuple" ) return false;
00146 m_objectTypes.erase( from );
00147 m_objectTypes.insert( std::make_pair( to, type ) );
00148 return true;
00149 }
00150
00151
00152 std::vector< std::string >
00153 Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::listObjectPaths( const std::string directory,
00154 bool recursive ) const
00155 {
00156 std::string dir = directory;
00157 if ( dir[ dir.size() - 1 ] != '/' ) dir += "/";
00158
00159 std::vector< std::string > result;
00160
00161 std::set< std::string > directorySet;
00162 for ( std::map< std::string, std::string >::const_iterator iObj = m_objectTypes.begin();
00163 iObj != m_objectTypes.end(); ++iObj ) {
00164 const std::string& object = iObj->first;
00165 std::string::size_type p = object.find( dir );
00166 if ( p == 0 ) {
00167 std::string complement = object.substr( dir.size() );
00168
00169 while ( complement.size() > 0 && complement[0] == '/' ) complement = complement.substr( 1 );
00170 if ( complement.size() == 0 ) continue;
00171
00172
00173 std::string::size_type n = complement.find( "/" );
00174 if ( n == std::string::npos ) {
00175 result.push_back( object );
00176 }
00177 else {
00178 directorySet.insert( dir + complement.substr( 0, n ) + "/" );
00179 }
00180 }
00181 }
00182
00183 for ( std::set< std::string >::const_iterator iDir = directorySet.begin();
00184 iDir != directorySet.end(); ++iDir ) {
00185 result.push_back( *iDir );
00186 if ( recursive ) {
00187 std::vector< std::string > subDirResults = listObjectPaths( *iDir, recursive );
00188 for ( unsigned int i = 0; i < subDirResults.size(); ++i ) result.push_back( subDirResults[ i ] );
00189 }
00190 }
00191
00192 return result;
00193 }
00194
00195
00196 std::vector< std::string > Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::listObjectTypes( const std::string directory,
00197 bool recursive ) const
00198 {
00199 std::string dir = directory;
00200 if ( dir[ dir.size() - 1 ] != '/' ) dir += "/";
00201
00202 std::vector< std::string > result;
00203
00204 std::set< std::string > directorySet;
00205 for ( std::map< std::string, std::string >::const_iterator iObj = m_objectTypes.begin();
00206 iObj != m_objectTypes.end(); ++iObj ) {
00207 const std::string& object = iObj->first;
00208 std::string::size_type p = object.find( dir );
00209 if ( p == 0 ) {
00210 std::string complement = object.substr( dir.size() );
00211
00212 while ( complement.size() > 0 && complement[0] == '/' ) complement = complement.substr( 1 );
00213 if ( complement.size() == 0 ) continue;
00214
00215
00216 std::string::size_type n = complement.find( "/" );
00217 if ( n == std::string::npos ) {
00218 result.push_back( iObj->second );
00219 }
00220 else {
00221 directorySet.insert( dir + complement.substr( 0, n ) + "/" );
00222 }
00223 }
00224 }
00225
00226 for ( std::set< std::string >::const_iterator iDir = directorySet.begin();
00227 iDir != directorySet.end(); ++iDir ) {
00228 result.push_back( "dir" );
00229 if ( recursive ) {
00230 std::vector< std::string > subDirResults = listObjectTypes( *iDir, recursive );
00231 for ( unsigned int i = 0; i < subDirResults.size(); ++i ) result.push_back( subDirResults[ i ] );
00232 }
00233 }
00234
00235 return result;
00236 }
00237
00238
00239 bool
00240 Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::commit()
00241 {
00242
00243 return true;
00244 }
00245
00246
00247 bool
00248 Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::close()
00249 {
00250 return true;
00251 }
00252
00253
00254 bool Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::canMoveTuples() const {return false;}
00255 bool Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::canCopyTuples() const {return false;}
00256
00257
00258 bool
00259 Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::writeTupleHeader( AIDA::Dev::ITupleHeader& header )
00260 {
00261 if ( ! m_backingStore ) return false;
00262 else return m_backingStore->writeTupleHeader( header );
00263 }
00264
00265
00266 bool
00267 Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::readTupleHeader( AIDA::Dev::ITupleHeader& header )
00268 {
00269 if ( ! m_backingStore ) return false;
00270 else return m_backingStore->readTupleHeader( header );
00271 }
00272
00273
00274 bool
00275 Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::bindVariable( AIDA::Dev::ITupleHeader& header, int variableIndex )
00276 {
00277 if ( ! m_backingStore ) return false;
00278 else return m_backingStore->bindVariable( header, variableIndex );
00279 }
00280
00281
00282 void*
00283 Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::variableAddress( AIDA::Dev::ITupleHeader& header, int variableIndex )
00284 {
00285 if ( ! m_backingStore ) return 0;
00286 else return m_backingStore->variableAddress( header, variableIndex );
00287 }
00288
00289
00290 const void*
00291 Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::variableAddress( const AIDA::Dev::ITupleHeader& header, int variableIndex ) const
00292 {
00293 if ( ! m_backingStore ) return 0;
00294 else return m_backingStore->variableAddress( header, variableIndex );
00295 }
00296
00297
00298 bool
00299 Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::clearBindings( const AIDA::Dev::ITupleHeader& header )
00300 {
00301 if ( ! m_backingStore ) return false;
00302 else return m_backingStore->clearBindings( header );
00303 }
00304
00305
00306 bool
00307 Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::writeTupleRow( AIDA::Dev::ITupleHeader& header )
00308 {
00309 if ( ! m_backingStore ) return false;
00310 else return m_backingStore->writeTupleRow( header );
00311 }
00312
00313
00314 bool
00315 Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::readTupleRow( AIDA::Dev::ITupleHeader& header )
00316 {
00317 if ( ! m_backingStore ) return false;
00318 else return m_backingStore->readTupleRow( header );
00319 }
00320
00321
00322 bool
00323 Anaphe::AIDA_MemoryStore::AIDA_StoreMemory::resetTuple( AIDA::Dev::ITupleHeader& header )
00324 {
00325 if ( ! m_backingStore ) return false;
00326 else return m_backingStore->resetTuple( header );
00327 }