You've already forked mariadb-columnstore-engine
							
							
				mirror of
				https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
				synced 2025-10-30 07:25:34 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			295 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			295 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* Copyright (C) 2014 InfiniDB, Inc.
 | |
| 
 | |
|    This program is free software; you can redistribute it and/or
 | |
|    modify it under the terms of the GNU General Public License
 | |
|    as published by the Free Software Foundation; version 2 of
 | |
|    the License.
 | |
| 
 | |
|    This program is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|    GNU General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU General Public License
 | |
|    along with this program; if not, write to the Free Software
 | |
|    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 | |
|    MA 02110-1301, USA. */
 | |
| 
 | |
| /*****************************************************************************
 | |
|  * $Id: cvt_em.cpp 1823 2013-01-21 14:13:09Z rdempsey $
 | |
|  *
 | |
|  ****************************************************************************/
 | |
| 
 | |
| /*
 | |
|  * Loads state of the BRM data structures from file.
 | |
|  *
 | |
|  * More detailed description
 | |
|  */
 | |
| 
 | |
| #include <iostream>
 | |
| #include <map>
 | |
| using namespace std;
 | |
| 
 | |
| #include "extentmap.h"
 | |
| using namespace BRM;
 | |
| 
 | |
| namespace
 | |
| {
 | |
| void usage(char* name)
 | |
| {
 | |
|   cout << "Usage: " << name << " <prefix>" << endl;
 | |
|   exit(1);
 | |
| }
 | |
| }  // namespace
 | |
| 
 | |
| namespace BRM
 | |
| {
 | |
| class ExtentMapConverter
 | |
| {
 | |
|  public:
 | |
|   ExtentMapConverter(){};
 | |
| 
 | |
|   int doCvt(unsigned oldExtentSize, unsigned newExtentSize, const string& filename);
 | |
| 
 | |
|  private:
 | |
|   ExtentMapConverter(const ExtentMapConverter& rhs);
 | |
|   ExtentMapConverter& operator=(const ExtentMapConverter& rhs);
 | |
| 
 | |
|   ExtentMap em;
 | |
| };
 | |
| 
 | |
| int ExtentMapConverter::doCvt(unsigned oldExtentSize, unsigned newExtentSize, const string& filename)
 | |
| {
 | |
|   int currentSize, loadSize[3];
 | |
|   ifstream in;
 | |
| 
 | |
|   em.grabEMEntryTable(ExtentMap::WRITE);
 | |
| 
 | |
|   try
 | |
|   {
 | |
|     em.grabFreeList(ExtentMap::WRITE);
 | |
|   }
 | |
|   catch (...)
 | |
|   {
 | |
|     em.releaseEMEntryTable(ExtentMap::WRITE);
 | |
|     throw;
 | |
|   }
 | |
| 
 | |
|   div_t d = div((int)oldExtentSize, (int)newExtentSize);
 | |
|   idbassert(d.quot > 1);
 | |
|   idbassert(d.rem == 0);
 | |
| 
 | |
|   const unsigned mult = d.quot;
 | |
| 
 | |
|   in.open(filename.c_str());
 | |
| 
 | |
|   if (!in)
 | |
|   {
 | |
|     log_errno("ExtentMap::load(): open");
 | |
|     em.releaseFreeList(ExtentMap::WRITE);
 | |
|     em.releaseEMEntryTable(ExtentMap::WRITE);
 | |
|     throw std::ios_base::failure("ExtentMap::load(): open failed. Check the error log.");
 | |
|   }
 | |
| 
 | |
|   in.exceptions(ios_base::badbit | ios_base::failbit);
 | |
| 
 | |
|   try
 | |
|   {
 | |
|     in.read((char*)&loadSize, 3 * sizeof(int));
 | |
|   }
 | |
|   catch (...)
 | |
|   {
 | |
|     in.close();
 | |
|     em.releaseFreeList(ExtentMap::WRITE);
 | |
|     em.releaseEMEntryTable(ExtentMap::WRITE);
 | |
|     throw;
 | |
|   }
 | |
| 
 | |
|   const int emVersion = loadSize[0];
 | |
|   const int emNumElements = loadSize[1];
 | |
|   const int flNumElements = loadSize[2];
 | |
|   /* What's a safe upper limit on the # of EM and FL entries? */
 | |
| #define EM_MAGIC_V3 0x76f78b1e
 | |
| 
 | |
|   if (emVersion != EM_MAGIC_V3 || emNumElements < 0 || flNumElements < 0)
 | |
|   {
 | |
|     in.close();
 | |
|     em.releaseFreeList(ExtentMap::WRITE);
 | |
|     em.releaseEMEntryTable(ExtentMap::WRITE);
 | |
|     log("ExtentMap::load64(): That file is not a valid 64-bit ExtentMap image");
 | |
|     throw std::runtime_error("ExtentMap::load64(): That file is not a valid 64-bit ExtentMap image");
 | |
|   }
 | |
| 
 | |
|   memset(em.fExtentMap, 0, em.fEMShminfo->allocdSize);
 | |
|   memset(em.fFreeList, 0, em.fFLShminfo->allocdSize);
 | |
|   em.fEMShminfo->currentSize = 0;
 | |
|   em.fFLShminfo->currentSize = 0;
 | |
| 
 | |
|   int j = 0;
 | |
|   int maxLoops = (emNumElements * (signed)mult - em.fEMShminfo->allocdSize / sizeof(EMEntry)) / 100 + 1;
 | |
|   int target = (int)(maxLoops * .02);
 | |
| 
 | |
|   if (maxLoops < 50)
 | |
|     target = 1;
 | |
| 
 | |
|   // allocate shared memory for extent data
 | |
|   for (currentSize = em.fEMShminfo->allocdSize / sizeof(EMEntry);
 | |
|        currentSize < (emNumElements * (signed)mult);
 | |
|        currentSize = em.fEMShminfo->allocdSize / sizeof(EMEntry))
 | |
|   {
 | |
|     em.growEMShmseg();
 | |
| 
 | |
|     if ((j % target) == 0)
 | |
|       cout << '.' << flush;
 | |
| 
 | |
|     j++;
 | |
|   }
 | |
| 
 | |
|   cout << endl;
 | |
| 
 | |
|   // allocate shared memory for freelist
 | |
|   for (currentSize = em.fFLShminfo->allocdSize / sizeof(InlineLBIDRange); currentSize < flNumElements;
 | |
|        currentSize = em.fFLShminfo->allocdSize / sizeof(InlineLBIDRange))
 | |
|   {
 | |
|     em.growFLShmseg();
 | |
|   }
 | |
| 
 | |
|   try
 | |
|   {
 | |
|     typedef map<int, vector<int> > OIDMap_t;
 | |
|     OIDMap_t OIDMap;
 | |
|     uint8_t buf[emNumElements * sizeof(EMEntry)];
 | |
|     uint8_t buf2[flNumElements * sizeof(InlineLBIDRange)];
 | |
| 
 | |
|     in.read((char*)buf, emNumElements * sizeof(EMEntry));
 | |
| 
 | |
|     // memcpy(fExtentMap, buf, emNumElements * sizeof(EMEntry));
 | |
|     EMEntry* emSrc = reinterpret_cast<EMEntry*>(&buf[0]);
 | |
|     j = 0;
 | |
| 
 | |
|     for (int i = 0; i < emNumElements; i++)
 | |
|     {
 | |
|       vector<int>& oidv = OIDMap[emSrc[i].fileID];
 | |
| 
 | |
|       for (unsigned k = 0; k < mult; k++)
 | |
|       {
 | |
|         oidv.push_back(j);
 | |
|         // em.fExtentMap[j].range.start = emSrc[i].range.start;
 | |
|         em.fExtentMap[j].range.start = emSrc[i].range.start + (k * newExtentSize);
 | |
|         // em.fExtentMap[j].range.size = emSrc[i].range.size;
 | |
|         em.fExtentMap[j].range.size = newExtentSize / 1024;
 | |
|         em.fExtentMap[j].fileID = emSrc[i].fileID;
 | |
|         em.fExtentMap[j].blockOffset = emSrc[i].blockOffset + (k * newExtentSize);
 | |
|         em.fExtentMap[j].HWM = emSrc[i].HWM;
 | |
|         em.fExtentMap[j].txnID = emSrc[i].txnID;
 | |
|         em.fExtentMap[j].secondHWM = emSrc[i].secondHWM;
 | |
|         em.fExtentMap[j].nextHeader = emSrc[i].nextHeader;
 | |
|         em.fExtentMap[j].partition.type = emSrc[i].partition.type;
 | |
|         // em.fExtentMap[j].partition.cprange.hi_val = emSrc[i].partition.cprange.hi_val;
 | |
|         em.fExtentMap[j].partition.cprange.hi_val = numeric_limits<int64_t>::min();
 | |
|         // em.fExtentMap[j].partition.cprange.lo_val = emSrc[i].partition.cprange.lo_val;
 | |
|         em.fExtentMap[j].partition.cprange.lo_val = numeric_limits<int64_t>::max();
 | |
|         // em.fExtentMap[j].partition.cprange.sequenceNum = emSrc[i].partition.cprange.sequenceNum;
 | |
|         em.fExtentMap[j].partition.cprange.sequenceNum = 0;
 | |
|         // em.fExtentMap[j].partition.cprange.isValid = emSrc[i].partition.cprange.isValid;
 | |
|         em.fExtentMap[j].partition.cprange.isValid = CP_INVALID;
 | |
|         j++;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     em.fEMShminfo->currentSize = j * sizeof(EMEntry);
 | |
| 
 | |
|     cout << j << " total new em entries from " << emNumElements << " file entries" << endl;
 | |
|     cout << OIDMap.size() << " OIDs added to em" << endl;
 | |
| 
 | |
|     OIDMap_t::const_iterator iter = OIDMap.begin();
 | |
|     OIDMap_t::const_iterator end = OIDMap.end();
 | |
| 
 | |
|     int l = 0;
 | |
| 
 | |
|     while (iter != end)
 | |
|     {
 | |
|       const vector<int>& oidv = iter->second;
 | |
|       vector<int>::const_reverse_iterator riter = oidv.rbegin();
 | |
|       vector<int>::const_reverse_iterator rend = oidv.rend();
 | |
|       HWM_t hwm = em.fExtentMap[*riter].HWM;
 | |
| 
 | |
|       while (riter != rend)
 | |
|       {
 | |
|         if (em.fExtentMap[*riter].blockOffset > hwm)
 | |
|         {
 | |
|           em.fExtentMap[*riter].fileID = numeric_limits<int>::max();
 | |
|           em.fExtentMap[*riter].blockOffset = 0;
 | |
|           em.fExtentMap[*riter].HWM = 0;
 | |
|           l++;
 | |
|         }
 | |
|         else
 | |
|           break;
 | |
| 
 | |
|         ++riter;
 | |
|       }
 | |
| 
 | |
|       ++iter;
 | |
|     }
 | |
| 
 | |
|     cout << l << " entries moved to OID " << numeric_limits<int>::max() << endl;
 | |
| 
 | |
| #if 0
 | |
|         int k = j;
 | |
| 
 | |
|         for (int j = 0; j < k; j++)
 | |
|             cout << em.fExtentMap[j].range.start << '\t' << em.fExtentMap[j].range.size << '\t' <<
 | |
|                  em.fExtentMap[j].fileID << '\t' << em.fExtentMap[j].blockOffset << '\t' << em.fExtentMap[j].HWM << '\t' <<
 | |
|                  em.fExtentMap[j].txnID << '\t' << em.fExtentMap[j].secondHWM << '\t' << em.fExtentMap[j].nextHeader << endl;
 | |
| 
 | |
| #endif
 | |
|     in.read((char*)buf2, flNumElements * sizeof(InlineLBIDRange));
 | |
| 
 | |
|     // memcpy(fFreeList, buf2, flNumElements * sizeof(InlineLBIDRange));
 | |
|     InlineLBIDRange* lrSrc = reinterpret_cast<InlineLBIDRange*>(&buf2[0]);
 | |
|     j = 0;
 | |
| 
 | |
|     for (int i = 0; i < flNumElements; i++)
 | |
|     {
 | |
|       em.fFreeList[j].start = lrSrc[i].start;
 | |
|       em.fFreeList[j].size = lrSrc[i].size;
 | |
|       j++;
 | |
|     }
 | |
| 
 | |
|     em.fFLShminfo->currentSize = j * sizeof(InlineLBIDRange);
 | |
| 
 | |
|     cout << j << " total new fl entries from " << flNumElements << " file entries" << endl;
 | |
|   }
 | |
|   catch (...)
 | |
|   {
 | |
|     in.close();
 | |
|     em.releaseFreeList(ExtentMap::WRITE);
 | |
|     em.releaseEMEntryTable(ExtentMap::WRITE);
 | |
|     throw;
 | |
|   }
 | |
| 
 | |
|   in.close();
 | |
|   em.releaseFreeList(ExtentMap::WRITE);
 | |
|   em.releaseEMEntryTable(ExtentMap::WRITE);
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| }  // namespace BRM
 | |
| 
 | |
| int main(int argc, char** argv)
 | |
| {
 | |
|   ExtentMapConverter emc;
 | |
| 
 | |
|   if (emc.doCvt(8192, 1024, "BRM_saves_em") != 0)
 | |
|   {
 | |
|     cerr << "Conversion failed." << endl;
 | |
|     return 1;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     cout << "OK" << endl;
 | |
|     return 0;
 | |
|   }
 | |
| }
 |