예제 #1
0
bool Index::ConstructLowerBoundTuple(
    storage::Tuple *index_key, const std::vector<peloton::Value> &values,
    const std::vector<oid_t> &key_column_ids,
    const std::vector<ExpressionType> &expr_types) {
  auto schema = index_key->GetSchema();
  auto col_count = schema->GetColumnCount();
  bool all_constraints_equal = true;

  // Go over each column in the key tuple
  // Setting either the placeholder or the min value
  for (oid_t column_itr = 0; column_itr < col_count; column_itr++) {
    auto key_column_itr =
        std::find(key_column_ids.begin(), key_column_ids.end(), column_itr);
    bool placeholder = false;
    Value value;

    // This column is part of the key column ids
    if (key_column_itr != key_column_ids.end()) {
      auto offset = std::distance(key_column_ids.begin(), key_column_itr);
      // Equality constraint
      if (expr_types[offset] == EXPRESSION_TYPE_COMPARE_EQUAL) {
        placeholder = true;
        value = values[offset];
      }
      // Not all expressions / constraints are equal
      else {
        all_constraints_equal = false;
      }
    }

    LOG_TRACE("Column itr : %u  Placeholder : %d ", column_itr, placeholder);

    // Fill in the placeholder
    if (placeholder == true) {
      index_key->SetValue(column_itr, value, GetPool());
    }
    // Fill in the min value
    else {
      auto value_type = schema->GetType(column_itr);
      index_key->SetValue(column_itr, Value::GetMinValue(value_type),
                          GetPool());
    }
  }

  LOG_TRACE("Lower Bound Tuple :: %s", index_key->GetInfo().c_str());
  if (col_count > values.size()) all_constraints_equal = false;

  return all_constraints_equal;
}
예제 #2
0
// WorkerThread Method
unsigned int cSQLPool::WorkerThread(void)
{
	PerSQLConnection* perSQLConnection = NULL;

	while ( !_is_exit )
	{
		_condition.wait(_mutex);

		mc_system_db::PPerhandleDataDB tmpData = GetData();

		// SQLConnection.
		perSQLConnection = GetPool( );

		// SQLConnection.
		if ( perSQLConnection == NULL )
		{
			// 10/1000(s) - CPU 
			Sleep( 10 );

			QueueRequest( tmpData );
			continue;
		}

		// SQLConnection.
		ReleasePool( perSQLConnection );
	}
	return 0L;
}
예제 #3
0
// DefaultWorkingSize Method
bool cSocketContextPool::DefaultWorkingSize(DWORD workingSize)
{
	cCSLock           lock( mCs );                  // Critical Section
	PerSocketContext* temp = NULL;

	try
	{
		while ( workingSize > 0 )
		{
			temp = GetPool( );

				if ( temp == NULL ) throw false;    // Socket Context

			workingSize--;
		}
		throw true;
	}
	catch ( bool boolean )
	{
		while ( mPagedPoolUsage != NULL )
		{
			ReleasePool( mPagedPoolUsage );
		}
		return boolean;
	}
}
예제 #4
0
bool DataTable::InsertInSecondaryIndexes(const storage::Tuple *tuple,
                                         ItemPointer location) {
  int index_count = GetIndexCount();

  // (A) Check existence for primary/unique indexes
  // FIXME Since this is NOT protected by a lock, concurrent insert may happen.
  for (int index_itr = index_count - 1; index_itr >= 0; --index_itr) {
    auto index = GetIndex(index_itr);
    auto index_schema = index->GetKeySchema();
    auto indexed_columns = index_schema->GetIndexedColumns();
    std::unique_ptr<storage::Tuple> key(new storage::Tuple(index_schema, true));
    key->SetFromTuple(tuple, indexed_columns, index->GetPool());

    switch (index->GetIndexType()) {
      case INDEX_CONSTRAINT_TYPE_PRIMARY_KEY:
        break;
      case INDEX_CONSTRAINT_TYPE_UNIQUE: {
        // if in this index there has been a visible or uncommitted
        // <key, location> pair, this constraint is violated
        index->InsertEntry(key.get(), location);
      } break;

      case INDEX_CONSTRAINT_TYPE_DEFAULT:
      default:
        index->InsertEntry(key.get(), location);
        break;
    }
    LOG_TRACE("Index constraint check on %s passed.", index->GetName().c_str());
  }
  return true;
}
예제 #5
0
파일: CoWork.cpp 프로젝트: koz4k/soccer
void CoWork::Pool::ThreadRun(int tno)
{
	LLOG("CoWork thread #" << tno << " started");
	Pool& p = GetPool();
	p.lock.Enter();
	for(;;) {
		while(!p.jobs.InList()) {
			LHITCOUNT("CoWork: Parking thread to Wait");
			if(p.quit) {
				p.lock.Leave();
				return;
			}
			p.waiting_threads++;
			LLOG("#" << tno << " Waiting for job");
			p.waitforjob.Wait(p.lock);
			LLOG("#" << tno << " Waiting ended");
			p.waiting_threads--;
		}
		LLOG("#" << tno << " Job acquired");
		LHITCOUNT("CoWork: Running new job");
		p.DoJob(*p.jobs.GetNext());
		LLOG("#" << tno << " Job finished");
	}
	p.lock.Leave();
	LLOG("CoWork thread #" << tno << " finished");
}
예제 #6
0
/*
 * Withdraw some bits from the pool.  Regardless of the distribution of the
 * input bits, the bits returned are uniformly distributed, although they
 * cannot, of course, contain more Shannon entropy than the input bits.
 */
	static void
sRandPoolGetBytesEntropy(
	void *			priv,
	PGPByte *		buf,
	unsigned		len,
	unsigned		bits)
{
	RandomPool *pool	= GetPool();
	unsigned t;
	
	pgpAssert( pool );

	(void)priv;

	if (pool->randBits >= bits)
		pool->randBits -= bits;
	else
		pool->randFrac = pool->randBits = 0;

	while (len > (t = sizeof(pool->randOut) - pool->randOutGetPos)) {
		pgpCopyMemory( (PGPByte *)pool->randOut + pool->randOutGetPos, buf, t);
		buf += t;
		len -= t;
		sRandGetOutput( pool );
	}

	if (len) {
		pgpCopyMemory( (PGPByte *)pool->randOut+pool->randOutGetPos, buf, len);
		pool->randOutGetPos += len;
	}
}
예제 #7
0
파일: CoWork.cpp 프로젝트: koz4k/soccer
bool CoWork::IsFinished()
{
	Pool& p = GetPool();
	p.lock.Enter();
	bool b = jobs.IsEmpty(1);
	p.lock.Leave();
	return b;
}
예제 #8
0
	static void
sRandPoolStirLock(void *priv)
{
	RandomPool *pool	= GetPool();
	
	PGPRMWOLockStartWriting( &pool->criticalLock );
		sRandPoolStir( priv );
	PGPRMWOLockStopWriting( &pool->criticalLock );
}
예제 #9
0
bool DataTable::InsertInSecondaryIndexes(const AbstractTuple *tuple,
                                         const TargetList *targets_ptr,
                                         ItemPointer *index_entry_ptr) {
  int index_count = GetIndexCount();
  // Transaform the target list into a hash set
  // when attempting to perform insertion to a secondary index,
  // we must check whether the updated column is a secondary index column.
  // insertion happens only if the updated column is a secondary index column.
  std::unordered_set<oid_t> targets_set;
  for (auto target : *targets_ptr) {
    targets_set.insert(target.first);
  }

  // Check existence for primary/unique indexes
  // Since this is NOT protected by a lock, concurrent insert may happen.
  for (int index_itr = index_count - 1; index_itr >= 0; --index_itr) {
    auto index = GetIndex(index_itr);
    auto index_schema = index->GetKeySchema();
    auto indexed_columns = index_schema->GetIndexedColumns();

    if (index->GetIndexType() == INDEX_CONSTRAINT_TYPE_PRIMARY_KEY) {
      continue;
    }

    // Check if we need to update the secondary index
    bool updated = false;
    for (auto col : indexed_columns) {
      if (targets_set.find(col) != targets_set.end()) {
        updated = true;
        break;
      }
    }

    // If attributes on key are not updated, skip the index update
    if (updated == false) {
      continue;
    }

    // Key attributes are updated, insert a new entry in all secondary index
    std::unique_ptr<storage::Tuple> key(new storage::Tuple(index_schema, true));

    key->SetFromTuple(tuple, indexed_columns, index->GetPool());

    switch (index->GetIndexType()) {
      case INDEX_CONSTRAINT_TYPE_PRIMARY_KEY:
        break;
      case INDEX_CONSTRAINT_TYPE_UNIQUE:
        break;
      case INDEX_CONSTRAINT_TYPE_DEFAULT:
      default:
        index->InsertEntry(key.get(), index_entry_ptr);
        break;
    }
    LOG_TRACE("Index constraint check on %s passed.", index->GetName().c_str());
  }
  return true;
}
예제 #10
0
파일: CoWork.cpp 프로젝트: koz4k/soccer
bool CoWork::TrySchedule(Function<void ()>&& fn)
{
	Pool& p = GetPool();
	Mutex::Lock __(p.lock);
	if(!p.free)
		return false;
	p.PushJob(pick(fn), NULL);
	return true;
}
예제 #11
0
	static void
sRandPoolAddBytesLock(
	void *			priv,
	PGPByte const *	p,
	unsigned		len)
{
	RandomPool *pool	= GetPool();
	
	PGPRMWOLockStartWriting( &pool->criticalLock );
		sRandPoolAddBytes( priv, p, len );
	PGPRMWOLockStopWriting( &pool->criticalLock );
}
예제 #12
0
	static void
sRandPoolGetBytesEntropyLock(
	void *			priv,
	PGPByte *		buf,
	unsigned		len,
	unsigned		bits)
{
	RandomPool *pool	= GetPool();
	
	PGPRMWOLockStartWriting( &pool->criticalLock );
		sRandPoolGetBytesEntropy( priv, buf, len, bits );
	PGPRMWOLockStopWriting( &pool->criticalLock );
}
예제 #13
0
 void RedisReply::ReserveMember(size_t num)
 {
     type = REDIS_REPLY_ARRAY;
     if (NULL == elements)
     {
         elements = new std::deque<RedisReply*>;
     }
     for (uint32 i = elements->size(); i < num; i++)
     {
         RedisReply& reply = GetPool().Allocate();
         reply.type = REDIS_REPLY_NIL;
         elements->push_back(&reply);
     }
 }
예제 #14
0
// GetPerSocketContext Method
// ReleasePerSocketContext Context Switching
PerSocketContext* cSocketContextPool::GetPerSocketContext(SOCKET socket, SOCKADDR_IN addr, DWORD ttl)
{
	cCSLock           lock( mCs );                                      // Critical Section
	PerSocketContext* perSocketContext = GetPool( );                    // Socket Context

	if ( perSocketContext != NULL )
	{
		perSocketContext->socket     = socket;                          
		perSocketContext->addr       = addr;                            // IP 
		perSocketContext->timeToLive = GetTickCount( ) + ttl;           // TTL.
	}

	return perSocketContext;
}
예제 #15
0
파일: CoWork.cpp 프로젝트: koz4k/soccer
void CoWork::Finish() {
	Pool& p = GetPool();
	p.lock.Enter();
	while(!jobs.IsEmpty(1)) {
		LLOG("Finish: todo: " << todo << " (CoWork " << FormatIntHex(this) << ")");
		p.DoJob(*jobs.GetNext(1));
	}
	while(todo) {
		LLOG("WaitForFinish (CoWork " << FormatIntHex(this) << ")");
		waitforfinish.Wait(p.lock);
	}
	p.lock.Leave();
	LLOG("CoWork " << FormatIntHex(this) << " finished");
}
예제 #16
0
파일: mp_sub.c 프로젝트: ohio813/BDArkit
BOOL BN_SUB_I(BIGNUM * y, DWORD n)
{
	BOOL bRet=FALSE;
    BIGNUM *temp;

	temp = GetPool(sizeof(BIGNUM));
	if (temp){
		BN_SET_I(temp, n);

		bRet = BN_SUB(y, temp);
		ExFreePool(temp);
	}
	return bRet;
}
예제 #17
0
/*
 * Destroys already-used random numbers.  Ensures no sensitive data
 * remains in memory that can be recovered later.  This repeatedly
 * mixes the output of the generator back into itself until all internal
 * state has been overwritten.
 */
	static void
sRandPoolStir(void *	priv )
{
	RandomPool *pool	= GetPool();
	unsigned	i;
	
	pgpAssert( pool );

	(void)priv;

	for (i = 0; i < 5*sizeof(pool->randKey)/sizeof(pool->randOut); i++) {
		sRandPoolAddBytes(priv, (PGPByte *)pool->randOut,
						  sizeof(pool->randOut));
		sRandGetOutput( pool );
	}
}
예제 #18
0
 RedisReply& RedisReply::AddMember(bool tail)
 {
     type = REDIS_REPLY_ARRAY;
     if (NULL == elements)
     {
         elements = new std::deque<RedisReply*>;
     }
     RedisReply& reply = GetPool().Allocate();
     if (tail)
     {
         elements->push_back(&reply);
     }
     else
     {
         elements->push_front(&reply);
     }
     return reply;
 }
예제 #19
0
파일: CoWork.cpp 프로젝트: koz4k/soccer
void CoWork::Do(Function<void ()>&& fn)
{
	LHITCOUNT("CoWork: Sheduling callback");
	Pool& p = GetPool();
	p.lock.Enter();
	if(!p.free) {
		LLOG("Stack full: running in the originating thread");
		LHITCOUNT("CoWork: Stack full: Running in originating thread");
		p.lock.Leave();
		fn();
		if(Pool::finlock)
			p.lock.Leave();
		return;
	}
	p.PushJob(pick(fn), this);
	todo++;
	p.lock.Leave();
}
예제 #20
0
/*
 * Make a deposit of information (entropy) into the pool.
 */
	static void
sRandPoolAddBytes(
	void *			priv,
	PGPByte const *	p,
	unsigned		len)
{
	RandomPool *pool	= GetPool();
	
	pgpAssert( pool );

	(void)priv;

	while (len--) {
		sRandPoolAddByte( pool, *p++ );
	}

	/* Pool has changed, randOut is out of date */
	pool->randOutGetPos = sizeof(pool->randOut);
}
예제 #21
0
CTimeSpan
CThreadPool_Controller_PID::GetSafeSleepTime(void) const
{
    double last_err = 0, integr_err = 0;
    CThreadPool* pool = GetPool();
    if (!pool) {
        return CTimeSpan(0, 0);
    }
    {{
        CMutexGuard guard(GetMainPoolMutex(pool));

        if (m_ErrHistory.size() == 0) {
            return CThreadPool_Controller::GetSafeSleepTime();
        }

        last_err = m_ErrHistory.back().err;
        integr_err = m_IntegrErr;
    }}

    unsigned int threads_cnt = pool->GetThreadsCount();
    if (last_err == 0
        ||  (last_err > 0  &&  threads_cnt == GetMaxThreads())
        ||  (last_err < 0  &&  threads_cnt == GetMinThreads()))
    {
        return CThreadPool_Controller::GetSafeSleepTime();
    }

    double sleep_time = 0;
    if (last_err > 0) {
        sleep_time = (m_Threshold - last_err - integr_err)
                     * m_IntegrCoeff / last_err;
    }
    else {
        sleep_time = (-m_Threshold - last_err - integr_err)
                     * m_IntegrCoeff / last_err;
    }
    if (sleep_time < 0)
        sleep_time = 0;

    return CTimeSpan(sleep_time);
}
예제 #22
0
/**
 * @brief Insert a tuple into all indexes. If index is primary/unique,
 * check visibility of existing
 * index entries.
 * @warning This still doesn't guarantee serializability.
 *
 * @returns True on success, false if a visible entry exists (in case of
 *primary/unique).
 */
bool DataTable::InsertInIndexes(const storage::Tuple *tuple,
                                ItemPointer location) {
  int index_count = GetIndexCount();
  auto &transaction_manager =
      concurrency::TransactionManagerFactory::GetInstance();

  std::function<bool(const ItemPointer &)> fn =
      std::bind(&concurrency::TransactionManager::IsOccupied,
                &transaction_manager, std::placeholders::_1);

  // (A) Check existence for primary/unique indexes
  // FIXME Since this is NOT protected by a lock, concurrent insert may happen.
  for (int index_itr = index_count - 1; index_itr >= 0; --index_itr) {
    auto index = GetIndex(index_itr);
    auto index_schema = index->GetKeySchema();
    auto indexed_columns = index_schema->GetIndexedColumns();
    std::unique_ptr<storage::Tuple> key(new storage::Tuple(index_schema, true));
    key->SetFromTuple(tuple, indexed_columns, index->GetPool());

    switch (index->GetIndexType()) {
      case INDEX_CONSTRAINT_TYPE_PRIMARY_KEY:
      case INDEX_CONSTRAINT_TYPE_UNIQUE: {
        // TODO: get unique tuple from primary index.
        // if in this index there has been a visible or uncommitted
        // <key, location> pair, this constraint is violated
        if (index->CondInsertEntry(key.get(), location, fn) == false) {
          return false;
        }

      } break;

      case INDEX_CONSTRAINT_TYPE_DEFAULT:
      default:
        index->InsertEntry(key.get(), location);
        break;
    }
    LOG_TRACE("Index constraint check on %s passed.", index->GetName().c_str());
  }

  return true;
}
예제 #23
0
	PGPError
pgpInitGlobalRandomPool()
{
	RandomPool *	pool	= NULL;
	
	pool	= GetPool();
	
	pool->randBits			= 0;
	pool->randFrac			= 0;
	pool->randInBits		= 0;
	pool->randKeyBits		= 0;
	pool->randKeyFrac		= 0;
	pool->randPoolAddPos	= 0;
	pool->randKeyAddPos		= 0;
	pool->randOutGetPos		= sizeof( pool->randOut);
	pool->randHashCounter	= 0;
	
	InitializePGPRMWOLock( &pool->criticalLock );
	
	return( kPGPError_NoErr );
}
예제 #24
0
	static PGPUInt32
pgpGlobalRandomPoolEntropyWasAdded(
	PGPUInt32		delta )
{
	PGPUInt32		frac,
					t;
	unsigned		n;
	RandomPool	*	pool	= GetPool();

	if (delta < 1 << DERATING)
		return 0;
	
	n = 31-DERATING;
	if (!(delta & 0xffff0000))
		delta <<= 16, n -= 16;
	if (!(delta & 0xff000000))
		delta <<= 8, n -= 8;
	if (!(delta & 0xf0000000))
		delta <<= 4, n -= 4;
	if (!(delta & 0xc0000000))
		delta <<= 2, n -= 2;
	if (!(delta & 0x80000000))
		delta <<= 1, n -= 1;
	pgpAssert(n < 32);

	/* Lose high-order bit of delta */
	pgpAssert(delta & 0x80000000);
	delta <<= 1;

	frac = pool->randKeyFrac;
	UMULH_32(t,delta,frac);
	if ((frac += t) < t) {
		if ((frac += delta) < delta)
			frac = (frac >> 1) + 0x80000000ul;
		else
			frac >>= 1;
		n++;
	} else if ((frac += delta) < delta) {
예제 #25
0
BWTreeIndex<KeyType, ValueType, KeyComparator, KeyEqualityChecker>::BWTreeIndex(
    IndexMetadata *metadata)
    : Index(metadata),
      container(KeyComparator(metadata), KeyEqualityChecker(metadata)),
      equals(metadata),
      comparator(metadata) {
  // Add your implementation here
  // Set min key of bwtree
  auto schema = metadata->GetKeySchema();
  auto col_count = schema->GetColumnCount();
  std::unique_ptr<storage::Tuple> min_key_tuple(new storage::Tuple(metadata->GetKeySchema(), true));

  for (oid_t column_itr = 0; column_itr < col_count; column_itr++) {
    auto value_type = schema->GetType(column_itr);
    min_key_tuple->SetValue(column_itr, Value::GetMinValue(value_type), GetPool());
  }

  KeyType min_key;
  min_key.SetFromKey(min_key_tuple.get());

  container.SetMinKey(min_key);
  container.Init();
}
// delete a tuple from all its indexes it belongs to.
void TransactionLevelGCManager::DeleteTupleFromIndexes(ItemPointer *indirection) {
  // do nothing if indirection is null
  if (indirection == nullptr){
    return;
  }
  LOG_TRACE("Deleting indirection %p from index", indirection);
  
  ItemPointer location = *indirection;

  auto &manager = catalog::Manager::GetInstance();
  auto tile_group = manager.GetTileGroup(location.block);

  PL_ASSERT(tile_group != nullptr);

  storage::DataTable *table =
    dynamic_cast<storage::DataTable *>(tile_group->GetAbstractTable());
  PL_ASSERT(table != nullptr);

  // construct the expired version.
  expression::ContainerTuple<storage::TileGroup> expired_tuple(tile_group.get(), location.offset);

  // unlink the version from all the indexes.
  for (size_t idx = 0; idx < table->GetIndexCount(); ++idx) {
    auto index = table->GetIndex(idx);
    auto index_schema = index->GetKeySchema();
    auto indexed_columns = index_schema->GetIndexedColumns();

    // build key.
    std::unique_ptr<storage::Tuple> key(
      new storage::Tuple(index_schema, true));
    key->SetFromTuple(&expired_tuple, indexed_columns, index->GetPool());

    index->DeleteEntry(key.get(), indirection);

  }
}
예제 #27
0
파일: CoWork.cpp 프로젝트: koz4k/soccer
void CoWork::FinLock()
{
	Pool::finlock = true;
	GetPool().lock.Enter();
}
예제 #28
0
void
CThreadPool_Controller_PID::OnEvent(EEvent event)
{
    if (event == eSuspend) {
        return;
    }

    // All reads below are atomic reads of one variable, thus they cannot
    // return bad results. They can be a little bit inconsistent with each
    // other because of races with other threads but that's okay for the
    // purposes of this controller.
    unsigned int threads_count = GetPool()->GetThreadsCount();
    unsigned int queued_tasks  = GetPool()->GetQueuedTasksCount();
    unsigned int run_tasks     = GetPool()->GetExecutingTasksCount();

    if (threads_count == 0) {
        EnsureLimits();
        threads_count = GetMinThreads();

        // Special case when MinThreads == 0
        if (threads_count == 0) {
            if (queued_tasks == 0) {
                return;
            }

            threads_count = 1;
            SetThreadsCount(threads_count);
        }
    }

    double now_err = (double(queued_tasks + run_tasks) - threads_count)
                            / threads_count;
    double now_time = m_Timer.Elapsed();

    if (event == eResume) {
        // When we resuming we need to avoid panic because of big changes in
        // error value. So we will assume that current error value was began
        // long time ago and didn't change afterwards.
        m_ErrHistory.clear();
        m_ErrHistory.push_back(SThreadPool_PID_ErrInfo(now_time - m_DerivTime,
                                                       now_err));
    }

    double period = now_time - m_ErrHistory.back().call_time;

    if (now_err < 0  &&  threads_count == GetMinThreads()
        &&  m_IntegrErr <= 0)
    {
        now_err = 0;
    }

    double integr_err = m_IntegrErr + (now_err + m_ErrHistory.back().err) / 2
                                       * period / m_IntegrCoeff;

    while (m_ErrHistory.size() > 1
           &&  now_time - m_ErrHistory[1].call_time >= m_DerivTime)
    {
        m_ErrHistory.pop_front();
    }
    if (now_time - m_ErrHistory.back().call_time >= m_DerivTime / 10) {
        m_ErrHistory.push_back(SThreadPool_PID_ErrInfo(now_time, now_err));
        if (threads_count == GetMaxThreads()  &&  integr_err > m_Threshold) {
            m_IntegrErr = m_Threshold;
        }
        else if (threads_count == GetMinThreads()
                 &&  integr_err < -m_Threshold)
        {
            m_IntegrErr = -m_Threshold;
        }
        else {
            m_IntegrErr = integr_err;
        }
    }

    double deriv_err = (now_err - m_ErrHistory[0].err)
                        / m_DerivTime * m_DerivCoeff;

    double final_val = (now_err + integr_err + deriv_err) / m_Threshold;
/*
    LOG_POST(CTime(CTime::eCurrent).AsString("M/D/Y h:m:s.l").c_str()
             << "  count=" << threads_count << ", queued=" << queued_tasks
             << ", run=" << run_tasks << ", err=" << now_err << ", time=" << now_time
             << ", intErr=" << m_IntegrErr << ", derivErr=" << deriv_err
             << ", final=" << final_val << ", hist_size=" << m_ErrHistory.size());
*/
    if (final_val >= 1  ||  final_val <= -1) {
        if (final_val < 0 && -final_val > threads_count)
            SetThreadsCount(GetMinThreads());
        else
            SetThreadsCount(threads_count + int(final_val));
    }
    else {
        EnsureLimits();
    }
}
예제 #29
0
/**
 * @brief Insert a tuple into all indexes. If index is primary/unique,
 * check visibility of existing
 * index entries.
 * @warning This still doesn't guarantee serializability.
 *
 * @returns True on success, false if a visible entry exists (in case of
 *primary/unique).
 */
bool DataTable::InsertInIndexes(const storage::Tuple *tuple,
                                ItemPointer location,
                                concurrency::Transaction *transaction,
                                ItemPointer **index_entry_ptr) {

  int index_count = GetIndexCount();

  size_t active_indirection_array_id = number_of_tuples_ % ACTIVE_INDIRECTION_ARRAY_COUNT;

  size_t indirection_offset = INVALID_INDIRECTION_OFFSET;
  
  while (true) {
    auto active_indirection_array = active_indirection_arrays_[active_indirection_array_id];
    indirection_offset = active_indirection_array->AllocateIndirection();

    if (indirection_offset != INVALID_INDIRECTION_OFFSET) {
      *index_entry_ptr = active_indirection_array->GetIndirectionByOffset(indirection_offset);
      break;
    }
  }

  (*index_entry_ptr)->block = location.block;
  (*index_entry_ptr)->offset = location.offset;

  if (indirection_offset == INDIRECTION_ARRAY_MAX_SIZE - 1) {
    AddDefaultIndirectionArray(active_indirection_array_id);
  }

  auto &transaction_manager =
      concurrency::TransactionManagerFactory::GetInstance();

  std::function<bool(const void *)> fn =
      std::bind(&concurrency::TransactionManager::IsOccupied,
                &transaction_manager, transaction, std::placeholders::_1);

  // Since this is NOT protected by a lock, concurrent insert may happen.
  bool res = true;
  int success_count = 0;

  for (int index_itr = index_count - 1; index_itr >= 0; --index_itr) {
    auto index = GetIndex(index_itr);
    auto index_schema = index->GetKeySchema();
    auto indexed_columns = index_schema->GetIndexedColumns();
    std::unique_ptr<storage::Tuple> key(new storage::Tuple(index_schema, true));
    key->SetFromTuple(tuple, indexed_columns, index->GetPool());

    switch (index->GetIndexType()) {
      case INDEX_CONSTRAINT_TYPE_PRIMARY_KEY: {
        // get unique tuple from primary index.
        // if in this index there has been a visible or uncommitted
        // <key, location> pair, this constraint is violated
        res = index->CondInsertEntry(key.get(), *index_entry_ptr, fn);
      } break;
      case INDEX_CONSTRAINT_TYPE_UNIQUE: {
        // get unique tuple from primary index.
        // if in this index there has been a visible or uncommitted
        // <key, location> pair, this constraint is violated
        // res = index->CondInsertEntry(key.get(), *index_entry_ptr, fn);
      } break;

      case INDEX_CONSTRAINT_TYPE_DEFAULT:
      default:
        index->InsertEntry(key.get(), *index_entry_ptr);
        break;
    }

    // Handle failure
    if (res == false) {
      // If some of the indexes have been inserted,
      // the pointer has a chance to be dereferenced by readers and it cannot be deleted
      *index_entry_ptr = nullptr;
      return false;
    } else {
      success_count += 1;
    }
    LOG_TRACE("Index constraint check on %s passed.", index->GetName().c_str());
  }

  return true;
}
예제 #30
0
파일: mp_div.c 프로젝트: ohio813/BDArkit
//x = y * n + m
BOOL BN_DIV(BIGNUM * y, CONST BIGNUM * x, CONST BIGNUM * n, BIGNUM * m)
{
    BOOL bRet = FALSE;
    BOOL bResult = FALSE;
    INT nResult= 0;
	DWORD i = 0;
	ULARGE_INTEGER m0;
	ULONGLONG n0 = 0;
	ULONGLONG min = 0, div = 0, max = 0;
	BIGNUM *mul=NULL;
	BIGNUM *sub=NULL;
	ULONGLONG ld = 0, d = 0, rd = 0;
	//

	mul = GetPool(sizeof(BIGNUM));
	sub = GetPool(sizeof(BIGNUM));
	if (!sub || !mul){
		CONDITION_ASSERT(bResult);
	}
    BN_SET_I(sub, 0);
    BN_SET_I(mul, 0);
	BN_SET_I(y, 0);
	BN_SET(m, x);
	//
	for (i = x->dwCount; n->dwCount <= i; --i)
	{
		CONDITION_ASSERT(i == m->dwCount || i + 1 == m->dwCount);
		
		m0.QuadPart = m->dwDigits[i - 1];
		if (i < m->dwCount)
		{
			m0.u.HighPart = m->dwDigits[m->dwCount - 1];
		}
		n0 = n->dwDigits[n->dwCount - 1];
		max = (m0.QuadPart / n0);
		min = (m0.QuadPart / (n0 + 1));
		CONDITION_ASSERT(min <= max);
		//
		for ( ld = 0, rd = max - min; ; )
		{
			d = ld + (rd - ld) / 2;
			div = max - d;
			if (ld == rd) break;
			//
			bResult = BN_MUL_I(mul, n, div);
			CONDITION_ASSERT(bResult);
			//
			bResult = BN_LSHIFT_D(mul, i - n->dwCount);
			CONDITION_ASSERT(bResult);
			//
			nResult = BN_CMP(m, mul);
			if (0 < nResult)
			{
				BN_SET(sub, m);
				//
				bResult = BN_SUB(sub, mul);
				CONDITION_ASSERT(bResult);
				//
				BN_RSHIFT_D(sub, i - n->dwCount);
				//
				nResult = BN_CMP(n, sub);
				if (0 < nResult) 
                    break;
				//
				rd = d;
				continue;
			}
			if (nResult < 0)
			{
				ld = d + 1;
				continue;
			}
			// if (0 == r)
			{
				break;
			}
		}
		//
		bResult = BN_MUL_I(mul, n, div);
		CONDITION_ASSERT(bResult);
		//
		bResult = BN_LSHIFT_D(mul, i - n->dwCount);
		CONDITION_ASSERT(bResult);
		//
		bResult = BN_SUB(m, mul);
		CONDITION_ASSERT(bResult);
		//
		y->dwDigits[i - n->dwCount] = (DWORD)div;
	}
	//
	if (n->dwCount < x->dwCount)
	{
		y->dwCount = x->dwCount - n->dwCount + 1;
	}
	for (i = y->dwCount; 0 < i; --i)
	{
		if (y->dwDigits[i - 1])
		{
			break;
		}
		if (1 < y->dwCount)
		{
			--y->dwCount;
		}
	}
	
    bRet = TRUE;
Exit0:
	if (mul){
		ExFreePool(mul);
	}
	if (sub){
		ExFreePool(sub);
	}
	return bRet;
}