1 /* Copyright (C) 2014 InfiniDB, Inc.
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; version 2 of
6 the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16 MA 02110-1301, USA. */
17
18 /*****************************************************************************
19 * $Id: we_colbufmgrdctnry.cpp 4726 2013-08-07 03:38:36Z bwilkinson $
20 *
21 ****************************************************************************/
22
23 #include "we_colbufmgr.h"
24 #include "we_columninfo.h"
25 #include "we_log.h"
26 #include <iostream>
27 #include <sstream>
28
29 namespace WriteEngine
30 {
31
32 //------------------------------------------------------------------------------
33 // ColumnBufferManagerDctnry constructor that takes a ColumnInfo, colWidth, and
34 // FILE*.
35 //------------------------------------------------------------------------------
ColumnBufferManagerDctnry(ColumnInfo * pColInfo,int colWidth,Log * logger,int compressionType)36 ColumnBufferManagerDctnry::ColumnBufferManagerDctnry(
37 ColumnInfo* pColInfo, int colWidth, Log* logger, int compressionType) :
38 ColumnBufferManager(pColInfo, colWidth, logger, compressionType)
39 {
40 }
41
42 //------------------------------------------------------------------------------
43 // ColumnBufferManagerDctnry destructor.
44 //------------------------------------------------------------------------------
~ColumnBufferManagerDctnry()45 ColumnBufferManagerDctnry::~ColumnBufferManagerDctnry()
46 {
47 }
48
49 //------------------------------------------------------------------------------
50 // If we wanted to intercept the row data being written out by
51 // ColumnBufferManagerDctnry in order to break up any buffer crossing an
52 // extent boundary, this is where that logic would reside. However, for
53 // dictionary columns we perform this extent division up front. So for a
54 // dictionary column, this function is a simple pass-thru to the ColumnBuffer's
55 // writeToFile() function.
56 // The data to be written, starts at "startOffset" in the internal buffer and
57 // is "writeSize" bytes long.
58 //------------------------------------------------------------------------------
writeToFileExtentCheck(uint32_t startOffset,uint32_t writeSize)59 int ColumnBufferManagerDctnry::writeToFileExtentCheck(
60 uint32_t startOffset, uint32_t writeSize)
61 {
62 if (fLog->isDebug( DEBUG_3 ))
63 {
64 std::ostringstream oss;
65 oss << "Dctnry writeToFileExtentCheck"
66 ": OID-" << fColInfo->curCol.dataFile.fid <<
67 "; DBRoot-" << fColInfo->curCol.dataFile.fDbRoot <<
68 "; part-" << fColInfo->curCol.dataFile.fPartition <<
69 "; seg-" << fColInfo->curCol.dataFile.fSegment <<
70 "; writeSize-" << writeSize <<
71 "; oldAvailFileSize-" << fColInfo->availFileSize <<
72 "; newAvailFileSize-" << (fColInfo->availFileSize - writeSize);
73 fLog->logMsg( oss.str(), MSGLVL_INFO2 );
74 }
75
76 int rc = fCBuf->writeToFile(startOffset, writeSize);
77
78 if (rc != NO_ERROR)
79 {
80 WErrorCodes ec;
81 std::ostringstream oss;
82 oss << "writeToFileExtentCheck: write token extent failed: " <<
83 ec.errorString(rc);
84 fLog->logMsg( oss.str(), rc, MSGLVL_ERROR );
85 return rc;
86 }
87
88 fColInfo->updateBytesWrittenCounts( writeSize );
89
90 return NO_ERROR;
91 }
92
93 //------------------------------------------------------------------------------
94 // Before a section is reserved to contain "nRows" of incoming data, this
95 // function can be called to determine whether this group of rows will cause
96 // the buffer to cross an extent boundary. If there is not room for "nRows",
97 // the number of rows that will fit in the current extent are returned.
98 // This function also catches and handles the case where an abbreviated
99 // extent needs to be expanded to a full extent on disk.
100 //
101 // WARNING: If the extent is expanded, then this function will change the
102 // information in the ColumnInfo struct that owns this
103 // ColumnBufferManagerDctnry.
104 //------------------------------------------------------------------------------
rowsExtentCheck(int nRows,int & nRows2)105 int ColumnBufferManagerDctnry::rowsExtentCheck( int nRows, int& nRows2 )
106 {
107 nRows2 = nRows;
108
109 int bufferSize = fCBuf->getSize();
110 long long spaceRequired = nRows * fColWidth;
111 long dataInBuffer = 0;
112
113 if (bufferSize > 0)
114 dataInBuffer = (fBufFreeOffset - fBufWriteOffset + bufferSize) % bufferSize;
115
116 // if extent is out of space, see if this is an abbrev extent we can expand
117 if (((dataInBuffer + spaceRequired) > fColInfo->availFileSize) &&
118 (fColInfo->isAbbrevExtent()))
119 {
120 RETURN_ON_ERROR( fColInfo->expandAbbrevExtent(true) )
121 }
122
123 if ((dataInBuffer + spaceRequired) > fColInfo->availFileSize)
124 {
125 spaceRequired = fColInfo->availFileSize - dataInBuffer;
126 nRows2 = (int)(spaceRequired / fColWidth);
127
128 if (fLog->isDebug( DEBUG_1 ))
129 {
130 std::ostringstream oss1;
131 oss1 << "Dctnry rowsExtentCheck (filling extent): OID-" <<
132 fColInfo->curCol.dataFile.fid <<
133 "; DBRoot-" << fColInfo->curCol.dataFile.fDbRoot <<
134 "; part-" << fColInfo->curCol.dataFile.fPartition <<
135 "; seg-" << fColInfo->curCol.dataFile.fSegment <<
136 "; spaceRequired-" << spaceRequired <<
137 "; dataInBuffer-" << dataInBuffer <<
138 "; availSpace-" << fColInfo->availFileSize;
139 fLog->logMsg( oss1.str(), MSGLVL_INFO2 );
140
141 std::ostringstream oss2;
142 oss2 << "Dctnry rowsExtentCheck: OID-" <<
143 fColInfo->curCol.dataFile.fid <<
144 "; DBRoot-" << fColInfo->curCol.dataFile.fDbRoot <<
145 "; part-" << fColInfo->curCol.dataFile.fPartition <<
146 "; seg-" << fColInfo->curCol.dataFile.fSegment <<
147 "; Changing nRows from " << nRows << " to " << nRows2;
148 fLog->logMsg( oss2.str(), MSGLVL_INFO2 );
149 }
150 }
151 else
152 {
153 if (fLog->isDebug( DEBUG_2 ))
154 {
155 std::ostringstream oss;
156 oss << "Dctnry rowsExtentCheck: OID-" <<
157 fColInfo->curCol.dataFile.fid <<
158 "; DBRoot-" << fColInfo->curCol.dataFile.fDbRoot <<
159 "; part-" << fColInfo->curCol.dataFile.fPartition <<
160 "; seg-" << fColInfo->curCol.dataFile.fSegment <<
161 "; spaceRequired-" << spaceRequired <<
162 "; dataInBuffer-" << dataInBuffer <<
163 "; availSpace-" << fColInfo->availFileSize;
164 fLog->logMsg( oss.str(), MSGLVL_INFO2 );
165 }
166 }
167
168 return NO_ERROR;
169 }
170
171 }
172