mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-04-18 21:44:02 +03:00
158 lines
3.7 KiB
C++
158 lines
3.7 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$
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define BRMAUTOINCMGR_DLLEXPORT
|
|
#include "autoincrementmanager.h"
|
|
#undef BRMAUTOINCMGR_DLLEXPORT
|
|
|
|
#include <math.h>
|
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
|
|
|
using namespace std;
|
|
using namespace boost;
|
|
using namespace boost::posix_time;
|
|
|
|
namespace BRM
|
|
{
|
|
AutoincrementManager::AutoincrementManager()
|
|
{
|
|
}
|
|
|
|
AutoincrementManager::~AutoincrementManager()
|
|
{
|
|
}
|
|
|
|
void AutoincrementManager::startSequence(uint32_t oid, uint64_t firstNum, uint32_t colWidth,
|
|
execplan::CalpontSystemCatalog::ColDataType colDataType)
|
|
{
|
|
boost::mutex::scoped_lock lk(lock);
|
|
map<uint64_t, sequence>::iterator it;
|
|
sequence s;
|
|
|
|
it = sequences.find(oid);
|
|
|
|
if (it != sequences.end())
|
|
return;
|
|
|
|
s.value = firstNum;
|
|
|
|
if (isUnsigned(colDataType))
|
|
{
|
|
s.overflow = (0xFFFFFFFFFFFFFFFFULL >> (64 - colWidth * 8)) - 1;
|
|
}
|
|
else
|
|
{
|
|
s.overflow = (1ULL << (colWidth * 8 - 1));
|
|
}
|
|
|
|
sequences[oid] = s;
|
|
}
|
|
|
|
bool AutoincrementManager::getAIRange(uint32_t oid, uint64_t count, uint64_t* firstNum)
|
|
{
|
|
boost::mutex::scoped_lock lk(lock);
|
|
map<uint64_t, sequence>::iterator it;
|
|
|
|
it = sequences.find(oid);
|
|
|
|
if (it == sequences.end())
|
|
throw runtime_error("There is no sequence with that lock");
|
|
|
|
if ((count >= it->second.overflow || count + it->second.value > it->second.overflow ||
|
|
count + it->second.value <= it->second.value) &&
|
|
count != 0)
|
|
return false;
|
|
|
|
*firstNum = it->second.value;
|
|
it->second.value += count;
|
|
return true;
|
|
}
|
|
|
|
void AutoincrementManager::resetSequence(uint32_t oid, uint64_t value)
|
|
{
|
|
boost::mutex::scoped_lock lk(lock);
|
|
map<uint64_t, sequence>::iterator it;
|
|
|
|
it = sequences.find(oid);
|
|
|
|
if (it == sequences.end())
|
|
return;
|
|
|
|
it->second.value = value;
|
|
}
|
|
|
|
const uint32_t AutoincrementManager::lockTime = 30;
|
|
|
|
void AutoincrementManager::getLock(uint32_t oid)
|
|
{
|
|
boost::mutex::scoped_lock lk(lock);
|
|
map<uint64_t, sequence>::iterator it;
|
|
ptime stealTime = microsec_clock::local_time() + seconds(lockTime);
|
|
|
|
bool gotIt = false;
|
|
|
|
it = sequences.find(oid);
|
|
|
|
if (it == sequences.end())
|
|
throw runtime_error("There is no sequence with that lock");
|
|
|
|
lk.unlock();
|
|
|
|
while (!gotIt && microsec_clock::local_time() < stealTime)
|
|
{
|
|
gotIt = it->second.lock.try_lock();
|
|
|
|
if (!gotIt)
|
|
usleep(100000);
|
|
}
|
|
|
|
// If !gotIt, take possession
|
|
}
|
|
|
|
void AutoincrementManager::releaseLock(uint32_t oid)
|
|
{
|
|
boost::mutex::scoped_lock lk(lock);
|
|
map<uint64_t, sequence>::iterator it;
|
|
|
|
it = sequences.find(oid);
|
|
|
|
if (it == sequences.end())
|
|
return; // it's unlocked if the lock doesn't exist...
|
|
|
|
lk.unlock();
|
|
|
|
it->second.lock.unlock();
|
|
}
|
|
|
|
void AutoincrementManager::deleteSequence(uint32_t oid)
|
|
{
|
|
boost::mutex::scoped_lock lk(lock);
|
|
map<uint64_t, sequence>::iterator it;
|
|
|
|
it = sequences.find(oid);
|
|
|
|
if (it != sequences.end())
|
|
sequences.erase(it);
|
|
}
|
|
|
|
} /* namespace BRM */
|