1 #ifndef CPPAD_CG_ARRAY_COMPRESSER_INCLUDED 2 #define CPPAD_CG_ARRAY_COMPRESSER_INCLUDED 32 std::map<size_t, size_t> _freeArrayStartSpace;
36 std::map<size_t, size_t> _freeArrayEndSpace;
40 std::vector<const Argument<Base>*> _tmpArrayValues;
56 size_t maxArraySize) :
57 _tmpArrayValues(maxArraySize, nullptr),
62 inline size_t getIdCount()
const {
67 size_t arrayStart = _varId[released] - 1;
71 size_t arrayEnd = arrayStart + arraySize - 1;
73 std::map<size_t, size_t>::iterator it;
76 it = _freeArrayEndSpace.find(arrayStart - 1);
77 if (it != _freeArrayEndSpace.end()) {
78 arrayStart = it->second;
79 _freeArrayEndSpace.erase(it);
80 _freeArrayStartSpace.erase(arrayStart);
85 it = _freeArrayStartSpace.find(arrayEnd + 1);
86 if (it != _freeArrayStartSpace.end()) {
87 arrayEnd = it->second;
88 _freeArrayStartSpace.erase(it);
89 _freeArrayEndSpace.erase(arrayEnd);
92 _freeArrayStartSpace[arrayStart] = arrayEnd;
93 _freeArrayEndSpace[arrayEnd] = arrayStart;
95 CPPADCG_ASSERT_UNKNOWN(_freeArrayStartSpace.size() == _freeArrayEndSpace.size());
104 std::set<size_t> blackList;
105 const std::vector<Argument<Base> >& args = newArray.
getArguments();
106 for (
size_t i = 0; i < args.size(); i++) {
108 if (argOp !=
nullptr && argOp->
getOperationType() == CGOpCode::ArrayElement) {
110 CPPADCG_ASSERT_UNKNOWN(_varId[otherArray] > 0);
111 size_t otherArrayStart = _varId[otherArray] - 1;
112 size_t index = argOp->
getInfo()[0];
113 blackList.insert(otherArrayStart + index);
120 std::map<size_t, size_t>::reverse_iterator it;
121 std::map<size_t, size_t>::reverse_iterator itBestFit = _freeArrayStartSpace.rend();
122 size_t bestCommonValues = 0;
123 for (it = _freeArrayStartSpace.rbegin(); it != _freeArrayStartSpace.rend(); ++it) {
124 size_t start = it->first;
125 size_t end = it->second;
126 size_t space = end - start + 1;
127 if (space < arraySize) {
131 std::set<size_t>::const_iterator itBlack = blackList.lower_bound(start);
132 if (itBlack != blackList.end() && *itBlack <= end) {
137 if (itBestFit == _freeArrayStartSpace.rend()) {
140 size_t bestSpace = itBestFit->second - itBestFit->first + 1;
142 size_t commonVals = 0;
143 for (
size_t i = 0; i < arraySize; i++) {
144 if (isSameArrayElement(_tmpArrayValues[start + i], args[i])) {
149 if (space < bestSpace || commonVals > bestCommonValues) {
152 bestCommonValues = commonVals;
153 if (bestCommonValues == arraySize) {
160 size_t bestStart = (std::numeric_limits<size_t>::max)();
161 if (itBestFit != _freeArrayStartSpace.rend()) {
165 bestStart = itBestFit->first;
166 size_t bestEnd = itBestFit->second;
167 size_t bestSpace = bestEnd - bestStart + 1;
168 _freeArrayStartSpace.erase(bestStart);
169 if (bestSpace == arraySize) {
171 _freeArrayEndSpace.erase(bestEnd);
174 size_t newFreeStart = bestStart + arraySize;
175 _freeArrayStartSpace[newFreeStart] = bestEnd;
176 _freeArrayEndSpace.at(bestEnd) = newFreeStart;
184 std::map<size_t, size_t>::iterator itEnd;
185 itEnd = _freeArrayEndSpace.find(_idArrayCount - 1 - 1);
186 if (itEnd != _freeArrayEndSpace.end()) {
188 size_t lastSpotStart = itEnd->second;
189 size_t lastSpotEnd = itEnd->first;
190 size_t lastSpotSize = lastSpotEnd - lastSpotStart + 1;
191 std::set<size_t>::const_iterator itBlack = blackList.lower_bound(lastSpotStart);
192 if (itBlack == blackList.end()) {
194 _freeArrayEndSpace.erase(itEnd);
195 _freeArrayStartSpace.erase(lastSpotStart);
197 _idArrayCount += arraySize - lastSpotSize;
198 bestStart = lastSpotStart;
202 if (bestStart == (std::numeric_limits<size_t>::max)()) {
204 size_t id = _idArrayCount;
205 _idArrayCount += arraySize;
210 for (
size_t i = 0; i < arraySize; i++) {
211 _tmpArrayValues[bestStart + i] = &args[i];
214 CPPADCG_ASSERT_UNKNOWN(_freeArrayStartSpace.size() == _freeArrayEndSpace.size());
219 inline static bool isSameArrayElement(
const Argument<Base>* oldArg,
221 if (oldArg !=
nullptr) {
222 if (oldArg->getParameter() !=
nullptr) {
223 if (arg.getParameter() !=
nullptr) {
224 return (*arg.getParameter() == *oldArg->getParameter());
227 return (arg.getOperation() == oldArg->getOperation());
const std::vector< Argument< Base > > & getArguments() const
CGOpCode getOperationType() const
ArrayIdCompresser(CodeHandlerVector< Base, size_t > &varId, size_t maxArraySize)
size_t reserveArraySpace(const OperationNode< Base > &newArray)
const std::vector< size_t > & getInfo() const