Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

Database.h

Go to the documentation of this file.
00001 #ifndef Impala_Util_Database_h
00002 #define Impala_Util_Database_h
00003 
00004 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00005 
00006 #ifdef unix
00007 #include <sys/stat.h>
00008 #include <sys/types.h>
00009 #include <sys/resource.h>
00010 #else
00011 #include <direct.h>
00012 #endif
00013 
00014 #include <vector>
00015 #include "Basis/CmdOptions.h"
00016 #include "Basis/FileNameTmp.h"
00017 #include "Util/ChannelPool.h"
00018 #include "Util/ReadIOBufferFromChannel.h"
00019 #include "Util/IOBufferFile.h"
00020 #include "Util/IOBufferChannel.h"
00021 
00022 namespace Impala
00023 {
00024 namespace Util
00025 {
00026 
00027 
00028 class Database
00029 {
00030 public:
00031 
00032     static Database&
00033     GetInstance()
00034     {
00035         static Database theDatabase;
00036         return theDatabase;
00037     }
00038 
00039     Database()
00040     {
00041         Init("");
00042     }
00043 
00044     Database(String setName)
00045     {
00046         Init(setName);
00047     }
00048 
00049     // For use in data server only : reset data path for new request.
00050     void
00051     SetDataPath(String data)
00052     {
00053         mDataString = data;
00054         mData.clear();
00055         mData = StringList(mDataString, ';');
00056     }
00057 
00058     String
00059     GetDataPath()
00060     {
00061         return mDataString;
00062     }
00063 
00064     // For use in data server only : reset override for new request.
00065     void
00066     SetOverride(bool override)
00067     {
00068         mOverride = override;
00069     }
00070 
00071     // Any data directory part
00072 
00073     String
00074     MakeDir(CString dir)
00075     {
00076         return DoMkDirPath(dir);
00077     }
00078 
00079     String
00080     MakeDir(CString dir1, CString dir2)
00081     {
00082         return MakeDir(ConcatDir(dir1, dir2));
00083     }
00084 
00085     String
00086     MakeDir(CString dir1, CString dir2, CString dir3)
00087     {
00088         return MakeDir(dir1, ConcatDir(dir2, dir3));
00089     }
00090 
00091     String
00092     MakeDir(CString dir1, CString dir2, CString dir3, CString dir4)
00093     {
00094         return MakeDir(dir1, dir2, ConcatDir(dir3, dir4));
00095     }
00096 
00097     String
00098     MakeDir(CString dir1, CString dir2, CString dir3, CString dir4, CString dir5)
00099     {
00100         return MakeDir(dir1, dir2, dir3, ConcatDir(dir4, dir5));
00101     }
00102 
00103     // Any data file part
00104 
00105     String
00106     GetFilePath(CString file, bool toWrite, bool silent)
00107     {
00108         CString path = file;
00109         if (toWrite)
00110             return GetWritableFile(mData.begin(), mData.end(), path, silent);
00111         return GetReadableFile(mData.begin(), mData.end(), path, silent);
00112     }
00113 
00114     String
00115     GetFilePath(CString dir, CString file, bool toWrite, bool silent)
00116     {
00117         String path = dir + "/" + file;
00118         if (toWrite)
00119             return GetWritableFile(mData.begin(), mData.end(), path, silent);
00120         return GetReadableFile(mData.begin(), mData.end(), path, silent);
00121     }
00122 
00123     String
00124     GetFilePath(CString dir1, CString dir2, CString file, bool toWrite,
00125                 bool silent)
00126     {
00127         String path = dir1 + "/" + dir2 + "/" + file;
00128         if (toWrite)
00129             return GetWritableFile(mData.begin(), mData.end(), path, silent);
00130         return GetReadableFile(mData.begin(), mData.end(), path, silent);
00131     }
00132 
00133     String
00134     GetFilePath(CString dir1, CString dir2, CString dir3, CString file,
00135                 bool toWrite, bool silent)
00136     {
00137         String path = dir1 + "/" + dir2 + "/" + dir3 + "/" + file;
00138         if (toWrite)
00139             return GetWritableFile(mData.begin(), mData.end(), path, silent);
00140         return GetReadableFile(mData.begin(), mData.end(), path, silent);
00141     }
00142 
00143     String
00144     GetFilePath(CString dir1, CString dir2, CString dir3, CString dir4,
00145                 CString file, bool toWrite, bool silent)
00146     {
00147         String path = dir1 + "/" + dir2 + "/" + dir3 + "/" + dir4 + "/" + file;
00148         if (toWrite)
00149             return GetWritableFile(mData.begin(), mData.end(), path, silent);
00150         return GetReadableFile(mData.begin(), mData.end(), path, silent);
00151     }
00152 
00153     String
00154     GetFilePath(CString dir1, CString dir2, CString dir3, CString dir4,
00155                 CString dir5, CString file, bool toWrite, bool silent)
00156     {
00157         String path = dir1 + "/" + dir2 + "/" + dir3 + "/" + dir4 + "/"
00158             + dir5 + "/" + file;
00159         if (toWrite)
00160             return GetWritableFile(mData.begin(), mData.end(), path, silent);
00161         return GetReadableFile(mData.begin(), mData.end(), path, silent);
00162     }
00163 
00183     IOBuffer*
00184     GetIOBuffer(CString fileName, bool readMode, bool useMemoryIfLocal,
00185                 String useLocalFileIfRemote, Int64 useLocalSizeIfRemote = 0,
00186                 bool useIOBufferChannel = false)
00187     {
00188         IOBuffer* res = 0;
00189         ILOG_DEBUG("GetIOBuffer [" << fileName << "]");
00190         if (mDataChannel)
00191         {
00192             if (readMode)
00193             {
00194                 if (useIOBufferChannel)
00195                 {
00196                     ILOG_DEBUG("GetIOBuffer: Read using Channel to " <<
00197                                mDataServer << ": " << fileName);
00198                     res = new IOBufferChannel(fileName, true, mDataChannel);
00199                 }
00200                 else
00201                 {
00202                     ILOG_DEBUG("GetIOBuffer: Read using File: " << fileName);
00203                     /* the race condition that occurs when someone passes in
00204                        "tmp" while reading a file is very difficult to track
00205                        down (only happens with MPI-jobs). Therefore, generate 
00206                        a temporary filename even in read mode */
00207                     if (useLocalFileIfRemote == "tmp")
00208                         useLocalFileIfRemote = FileNameTmp();
00209                     res = ReadIOBufferFromChannel(mDataChannel, fileName,
00210                                                   useLocalFileIfRemote);
00211                 }
00212             }
00213             else
00214             {
00215                 if (useIOBufferChannel)
00216                 {
00217                     ILOG_DEBUG("GetIOBuffer: Write using Channel " << fileName);
00218                     res = new IOBufferChannel(fileName, false, mDataChannel);
00219                 }
00220                 else if (useLocalFileIfRemote.empty())
00221                 {
00222                     ILOG_DEBUG("GetIOBuffer: Write using mem " << fileName);
00223                     res = new IOBuffer(useLocalSizeIfRemote);
00224                 }
00225                 else
00226                 {
00227                     ILOG_DEBUG("GetIOBuffer: Write using File " << fileName);
00228                     if (useLocalFileIfRemote == "tmp")
00229                         useLocalFileIfRemote = FileNameTmp();
00230                     res = new IOBufferFile(useLocalFileIfRemote, false, false);
00231                 }
00232                 if (!useIOBufferChannel)
00233                     res->SetUseChannel(mDataChannel, fileName,
00234                                        useLocalFileIfRemote);
00235             }
00236         }
00237         else
00238         {
00239             res = new IOBufferFile(fileName, readMode, useMemoryIfLocal);
00240         }
00241 
00242         if (res)
00243         {
00244             if (!res->Valid())
00245             {
00246                 delete res;
00247                 res = 0;
00248             }
00249         }
00250         return res;
00251     }
00252 
00253     Channel*
00254     GetDataChannel()
00255     {
00256         return mDataChannel;
00257     }
00258 
00259     void
00260     Dump() const
00261     {
00262         ILOG_INFO_ONCE("Dump: data=[" << mDataString << "] server=[" <<
00263                        mDataServer << "]");
00264     }
00265 
00266 private:
00267 
00268     void
00269     Init(String setName)
00270     {
00271         CmdOptions& options = CmdOptions::GetInstance();
00272         mDataString = StringReplaceAll(options.GetString("data"), ":", ";", false);
00273         ILOG_DEBUG("'data' option externally specified: " << mDataString);
00274         String additionalData = options.GetString("data::"+setName, "");
00275         if (additionalData.empty() && !setName.empty())
00276             additionalData = "../" + FileNameBase(setName);
00277         if (!additionalData.empty())
00278         {
00279             mDataString = additionalData + ";" + mDataString;
00280             ILOG_INFO_ONCE("'data' option for " << setName <<
00281                            " has been extended: " << mDataString);
00282         }
00283         mData = StringList(mDataString, ';');
00284         mDataServer = options.GetString("dataServer");
00285         String replaceDataServer = options.GetString("dataServer::"+setName, "");
00286         if (!replaceDataServer.empty())
00287         {
00288             mDataServer = replaceDataServer;
00289             ILOG_INFO_ONCE("server for " << setName << " is " << mDataServer);
00290         }
00291         mDataChannel = 0;
00292         if (!mDataServer.empty())
00293         {
00294             ILOG_INFO_ONCE("Retrieving channel to server " << mDataServer);
00295             String passFile = options.GetString("passwordFile");
00296             mDataChannel = ChannelPool::Instance().Get(mDataServer, passFile);
00297         }
00298         mOverride = options.GetBool("override");
00299 #ifdef WIN32
00300         // printf("%d\n", _getmaxstdio()); // normally 512
00301         _setmaxstdio(2048); // set it to the absolute maximum
00302 #endif
00303 #ifdef unix
00304         rlimit lim;
00305         getrlimit(RLIMIT_NOFILE, &lim);
00306         lim.rlim_cur = 2048; // will succeed on image, down to 1024(?) on linux
00307         setrlimit(RLIMIT_NOFILE, &lim);
00308 #endif
00309     }
00310 
00311     // Utilities
00312 
00313     void
00314     DoMkDir(CString dir)
00315     {
00316 #ifdef unix
00317         mode_t m = 0755;
00318         mkdir(dir.c_str(), m);
00319 #else
00320         mkdir(dir.c_str());
00321 #endif
00322     }
00323 
00324     String
00325     DoMkDirPath(CString dir)
00326     {
00327         if (mDataChannel)
00328             return DoMkDirPathServer(dir);
00329 
00330         return DoMkDirPathLocal(ConcatDir(*mData.begin(), dir));
00331     }
00332 
00333     String
00334     DoMkDirPathLocal(CString dirWithBackSlashes)
00335     {
00336         String dir = StringReplaceAll(dirWithBackSlashes, "\\", "/");
00337         ILOG_DEBUG("DoMkDirPath: " << dir);
00338         StringList subDirs(dir, '/');
00339         String path("");
00340         if (dir[0] == '/')
00341             path = String("/");
00342         for (StringListCI i=subDirs.begin() ; i!=subDirs.end() ; i++)
00343         {
00344             CString subDir = *i;
00345             ILOG_DEBUG("  DoMkDirPath: subDir = " << subDir);
00346             if (subDir.size() == 0)
00347                 continue;
00348             if ((path.size() > 0) && (*path.rbegin() != '/'))
00349                 path = path + "/";
00350             path = path + *i;
00351             DoMkDir(path);
00352         }
00353         return path;
00354     }
00355 
00356     String
00357     DoMkDirPathServer(CString dir)
00358     {
00359         char* buf = mDataChannel->Buffer();
00360         sprintf(buf, "domkdirpath \"%s\" \"%s\"\0", dir.c_str(), mDataString.c_str());
00361         int len = mDataChannel->SendRequest(strlen(buf)+1);
00362         if (mDataChannel->LastSendHadError())
00363             return "";
00364         buf[len] = 0;
00365         String res(buf);
00366         ILOG_DEBUG("Got dir [" << res << "]");
00367         return res;
00368     }
00369 
00370     String
00371     GetReadableFile(StringListCI begin, StringListCI end, CString file,
00372                     bool silent)
00373     {
00374         if (mDataChannel)
00375             return GetReadableFileServer(file, silent);
00376         return GetReadableFileLocal(begin, end, file, silent);
00377     }
00378 
00379     String
00380     GetReadableFileLocal(StringListCI begin, StringListCI end, CString file,
00381                          bool silent)
00382     {
00383         StringListCI i;
00384         for (i=begin ; i!=end ; i++)
00385         {
00386             String path = *i + "/" + file;
00387             ILOG_DEBUG("GetReadableFile: trying " << path);
00388             if (IOBufferFile::FileExists(path))
00389                 return path;
00390         }
00391 
00392         if (!silent)
00393         {
00394             ILOG_ERROR("Unable to find " << file << " in path ");
00395             for (i=begin ; i!=end ; i++)
00396                 ILOG_INFO("    " << *i);
00397         }
00398         return String("");
00399     }
00400 
00401     String
00402     GetReadableFileServer(CString file, bool silent)
00403     {
00404         char* buf = mDataChannel->Buffer();
00405         sprintf(buf, "getreadablefile \"%s\" \"%s\" %d\0", file.c_str(),
00406                 mDataString.c_str(), silent);
00407         int len = mDataChannel->SendRequest(strlen(buf)+1);
00408         if (mDataChannel->LastSendHadError())
00409             return "";
00410         buf[len] = 0;
00411         String res(buf);
00412         ILOG_DEBUG("Got file [" << res << "] from " << mDataServer);
00413         return res;
00414     }
00415 
00416     String
00417     GetWritableFile(StringListCI begin, StringListCI end, CString file,
00418                     bool silent)
00419     {
00420         if (mDataChannel)
00421             return GetWritableFileServer(file, silent);
00422         return GetWritableFileLocal(begin, end, file, silent);
00423     }
00424 
00425     String
00426     GetWritableFileLocal(StringListCI begin, StringListCI end, CString file,
00427                          bool silent)
00428     {
00429         if (begin == end)
00430         {
00431             ILOG_ERROR("GetWritableFile: no search path");
00432             return String("");
00433         }
00434         String path = *begin + "/" + file;
00435         ILOG_DEBUG("GetWritableFile: trying " << path);
00436         if (IOBufferFile::FileExists(path))
00437         {
00438             if (! mOverride)
00439             {
00440                 if (!silent)
00441                     ILOG_ERROR(path << " already exists, will not override!");
00442                 return String("");
00443             }
00444         }
00445         return path;
00446     }
00447 
00448     String
00449     GetWritableFileServer(CString file, bool silent)
00450     {
00451         char* buf = mDataChannel->Buffer();
00452         sprintf(buf, "getwritablefile \"%s\" \"%s\" %d %d\0", file.c_str(),
00453                 mDataString.c_str(), silent, mOverride);
00454         int len = mDataChannel->SendRequest(strlen(buf)+1);
00455         if (mDataChannel->LastSendHadError())
00456             return "";
00457         buf[len] = 0;
00458         String res(buf);
00459         ILOG_DEBUG("Got file [" << res << "] from " << mDataServer);
00460         return res;
00461     }
00462 
00463     String ConcatDir(CString dir, CString subDir)
00464     {
00465         return (subDir.empty() ? dir : (dir.empty() ? subDir : (dir + "/" + subDir)));
00466     }
00467 
00468     bool        mOverride;
00469     String      mDataString;
00470     StringList  mData;
00471     String      mDataServer;
00472     Channel*    mDataChannel;
00473 
00474     ILOG_VAR_DEC;
00475 };
00476 
00477 ILOG_VAR_INIT(Database, Impala.Util);
00478 
00479 } // namespace Util
00480 } // namespace Impala
00481 
00482 #endif // REPOSITORY_USED
00483 
00484 #endif

Generated on Fri Mar 19 09:31:46 2010 for ImpalaSrc by  doxygen 1.5.1