1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // CegoOrderSpace.cc
4 // -----------------
5 // Cego order space implementation
6 //
7 // Design and Implementation by Bjoern Lemke
8 //
9 // (C)opyright 2000-2019 Bjoern Lemke
10 //
11 // IMPLEMENTATION MODULE
12 //
13 // Class: CegoOrderSpace
14 //
15 // Description: Utility class for tuple sorting
16 //
17 // Status: CLEAN
18 //
19 ///////////////////////////////////////////////////////////////////////////////
20 
21 // LFC INCLUDES
22 #include <lfcbase/Exception.h>
23 
24 // CEGO INCLUDES
25 #include "CegoOrderSpace.h"
26 #include "CegoDataType.h"
27 #include "CegoTableManager.h"
28 
29 #include <string.h>
30 #include <stdlib.h>
31 
CegoOrderSpace()32 CegoOrderSpace::CegoOrderSpace()
33 {
34     _pAVL = new AVLTreeT<CegoOrderNode>;
35 }
36 
~CegoOrderSpace()37 CegoOrderSpace::~CegoOrderSpace()
38 {
39     if ( _pAVL )
40 	delete _pAVL;
41 }
42 
initOrderSpace(ListT<CegoExpr * > * pOrderList,ListT<CegoOrderNode::Ordering> * pOrderOptList,unsigned long long maxOrderSize)43 void CegoOrderSpace::initOrderSpace(ListT<CegoExpr*>* pOrderList, ListT<CegoOrderNode::Ordering>* pOrderOptList, unsigned long long maxOrderSize)
44 {
45     _schemaSet = false;
46     _pOrderList = pOrderList;
47     _pOrderOptList = pOrderOptList;
48     _maxOrderSize = maxOrderSize;
49     _orderSize = 0;
50 
51     CegoExpr **pExpr = pOrderList->First();
52     int id=1;
53     while ( pExpr )
54     {
55 	ListT<CegoAggregation*> aggList = (*pExpr)->getAggregationList();
56 	if ( aggList.Size() == 0 )
57 	{
58 	    // if no aggregation, we take all used attributes in order schema
59 
60 	    ListT<CegoAttrDesc*> attrRefList = (*pExpr)->getAttrRefList();
61 
62 	    CegoAttrDesc** pAttrRef = attrRefList.First();
63 
64 	    while ( pAttrRef )
65 	    {
66 		CegoField f((*pAttrRef)->getTableName(), (*pAttrRef)->getAttrName());
67 		f.setId(id);
68 		_orderSchema.Insert(f);
69 		id++;
70 		pAttrRef = attrRefList.Next();
71 	    }
72 	}
73 	else
74 	{
75 	    // if aggregation, this is a grouping order, we just take the aggregated values
76 
77 	    CegoAggregation **pAgg = aggList.First();
78 	    while ( pAgg )
79 	    {
80 		CegoField f;
81 		f.setAttrName("AGG");
82 		f.setId((*pAgg)->getAggregationId());
83 		_orderSchema.Insert(f);
84 
85 		pAgg = aggList.Next();
86 	    }
87 	}
88 	pExpr = pOrderList->Next();
89     }
90 }
91 
insertTuple(ListT<CegoField> & orderKey,ListT<CegoField> & orderTuple)92 void CegoOrderSpace::insertTuple(ListT<CegoField>& orderKey, ListT<CegoField>& orderTuple)
93 {
94     if ( _schemaSet == false )
95     {
96 	_selectSchema = orderTuple;
97 	_schemaSet = true;
98     }
99 
100     CegoField* pKF = orderKey.First();
101     CegoField* pOF = _orderSchema.First();
102     while (pKF && pOF )
103     {
104         pKF->setId(pOF->getId());
105         pKF = orderKey.Next();
106         pOF = _orderSchema.Next();
107     }
108 
109     ListT<CegoFieldValue> localTuple;
110 
111     int orderEntryLen = 0;
112 
113     CegoField *pF = orderTuple.First();
114     while (pF)
115     {
116 	CegoFieldValue fv = pF->getValue().getLocalCopy();
117 	localTuple.Insert(fv);
118 
119 	// calculate entry size
120 	orderEntryLen += fv.usedMemory();
121 
122 	pF = orderTuple.Next();
123     }
124 
125     ListT<CegoFieldValue> localKey;
126 
127     CegoExpr **pExpr = _pOrderList->First();
128     while ( pExpr )
129     {
130 	setAggregationValue(*pExpr, orderKey);
131 
132 	(*pExpr)->setFieldListArray(&orderKey);
133 
134 	(*pExpr)->clearAttrCache();
135 
136 	CegoFieldValue fv = (*pExpr)->evalFieldValue().getLocalCopy();
137 
138 	localKey.Insert(fv);
139 
140 	// calculate entry size
141 	orderEntryLen += fv.usedMemory();
142 
143 	pExpr = _pOrderList->Next();
144     }
145 
146     CegoOrderNode n(localKey, localTuple, _pOrderOptList);
147     _orderSize += orderEntryLen;
148 
149     if ( _orderSize > _maxOrderSize )
150     {
151 	throw Exception(EXLOC, "Order size exceeded");
152     }
153 
154     _pAVL->Insert(n);
155 }
156 
resetOrderSpace()157 void CegoOrderSpace::resetOrderSpace()
158 {
159     _pAVL->Empty();
160     _orderSize = 0;
161 }
162 
getCursor()163 CegoOrderCursor* CegoOrderSpace::getCursor()
164 {
165     CegoOrderCursor *pOC = new CegoOrderCursor(_pAVL, _selectSchema);
166     return pOC;
167 }
168 
numAllocated() const169 unsigned long long CegoOrderSpace::numAllocated() const
170 {
171     return _orderSize;
172 }
173 
setAggregationValue(CegoExpr * pExpr,ListT<CegoField> & fl)174 void CegoOrderSpace::setAggregationValue(CegoExpr *pExpr, ListT<CegoField>& fl)
175 {
176     ListT<CegoAggregation*> aggList = pExpr->getAggregationList();
177 
178     CegoAggregation **pAgg = aggList.First();
179     while ( pAgg )
180     {
181 	CegoField *pF = fl.First();
182 	while ( pF )
183 	{
184 	    if ( pF->getId() == (*pAgg)->getAggregationId() )
185 	    {
186 		(*pAgg)->setFieldValue(pF->getValue());
187 		pF = 0;
188 	    }
189 	    else
190 	    {
191 		pF = fl.Next();
192 	    }
193 	}
194 	pAgg = aggList.Next();
195     }
196 }
197