Scopira 20080306

directio.h

00001 
00002 /*
00003  *  Copyright (c) 2004-2007    National Research Council
00004  *
00005  *  All rights reserved.
00006  *
00007  *  This material is confidential and proprietary information of
00008  *  National Research Council Canada ("Confidential Information").
00009  *  This Confidential Information may only be used and reproduced
00010  *  in accordance with the terms of the license agreement.
00011  *
00012  */
00013 
00014 #ifndef __INCLUDED_SCOPIRA_BASEKIT_DIRECTIO_H__
00015 #define __INCLUDED_SCOPIRA_BASEKIT_DIRECTIO_H__
00016 
00017 #include <vector>
00018 
00019 #include <scopira/tool/platform.h>
00020 #include <scopira/tool/export.h>
00021 #include <scopira/tool/fileflow.h>
00022 #include <scopira/tool/array.h>
00023 #include <scopira/basekit/narray.h>
00024 
00025 namespace scopira
00026 {
00027   namespace basekit
00028   {
00029     struct directio_header_t;
00030 
00031     SCOPIRA_EXPORT bool save_directio_file_impl(const std::string &filename, short numdimen, const size_t *dimen, size_t elemsize, const char *id, const void *data);
00032     SCOPIRA_EXPORT bool load_directio_file_impl(const std::string &filename, short numdimen, size_t *dimen, size_t elemsize, const char *id, void * &outary);
00033     SCOPIRA_EXPORT bool bind_direct_file_impl(scopira::tool::fileflow *f, scopira::tool::byte_t * &baseary, size_t len, narray_delete_i * &func, bool readonly);
00034     SCOPIRA_EXPORT bool create_directio_file_impl(const std::string &filename, short numdimen, size_t *dimen, size_t elemsize, const char *id);
00035     SCOPIRA_EXPORT bool bind_directio_file_impl(const std::string &filename, short numdimen, size_t *dimen, size_t elemsize, const char *id, bool readonly, void * &outary, narray_delete_i * &outfunc);
00036     SCOPIRA_EXPORT void sync_directio_file(narray_delete_i *d);
00037 
00038     // traits stuff
00039     template <class T> class directio_traints { public: typedef T data_type; };
00040     template <> class directio_traints<float> { public: static const char * get_name(void) { return "float32"; } };
00041     template <> class directio_traints<double> { public: static const char * get_name(void) { return "float64"; } };
00042     template <> class directio_traints<char> { public: static const char * get_name(void) { return "int8"; } };
00043     template <> class directio_traints<short> { public: static const char * get_name(void) { return "int16"; } };
00044     template <> class directio_traints<int> { public: static const char * get_name(void) { return "int32"; } };
00045 
00059     SCOPIRA_EXPORT bool query_directio_file(const std::string &filename,
00060         std::string &elementtype, std::vector<size_t> &dimen);
00061 
00072     template <class T, int DIM>
00073       bool load_directio_file(const std::string &filename,
00074           scopira::basekit::narray<T,DIM> &out) {
00075         nindex<DIM> d;
00076 
00077         void *baseary;
00078         if (!load_directio_file_impl(filename, DIM, d.c_array(), sizeof(T), directio_traints<T>::get_name(), baseary))
00079           return false;
00080         out.resize_direct(d, reinterpret_cast<T*>(baseary), normal_narray_delete);
00081         return true;
00082       }
00083 
00094     template <class T, int DIM>
00095       bool save_directio_file(const std::string &filename,
00096           const scopira::basekit::narray<T,DIM> &in) {
00097         return save_directio_file_impl(filename, DIM, in.dimen().c_array(), sizeof(T), directio_traints<T>::get_name(), in.c_array());
00098       }
00099 
00108     template <class T, int DIM>
00109       bool bind_direct_file(scopira::tool::fileflow *f,
00110           scopira::basekit::nindex<DIM> sz, scopira::basekit::narray<T,DIM> &out, bool readonly = false, scopira::tool::fileflow::offset_t skipb = 0)
00111       {
00112         scopira::tool::byte_t *baseary;
00113         narray_delete_i *func;
00114         out.resize(nindex<DIM>(0));
00115         if (!bind_direct_file_impl(f, baseary, sz.product()*sizeof(T)+skipb, func, readonly))
00116           return false;
00117         baseary += skipb;
00118         out.resize_direct(sz, reinterpret_cast<T*>(baseary), func);
00119         return true;
00120       }
00121 
00136     template <class T, int DIM>
00137       bool inline create_directio_file(const std::string &filename, nindex<DIM> sz)
00138       {
00139         return create_directio_file_impl(filename, DIM, sz.c_array(), sizeof(T), directio_traints<T>::get_name());
00140       }
00158     template <class T, int DIM>
00159       bool bind_directio_file(const std::string &filename, narray<T,DIM> &out, bool readonly = false) {
00160         nindex<DIM> d;
00161 
00162         void *baseary;
00163         narray_delete_i *func;
00164         if (!bind_directio_file_impl(filename, DIM, d.c_array(), sizeof(T), directio_traints<T>::get_name(), readonly, baseary, func))
00165           return false;
00166         out.resize_direct(d, reinterpret_cast<T*>(baseary), func);
00167         return true;
00168       }
00169     template <class T, int DIM>
00170       inline void sync_directio_file(const narray<T,DIM> &out) {
00171         sync_directio_file(out.get_direct());
00172       }
00173 
00174 
00175     class base_directio_slice;
00176     template <class T, int DIM> class directio_slice;
00177   }
00178 }
00179 
00185 class scopira::basekit::base_directio_slice
00186 {
00187   public:
00193     SCOPIRA_EXPORT bool failed(void) const { return dm_file.failed(); }
00194 
00201     size_t size_rows(void) const {
00202       assert(dm_dimen.size()>0);
00203       return dm_dimen[dm_dimen.size()-1];
00204     }
00205 
00206     // add custom load_array(void* ) with auto dm_baseoffset for external slice loading?
00207 
00208   protected:
00210     SCOPIRA_EXPORT base_directio_slice(void);
00211 
00218     SCOPIRA_EXPORT bool open_file(const std::string &filename, bool readonly,
00219         size_t dimlen, size_t elemsize, const char *elemname);
00220 
00221   protected:
00222     SCOPIRA_EXPORT void verify_dimen(const char *elemname, size_t subprod);
00223     SCOPIRA_EXPORT size_t seek_slice(size_t r, size_t elemsize);    // returns rowsize IN elements
00224 
00225   protected:
00226     scopira::tool::fileflow dm_file;
00227     scopira::tool::fileflow::offset_t dm_baseoffset;
00228     scopira::tool::basic_array<size_t> dm_dimen;  //this contains all the dimen of the file, including the last dimention
00229     const char *dm_elemname;
00230     size_t dm_dimenprod;
00231 };
00232 
00238 template <class T, int DIM> class scopira::basekit::directio_slice : public scopira::basekit::base_directio_slice
00239 {
00240   public:
00242     directio_slice(void) { }
00243 
00250     bool open_file(const std::string &filename, bool readonly) {
00251       return base_directio_slice::open_file(filename, readonly, DIM, sizeof(T), directio_traints<T>::get_name());
00252     }
00253 
00259     scopira::basekit::nindex<DIM> dimen(void) const {
00260       assert(DIM == dm_dimen.size());
00261       scopira::basekit::nindex<DIM> ret;
00262 
00263       for (int i=0; i<ret.size(); ++i)
00264         ret[i] = dm_dimen[i];
00265       return ret;
00266     }
00267 
00273     scopira::basekit::nindex<DIM-1> slice_dimen(void) const {
00274       assert(DIM == dm_dimen.size());
00275       scopira::basekit::nindex<DIM-1> ret;
00276 
00277       for (int i=0; i<ret.size(); ++i)
00278         ret[i] = dm_dimen[i];
00279       return ret;
00280     }
00281 
00287     bool load_slice(size_t r, scopira::basekit::narray<T,DIM-1> &out) {
00288       verify_dimen(directio_traints<T>::get_name(), out.dimen().product());
00289       size_t numelem = seek_slice(r, sizeof(T));
00290       return dm_file.read_array(out.c_array(), numelem) == numelem;
00291     }
00292 
00298     bool save_slice(size_t r, scopira::basekit::narray<T,DIM-1> &out) {
00299       verify_dimen(directio_traints<T>::get_name(), out.dimen().product());
00300       size_t numelem = seek_slice(r, sizeof(T));
00301       return dm_file.write_array(out.c_array(), numelem) == numelem;
00302     }
00303 };
00304 
00305 #endif
00306