00001 #ifndef Impala_Core_Matrix_VirtualMatrixIOBufferWriter_h
00002 #define Impala_Core_Matrix_VirtualMatrixIOBufferWriter_h
00003
00004 #include "Core/Matrix/VirtualMatrix.h"
00005 #include "Util/IOBuffer.h"
00006 #include "Core/Array/ReadRaw.h"
00007
00008 namespace Impala
00009 {
00010 namespace Core
00011 {
00012 namespace Matrix
00013 {
00014
00015
00016 class VirtualMatrixIOBufferWriter : public VirtualMatrix
00017 {
00018 public:
00019
00020 VirtualMatrixIOBufferWriter(int nrRow, int nrCol, Util::IOBuffer* buffer,
00021 bool ownBuffer, bool write32, bool preWrite)
00022 {
00023 Init(nrRow, nrCol, buffer, ownBuffer, write32, preWrite);
00024 }
00025
00026 virtual
00027 ~VirtualMatrixIOBufferWriter()
00028 {
00029 if (mOwnBuffer)
00030 {
00031 delete mIOBuffer;
00032 mIOBuffer = 0;
00033 }
00034 }
00035
00036 virtual int
00037 NrRow()
00038 {
00039 return mNrRow;
00040 }
00041
00042 virtual int
00043 NrCol()
00044 {
00045 return mNrCol;
00046 }
00047
00048 private:
00049
00050 virtual bool
00051 HasGetRowImplReal64()
00052 {
00053 return false;
00054 }
00055
00056 virtual bool
00057 HasGetRowImplReal32()
00058 {
00059 return false;
00060 }
00061
00062 virtual bool
00063 HasAddRowImplReal64()
00064 {
00065
00066 return !mWrite32;
00067 }
00068
00069 virtual int
00070 AddRowImpl(int rowNr, Real64* buffer)
00071 {
00072 if (mWrite32)
00073 return AddRowConv<Real64,Real32>(rowNr, buffer);
00074 return AddRowDirect(rowNr, buffer);
00075 }
00076
00077 virtual int
00078 AddRowPartImpl(int rowNr, int colNr, Real64* buffer, int bufSize)
00079 {
00080 if (mWrite32)
00081 return AddRowPartConv<Real64,Real32>(rowNr, colNr, buffer, bufSize);
00082 return AddRowPartDirect(rowNr, colNr, buffer, bufSize);
00083 }
00084
00085 virtual bool
00086 HasAddRowImplReal32()
00087 {
00088
00089 return mWrite32;
00090 }
00091
00092 virtual int
00093 AddRowImpl(int rowNr, Real32* buffer)
00094 {
00095 if (mWrite32)
00096 return AddRowDirect(rowNr, buffer);
00097 return AddRowConv<Real32,Real64>(rowNr, buffer);
00098 }
00099
00100 virtual int
00101 AddRowPartImpl(int rowNr, int colNr, Real32* buffer, int bufSize)
00102 {
00103 if (mWrite32)
00104 return AddRowPartDirect(rowNr, colNr, buffer, bufSize);
00105 return AddRowPartConv<Real32,Real64>(rowNr, colNr, buffer, bufSize);
00106 }
00107
00108 virtual int
00109 GetDiagonalImpl(Real64* buffer, int bufferSize)
00110 {
00111 ILOG_ERROR("[GetDiagonalImpl] Not implemented");
00112 return 0;
00113 }
00114
00115 template<class SrcT, class DstT>
00116 int
00117 AddRowConv(int rowNr, SrcT* buffer)
00118 {
00119 int nr = NrCol();
00120 DstT* tmpBuf = new DstT[nr];
00121 for (int i=0 ; i<nr ; i++)
00122 tmpBuf[i] = static_cast<DstT>(buffer[i]);
00123 int res = AddRowDirect(rowNr, tmpBuf);
00124 delete tmpBuf;
00125 return res;
00126 }
00127
00128 template<class SrcT, class DstT>
00129 int
00130 AddRowPartConv(int rowNr, int colNr, SrcT* buffer, int bufSize)
00131 {
00132 DstT* tmpBuf = new DstT[bufSize];
00133 for (int i=0 ; i<bufSize ; i++)
00134 tmpBuf[i] = static_cast<DstT>(buffer[i]);
00135 int res = AddRowPartDirect(rowNr, colNr, tmpBuf, bufSize);
00136 delete tmpBuf;
00137 return res;
00138 }
00139
00140 template<class DstT>
00141 int
00142 AddRowDirect(int rowNr, DstT* buffer)
00143 {
00144 if (mPreWrite)
00145 {
00146 mIOBuffer->SetPosition(mBaseOffset + 200 + rowNr * mLineSize);
00147 }
00148 else
00149 {
00150 if (mExpectedRow != rowNr)
00151 {
00152 ILOG_ERROR("Cannot write: Unexpected row");
00153 return 0;
00154 }
00155 mExpectedRow++;
00156 }
00157 mIOBuffer->Write(buffer, mLineSize);
00158 return NrCol();
00159 }
00160
00161 template<class DstT>
00162 int
00163 AddRowPartDirect(int rowNr, int colNr, DstT* buffer, int bufSize)
00164 {
00165 if (!mPreWrite)
00166 {
00167 ILOG_ERROR("AddRowPartDirect only works with preWrite");
00168 return 0;
00169 }
00170
00171 Int64 offset = rowNr * mLineSize + colNr * mStorTypeSize;
00172 mIOBuffer->SetPosition(mBaseOffset + 200 + offset);
00173 Int64 bufWriteSize = bufSize * mStorTypeSize;
00174 mIOBuffer->Write(buffer, bufWriteSize);
00175 return bufWriteSize;
00176 }
00177
00178 template<class DstT>
00179 void
00180 PreWriteRows()
00181 {
00182 DstT* buffer = new DstT[NrCol()];
00183 for (int i=0 ; i<NrCol() ; i++)
00184 buffer[i] = 0;
00185 for (int i=0 ; i<NrRow() ; i++)
00186 AddRowDirect(i, buffer);
00187 delete buffer;
00188 }
00189
00190 void
00191 Init(int nrRow, int nrCol, Util::IOBuffer* buffer, bool ownBuffer,
00192 bool write32, bool preWrite)
00193 {
00194 mNrRow = nrRow;
00195 mNrCol = nrCol;
00196 mIOBuffer = buffer;
00197 mOwnBuffer = ownBuffer;
00198 mBaseOffset = mIOBuffer->GetPosition();
00199 mWrite32 = write32;
00200 mStorTypeSize = (write32) ? 4 : 8;
00201 mLineSize = mNrCol * mStorTypeSize;
00202 mPreWrite = preWrite;
00203
00204 String typeStr = (mWrite32) ? "real32" : "real64";
00205 String formatStr = "version: 1, binary: 1, type: " + typeStr +
00206 ", elemSize: %lld, width: %lld, height: %lld, nr: %lld";
00207 Int64 elemSize = 1;
00208 Int64 nrA = 1;
00209
00210 char buf[200];
00211 memset(buf, 0, 200);
00212 sprintf(buf, formatStr.c_str(), elemSize, mNrCol, mNrRow, nrA);
00213 buffer->Write(buf, 200);
00214 if (mPreWrite)
00215 {
00216 if (mWrite32)
00217 PreWriteRows<Real32>();
00218 else
00219 PreWriteRows<Real64>();
00220 mExpectedRow = -1;
00221 }
00222 else
00223 {
00224 mExpectedRow = 0;
00225 }
00226 }
00227
00228 Int64 mNrRow;
00229 Int64 mNrCol;
00230 Util::IOBuffer* mIOBuffer;
00231 bool mOwnBuffer;
00232 Int64 mBaseOffset;
00233 bool mWrite32;
00234 Int64 mStorTypeSize;
00235 Int64 mLineSize;
00236 bool mPreWrite;
00237 Int64 mExpectedRow;
00238
00239 ILOG_VAR_DEC;
00240 };
00241
00242 ILOG_VAR_INIT(VirtualMatrixIOBufferWriter, Impala.Core.Matrix);
00243
00244 }
00245 }
00246 }
00247
00248 #endif