00001 /* 00002 // $Id: //open/dev/fennel/calculator/WinAggHistogramStrA.cpp#3 $ 00003 // Fennel is a library of data storage and processing components. 00004 // Copyright (C) 2006-2009 The Eigenbase Project 00005 // Copyright (C) 2006-2009 SQLstream, Inc. 00006 // Copyright (C) 2009-2009 LucidEra, Inc. 00007 // 00008 // This program is free software; you can redistribute it and/or modify it 00009 // under the terms of the GNU General Public License as published by the Free 00010 // Software Foundation; either version 2 of the License, or (at your option) 00011 // any later version approved by The Eigenbase Project. 00012 // 00013 // This program is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 // GNU General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU General Public License 00019 // along with this program; if not, write to the Free Software 00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00021 */ 00022 00023 #include "fennel/common/CommonPreamble.h" 00024 #include "fennel/tuple/TupleData.h" 00025 #include "fennel/tuple/TupleDescriptor.h" 00026 #include "fennel/calculator/WinAggHistogramStrA.h" 00027 00028 FENNEL_BEGIN_CPPFILE("$Id: //open/dev/fennel/calculator/WinAggHistogramStrA.cpp#3 $"); 00029 00030 char* 00031 StringDesc::pointer() const 00032 { 00033 assert(StandardTypeDescriptor::isArray(mType)); 00034 assert(pData); 00035 return reinterpret_cast<char*>(const_cast<PBuffer>(pData)); 00036 } 00037 00038 TupleStorageByteLength 00039 StringDesc::stringLength() const 00040 { 00041 assert(StandardTypeDescriptor::isArray(mType)); 00042 return (StandardTypeDescriptor::isVariableLenArray(mType)) ? 00043 cbData : cbStorage; 00044 } 00045 00046 void WinAggHistogramStrA::addRow(RegisterRef<char*>* node) 00047 { 00048 if (!node->isNull()) { 00049 StringDesc desc; 00050 desc.cbStorage = node->storage(); 00051 desc.mType = node->type(); 00052 desc.pData = new FixedBuffer[desc.cbStorage]; 00053 desc.memCopyFrom(*node->getBinding()); 00054 // printf( 00055 // "WinAggHistogramStrA::addRow cbStorage=%d cbData=%d String=%s\n", 00056 // node->storage(),desc.cbData, desc.pData); 00057 00058 // Insert the value into the window 00059 (void) currentWindow.insert(desc); 00060 00061 // Add to the FIFO queue. Another copy of the StringDesc is 00062 // created, but it points to the same memory. 00063 queue.push_back(desc); 00064 } else { 00065 ++nullRows; 00066 } 00067 } 00068 00069 void WinAggHistogramStrA::dropRow(RegisterRef<char*>* node) 00070 { 00071 if (!node->isNull()) { 00072 // create a StringDesc from the node data to supply to the 00073 // search routine 00074 StringDesc desc; 00075 desc.cbStorage = node->storage(); 00076 desc.cbData = node->length(); 00077 desc.mType = node->type(); 00078 desc.pData = reinterpret_cast<PBuffer>(node->pointer()); 00079 // printf( 00080 // "WinAggHistogramStrA::dropRow cbStorage=%d cbData=%d String=%s", 00081 // node->storage(),desc.cbData, desc.pData); 00082 00083 // Search the window for matching entries. It may return more 00084 // than one but we will only delete one. 00085 assert(!currentWindow.empty()); 00086 pair<WinAggData::iterator, WinAggData::iterator> entries = 00087 currentWindow.equal_range(desc); 00088 00089 assert(entries.first != entries.second); // should at least be one 00090 assert(NULL != entries.first->pData); 00091 00092 if (entries.first != entries.second) { 00093 // printf( 00094 // " erasing entry cbStorage=%d cbData=%d String=%s\n", 00095 // entries.first->cbStorage, 00096 // entries.first->cbData, 00097 // entries.first->pData); 00098 if (NULL != entries.first->pData) { 00099 delete [] entries.first->pData; 00100 } 00101 currentWindow.erase(entries.first); 00102 } 00103 00104 // Remove from the FIFO queue. 00105 queue.pop_front(); 00106 } else { 00107 assert(0 != nullRows); 00108 --nullRows; 00109 } 00110 } 00111 00112 void WinAggHistogramStrA::setReturnReg( 00113 RegisterRef<char*>* dest, 00114 const StringDesc& src) 00115 { 00116 char* pData = dest->pointer(); 00117 TupleStorageByteLength srcLength = src.stringLength(); 00118 assert(pData); 00119 assert(srcLength <= dest->storage()); 00120 memcpy(pData, src.pointer(), srcLength); 00121 dest->length(srcLength); 00122 } 00123 00124 00125 void WinAggHistogramStrA::getMin(RegisterRef<char*>* node) 00126 { 00127 if (0 != currentWindow.size()) { 00128 setReturnReg(node, *(currentWindow.begin())); 00129 } else { 00130 // either all the rows added to the window had null 00131 // entries or there are no rows in the window. Either 00132 // way the function returns NULL. 00133 node->toNull(); 00134 } 00135 } 00136 00137 void WinAggHistogramStrA::getMax(RegisterRef<char*>* node) 00138 { 00139 if (0 != currentWindow.size()) { 00140 setReturnReg(node, *(--(currentWindow.end()))); 00141 } else { 00142 // either all the rows added to the window had null 00143 // entries or there are no rows in the window. Either 00144 // way the function returns NULL. 00145 node->toNull(); 00146 } 00147 } 00148 00149 void WinAggHistogramStrA::getFirstValue(RegisterRef<char*>* node) 00150 { 00151 if (queue.empty()) { 00152 node->toNull(); 00153 } else { 00154 setReturnReg(node, queue.front()); 00155 } 00156 } 00157 00158 00159 void WinAggHistogramStrA::getLastValue(RegisterRef<char*>* node) 00160 { 00161 if (queue.empty()) { 00162 node->toNull(); 00163 } else { 00164 setReturnReg(node, queue.back()); 00165 } 00166 } 00167 00168 FENNEL_END_CPPFILE("$Id: //open/dev/fennel/calculator/WinAggHistogramStrA.cpp#3 $"); 00169 00170 // End WinAggHistogramStrA.cpp