bool FdoRdbmsSQLDataReader::IsNull(FdoInt32 index)
{
    bool isNull = true;
    if( ! mHasMoreRows )
        throw FdoCommandException::Create(NlsMsgGet(FDORDBMS_62, noMoreRows));
    ValidateIndex(index);

    switch(mColList[index].datatype)
    {
    case RDBI_GEOMETRY:
        {
            FdoInt32 len = 0;
            GetGeometry(index, &len, true);
            isNull = (len == 0);
        }
        break;
    case RDBI_BLOB_ULEN:
    case RDBI_WSTRING_ULEN:
    case RDBI_STRING_ULEN:
        {
            FdoByteArray* arr = NULL;
            bool isNullArr = false;
            mQueryResult->GetBinaryValue (index+1, sizeof(FdoByteArray*), (char*)&arr, &isNullArr, NULL);
            isNull = (isNullArr || arr == NULL || arr->GetCount() == 0);
        }
        break;
    default:
        isNull = mQueryResult->GetIsNull(index+1);
        break;
    }
    return isNull;
}
const wchar_t* FdoRdbmsSQLDataReader::GetString(FdoInt32 index)
{
    bool isNULL = false;
    if (! mHasMoreRows)
        throw FdoCommandException::Create(NlsMsgGet(FDORDBMS_62, noMoreRows));
    ValidateIndex(index);

    int i = index;
	if (mSprops[i].valid)
		return mSprops[i].data;

    const wchar_t* tmpVal = NULL;
    if (mColList[index].datatype == RDBI_WSTRING_ULEN)
    {
        FdoByteArray* arr = NULL;
        mQueryResult->GetBinaryValue (index+1, sizeof(FdoByteArray*), (char*)&arr, &isNULL, NULL);
        if (!isNULL && arr != NULL && arr->GetCount() != 0)
        {
            int sizeW = (int)(arr->GetCount()/sizeof(wchar_t));
            mSprops[i].EnsureSize(sizeW + 1);
            memcpy(mSprops[i].data, arr->GetData(), arr->GetCount());
            *(mSprops[i].data+sizeW) = L'\0';
            mSprops[i].valid = 1;
            return mSprops[i].data;
        }
    }
    else if (mColList[index].datatype == RDBI_STRING_ULEN)
    {
        FdoByteArray* arr = NULL;
        mQueryResult->GetBinaryValue (index+1, sizeof(FdoByteArray*), (char*)&arr, &isNULL, NULL);
        if (!isNULL && arr != NULL && arr->GetCount() != 0)
        {
            int cntArr = arr->GetCount();
            mSprops[i].EnsureSize(2*cntArr + 1);
            char* startCh = (char*)(mSprops[i].data+cntArr);
            memcpy(startCh, arr->GetData(), cntArr);
            *(startCh+cntArr) = L'\0'; // add string ending
            ut_utf8_to_unicode(startCh, mSprops[i].data, cntArr+1);
            mSprops[i].valid = 1;
            return mSprops[i].data;
        }
    }
    else
        tmpVal = mQueryResult->GetString(index+1, &isNULL, NULL);

    if (isNULL || tmpVal == NULL)
    {
        mSprops[i].EnsureSize(1);
        mSprops[i].data = L'\0';
        mSprops[i].valid = 1;
        throw FdoCommandException::Create(NlsMsgGet1( FDORDBMS_386, strNUllColumnExp, mColList[index].column ));
    }
    
    size_t sz = wcslen(tmpVal);
    mSprops[i].EnsureSize(sz+1);
    wcscpy(mSprops[i].data, tmpVal);
    mSprops[i].valid = 1;

    return mSprops[i].data;
}
Exemple #3
0
/**
 * @param nPosition - start position.
 * @param nLength - length of the extracted string.
 */
void CStrStream::Delete(size_t nPosition, size_t nLength)
{
	ValidateIndex(nPosition, nLength);
	size_t nNewLength = m_nLength - nLength;
	MoveMemory(m_pszData + nPosition, m_pszData + nLength, (nNewLength + 1) * sizeof(TCHAR));
	m_nLength = nNewLength;
}
FdoLOBValue* FdoRdbmsSQLDataReader::GetLOB(FdoInt32 index)
{
    ValidateIndex(index);

    bool isNull = false;
    if (mColList[index].datatype == RDBI_BLOB_ULEN)
    {
        FdoByteArray* arr = NULL;
        mQueryResult->GetBinaryValue (index+1, sizeof(FdoByteArray*), (char*)&arr, &isNull, NULL);
        if (!isNull && arr != NULL && arr->GetCount() != 0)
            return static_cast<FdoLOBValue*>(FdoDataValue::Create(arr->GetData(), arr->GetCount(), FdoDataType_BLOB));
    }
    else if (mColList[index].size > 0)
    {
        FdoByte* vblob = new FdoByte[mColList[index].size];
        try
        {
            mQueryResult->GetBinaryValue (index+1, mColList[index].size, (char*)vblob, &isNull, NULL);
            FdoLOBValue* retVal = (!isNull) ? (FdoLOBValue*)FdoDataValue::Create(vblob, mColList[index].size, FdoDataType_BLOB) : NULL;
            delete[] vblob;
            return retVal;
        }
        catch(...)
        {
            delete[] vblob;
            throw;
        }
    }

    throw FdoCommandException::Create(NlsMsgGet1( FDORDBMS_386, strNUllColumnExp, mColList[index].column ));
}
const void* FdoRdbmsSQLDataReader::GetGeometry(FdoInt32 index, FdoInt32* len, bool noExcOnInvalid)
{
    ValidateIndex(index);
    if( ! mHasMoreRows )
        throw FdoCommandException::Create(NlsMsgGet(FDORDBMS_62, noMoreRows));

    if (mGeomIdx != index)
    {
        FdoIGeometry* geom = NULL;
        bool isSupportedType = false;
        bool isNull = false;

        mGeomIdx = index;
        if (mWkbBuffer)
            *mWkbBuffer = 0;
        mQueryResult->GetBinaryValue (index+1, sizeof(FdoIGeometry *), (char*)&geom, &isNull, NULL);

        if ( !isNull && geom && geom->GetDerivedType() != FdoGeometryType_None )
            isSupportedType = true;

        if ( !isNull && geom != NULL )
        {
            if ( isSupportedType )
            {
                FdoPtr<FdoFgfGeometryFactory>  gf = FdoFgfGeometryFactory::GetInstance();
                FdoPtr<FdoByteArray> fgf = gf->GetFgf(geom);
                if (fgf != NULL && fgf->GetCount() != 0)
                {
                    mWkbGeomLen = fgf->GetCount();
                    if (mWkbBufferLen < mWkbGeomLen)
                    {
                        delete[] mWkbBuffer;
                        mWkbBufferLen = mWkbGeomLen;
                        mWkbBuffer = new unsigned char[mWkbGeomLen];
                    }
                    memcpy(mWkbBuffer, fgf->GetData(), mWkbGeomLen);
                }
                else
                    mWkbGeomLen = 0;
            }
            else
                mWkbGeomLen = -1;
        }
        else // isNull indicator is not set by dbi_get_val_b for geometry columns
            mWkbGeomLen = 0;
    }
    *len = mWkbGeomLen;
    if (*len <= 0)
    {
        if (noExcOnInvalid)
            return NULL;
        else if (*len == 0)
            throw FdoCommandException::Create(NlsMsgGet1( FDORDBMS_385, "Property '%1$ls' value is NULL; use IsNull method before trying to access the property value", mColList[index].column ));
        else
            throw FdoCommandException::Create( NlsMsgGet(FDORDBMS_116, "Unsupported geometry type" ) );
    }

    return mWkbBuffer;
}
void CBaseObject::ValidateBaseObjectDetail(void)
{
	ValidateFlags();
	ValidateAllocation();
	ValidateDistToRoot();
	ValidateIndex();
	ValidateObjectsThisIn();
}
FdoPropertyType FdoRdbmsSQLDataReader::GetPropertyType(FdoInt32 index)
{
    ValidateIndex(index);
    if( mColList[index].datatype == RDBI_GEOMETRY )
        return FdoPropertyType_GeometricProperty;
    else
        return FdoPropertyType_DataProperty;
}
Exemple #8
0
/**
 * @param rStrHolder - string buffer that receives the data.
 * @param nPosition - start position.
 * @param nLength - length of the extracted string.
 */
void CStrStream::Substring(CStrHolder& rStrHolder, size_t nPosition, size_t nLength) const
{
	ValidateIndex(nPosition, nLength);
	size_t nEndPosition = nPosition + nLength;
	TCHAR chData = m_pszData[nEndPosition];
	m_pszData[nEndPosition] = _T('\0');
	rStrHolder = m_pszData + nPosition;
	m_pszData[nEndPosition] = chData;
}
Exemple #9
0
/**
 * @param pszSubstring - inserted string buffer.
 * @param nPosition - start position.
 * @param nLength - length of the inserted string.
 */
void CStrStream::Insert(PCTSTR pszSubstring, size_t nPosition, size_t nLength)
{
	ValidateIndex(nPosition);
	size_t nNewLength = m_nLength + nLength;
	EnsureSize(nNewLength + 1, true);
	size_t nNextPosition = nPosition + nLength;
	size_t nNextLength = m_nLength - nPosition;
	MoveMemory(m_pszData + nNextPosition, m_pszData + nPosition, (nNextLength + 1) * sizeof(TCHAR));
	MoveMemory(m_pszData + nPosition, pszSubstring, nLength * sizeof(TCHAR));
	m_nLength = nNewLength;
}
Exemple #10
0
// PURPOSE:
//   Subarray copy constructor
//
// PRE:
//   const SubArray& Obj_	: The argument subarray to be copied
//
// POST:
//   Calls PtrVector constructor to copy argument pointer vector and
//   initialize all data members to same value as argument subarray object.
//   Validates subarray index
//
SubArray::SubArray(const SubArray& Obj_):
    PtrVector(Obj_.GetLength()),
    _ArrayBase(NULL),
    _Index(Obj_.GetIndex()),
    _BackPtr(NULL),
    _Extension(NULL)
{
    ARXMARKER("Start: SubArray::SubArray(const SubArray&)", ARRAY_ERRSTREAM)

    if (Obj_._Extension)
        _Extension = Obj_._Extension->Clone();

    ValidateIndex();

    ARXMARKER("End: SubArray::SubArray(const SubArray&)", ARRAY_ERRSTREAM)
}
void RGB_Tlc5940::WriteRGB(byte index, byte red, byte green, byte blue) {	 
	//If index is invalid, abort write
	if(!ValidateIndex(index))
		return;
		
	Serial.println("Validation Complete!");
	
	Serial.println("Mapping values...");
	int absRed = map(red, 0, 255, 0, 4095);
	int absGreen = map(green, 0, 255, 0, 4095);
	int absBlue = map(blue, 0, 255, 0, 4095);
	
    Serial.print("Red: ");
	Serial.print(red);
	Serial.print(" to ");
	Serial.print(absRed);
	Serial.print(" ");
	
	Serial.print("Green: ");
	Serial.print(green);
	Serial.print(" to ");
	Serial.print(absGreen);
	Serial.print(" ");
	
	Serial.print("Blue: ");
	Serial.print(blue);
	Serial.print(" to ");
	Serial.println(absBlue);
	
	Serial.print("Writing to pins...");
	Serial.print("Red : ");
	Serial.print(_ledPins[index].r);
	Serial.print(" ");
	Serial.print("Green : ");
	Serial.print(_ledPins[index].g);
	Serial.print(" ");
	Serial.print("Blue : ");
	Serial.println(_ledPins[index].b);
	
	Tlc.set(_ledPins[index].r, absRed);
	Tlc.set(_ledPins[index].g, absGreen);
	Tlc.set(_ledPins[index].b, absBlue);
	Commit();
  
  return;
}
Exemple #12
0
// PURPOSE:
//   Subarray class constructor with total cells and array index argument
//
// PRE:
//   size_t NumArgs	: The totla number of cells in the subarray
//   size_t ThisIndex	: The initial subarray index
//
// POST:
//   Calls PtrVector constructor to create the null pointer vector and
//   validity state bit array
//   If number of arguments exceeds or equals the maximum value of unsigned
//   short type then length exception is thrown otherwise the subarray index
//   is validated and all elements in pointer vector is set to invalid state.
//
SubArray::SubArray(size_t NumArgs_, size_t ThisIndex_):
    PtrVector(NumArgs_),
    _ArrayBase(NULL),
    _Index(ThisIndex_),
    _BackPtr(NULL),
    _Extension(NULL)
{
    ARXMARKER("Start: SubArray::SubArray(size_t, size_t)", ARRAY_ERRSTREAM)

    // Throw exception if specified total array cells is greater than or equal
    // to maximum of counter type.
    if (NumArgs_ >= ArrayClass::MaxSize())
        Xlen();

    // Validate specified index
    ValidateIndex();

    // Initialize all array elements to invalid state.
    for (size_t Index_ = 0, Max_ = GetIndex(); Index_ < Max_; Index_++)
        SetInvalid(Index_);

    ARXMARKER("End: SubArray::SubArray(size_t, size_t)", ARRAY_ERRSTREAM)
}
void RGB_Tlc5940::WriteRGB(byte index, byte red, byte green, byte blue, boolean sync) {	 
	//If index is invalid, abort write
	if(!ValidateIndex(index))
		return;

	//Serial.println("Validation Complete!");
	
	//Serial.println("Mapping values...");
	int absRed = map(red, 0, 255, 0, 4095);
	int absGreen = map(green, 0, 255, 0, 4095);
	int absBlue = map(blue, 0, 255, 0, 4095);
    
	//Serial.println("Setting values...");
	Tlc.set(_ledPins[index].r, absRed);
	Tlc.set(_ledPins[index].g, absGreen);
	Tlc.set(_ledPins[index].b, absBlue);
	
  if(sync) {
	Commit();
  }
  
  return;
}
void ParseArguments(int argc, char *argv[], configuration &state) {
  // Default Values
  state.index = INDEX_TYPE_BWTREE;
  state.scale_factor = 1;
  state.duration = 10;
  state.profile_duration = 1;
  state.backend_count = 2;
  state.warehouse_count = 2;
  state.exp_backoff = false;
  state.affinity = false;
  state.gc_mode = false;
  state.gc_backend_count = 1;

  // Parse args
  while (1) {
    int idx = 0;
    int c = getopt_long(argc, argv, "heagi:k:d:p:b:w:n:", opts, &idx);

    if (c == -1) break;

    switch (c) {
      case 'i': {
        char *index = optarg;
        if (strcmp(index, "btree") == 0) {
          state.index = INDEX_TYPE_BTREE;
        } else if (strcmp(index, "bwtree") == 0) {
          state.index = INDEX_TYPE_BWTREE;
        } else {
          LOG_ERROR("Unknown index: %s", index);
          exit(EXIT_FAILURE);
        }
        break;
      }
      case 'k':
        state.scale_factor = atof(optarg);
        break;
      case 'd':
        state.duration = atof(optarg);
        break;
      case 'p':
        state.profile_duration = atof(optarg);
        break;
      case 'b':
        state.backend_count = atoi(optarg);
        break;
      case 'w':
        state.warehouse_count = atoi(optarg);
        break;
      case 'e':
        state.exp_backoff = true;
        break;
      case 'a':
        state.affinity = true;
        break;
      case 'g':
        state.gc_mode = true;
        break;
      case 'n':
        state.gc_backend_count = atof(optarg);
        break;

      case 'h':
        Usage(stderr);
        exit(EXIT_FAILURE);
        break;

      default:
        LOG_ERROR("Unknown option: -%c-", c);
        Usage(stderr);
        exit(EXIT_FAILURE);
    }
  }

  // Static TPCC parameters
  state.item_count = 100000 * state.scale_factor;
  state.districts_per_warehouse = 10;
  state.customers_per_district = 3000 * state.scale_factor;
  state.new_orders_per_district = 900 * state.scale_factor;

  // Print configuration
  ValidateIndex(state);
  ValidateScaleFactor(state);
  ValidateDuration(state);
  ValidateProfileDuration(state);
  ValidateBackendCount(state);
  ValidateWarehouseCount(state);
  ValidateGCBackendCount(state);

  LOG_TRACE("%s : %d", "Run client affinity", state.run_affinity);
  LOG_TRACE("%s : %d", "Run exponential backoff", state.run_backoff);
  LOG_TRACE("%s : %d", "Run garbage collection", state.gc_mode);
}
// Returns TRUE if the assignment was changed
BOOL CEffect::EvaluateAssignment(SAssignment *pAssignment)
{
    BOOL bNeedUpdate = FALSE;
    SGlobalVariable *pVarDep0, *pVarDep1;
    
    switch (pAssignment->AssignmentType)
    {
    case ERAT_NumericVariable:
        D3DXASSERT(pAssignment->DependencyCount == 1);
        if (pAssignment->pDependencies[0].pVariable->LastModifiedTime >= pAssignment->LastRecomputedTime)
        {
            dwordMemcpy(pAssignment->Destination.pNumeric, pAssignment->Source.pNumeric, pAssignment->DataSize);
            bNeedUpdate = TRUE;
        }
        break;

    case ERAT_NumericVariableIndex:
        D3DXASSERT(pAssignment->DependencyCount == 2);
        pVarDep0 = pAssignment->pDependencies[0].pVariable;
        pVarDep1 = pAssignment->pDependencies[1].pVariable;

        if (pVarDep0->LastModifiedTime >= pAssignment->LastRecomputedTime)
        {
            m_FXLIndex = *pVarDep0->Data.pNumericDword;

            ValidateIndex(pVarDep1->pType->Elements);

            // Array index variable is dirty, update the pointer
            pAssignment->Source.pNumeric = pVarDep1->Data.pNumeric + pVarDep1->pType->Stride * m_FXLIndex;
            
            // Copy the new data
            dwordMemcpy(pAssignment->Destination.pNumeric, pAssignment->Source.pNumeric, pAssignment->DataSize);
            bNeedUpdate = TRUE;
        }
        else if (pVarDep1->LastModifiedTime >= pAssignment->LastRecomputedTime)
        {
            // Only the array variable is dirty, copy the new data
            dwordMemcpy(pAssignment->Destination.pNumeric, pAssignment->Source.pNumeric, pAssignment->DataSize);
            bNeedUpdate = TRUE;
        }
        break;

    case ERAT_ObjectVariableIndex:
        D3DXASSERT(pAssignment->DependencyCount == 1);
        pVarDep0 = pAssignment->pDependencies[0].pVariable;
        if (pVarDep0->LastModifiedTime >= pAssignment->LastRecomputedTime)
        {
            m_FXLIndex = *pVarDep0->Data.pNumericDword;
            ValidateIndex(pAssignment->MaxElements);

            // Array index variable is dirty, update the destination pointer
            *((void **)pAssignment->Destination.pGeneric) = pAssignment->Source.pNumeric +
                pAssignment->DataSize * m_FXLIndex;
            bNeedUpdate = TRUE;
        }
        break;

    default:
    //case ERAT_Constant:           -- These are consumed and discarded
    //case ERAT_ObjectVariable:     -- These are consumed and discarded
    //case ERAT_ObjectConstIndex:   -- These are consumed and discarded
    //case ERAT_ObjectInlineShader: -- These are consumed and discarded
    //case ERAT_NumericConstIndex:  -- ERAT_NumericVariable should be generated instead
        D3DXASSERT(0);
        break;
    }
    
    // Mark the assignment as not dirty
    pAssignment->LastRecomputedTime = m_LocalTimer;

    return bNeedUpdate;
}
Exemple #16
0
void FilterB(int Tlen_, char *B_, int Qlen_, const FilterParams &FP, int Diameter,
  bool Comp)
	{
	if (Comp)
		Quit("-diameter requires -fwdonly (this needs to be fixed!)");

	SeqQ = B_;
	Tlen = Tlen_;
	Qlen = Qlen_;

	MinMatch = FP.SeedLength;
	MaxError = FP.SeedDiffs;
	TubeOffset = FP.TubeOffset;

	const int Kmask = pow4(k) - 1;

// Ukonnen's Lemma
	MinKmersPerHit = MinMatch + 1 - k*(MaxError + 1);

// Maximum distance between SeqQ positions of two k-mers in a match
// (More stringent bounds may be possible, but not a big problem
// if two adjacent matches get merged).
	MaxKmerDist = MinMatch - k;

	TubeWidth = TubeOffset + MaxError;

	if (TubeOffset < MaxError)
		{
		Log("TubeOffset < MaxError\n");
		exit(1);
		}
	if (MinKmersPerHit <= 0)
		{
		Log("MinKmersPerHit <= 0\n");
		exit(1);
		}

	MaxActiveTubes = (Tlen + TubeWidth - 1)/TubeOffset + 1;
	Tubes = all(TubeState, MaxActiveTubes);
	zero(Tubes, TubeState, MaxActiveTubes);

// Ticker tracks cycling of circular list of active tubes.
	int Ticker = TubeWidth;

// Initialize index to cover first window
	int StartKmerValidPos = 0;
	int EndKmerValidPos = 0;

	AllocateIndex(Diameter, k);
	const int KmerCount = Diameter - k + 1;

	int Start;
	int End;

	for (Start = 0; Start < KmerCount; ++Start)
		{
		int StartKmer = GetKmer(SeqQ, Start);
		AddToIndex(StartKmer, Start);
		}

#if	DEBUG
	ValidateIndex(SeqQ, 0, Diameter - k);
#endif

// Scan entire sequence.
// Start is coordinate of first base in first k-mer in sliding window
// End is coordinate of first base in last k-mer in sliding window
	Start = 0;
	End = Start + Diameter - k;

	int StartKmer = GetKmer(SeqQ, Start);
	if (StartKmer == -1)
		{
		StartKmer = 0;
		StartKmerValidPos = Start + k + 1;
		}
	int EndKmer = GetKmer(SeqQ, End);
	if (EndKmer == -1)
		{
		EndKmer = 0;
		EndKmerValidPos = End + k + 1;
		}
	for (; End < Qlen - k; ++Start, ++End)
		{
#if	DEBUG
		if (Start%10000 == 0)
			fprintf(stderr, "%d\n", Start);
		//if (Start%1000 == 0)
		//	ValidateIndex(SeqQ, Start, End);
#endif
		if (Start >= StartKmerValidPos)
			{
			assert(StartKmer == GetKmer(SeqQ, Start));
			for (DeclareListPtr(p) = GetListPtr(StartKmer); NotEndOfList(p); p = GetListNext(p))
				{
				int HitPos = GetListPos(p);
				CommonKmer(Start, HitPos);
				}
			DeleteFirstInstanceFromIndex(StartKmer, Start);
			}

		if (0 == --Ticker)
			{
			TubeEnd(Start);
			Ticker = TubeOffset;
			}

		{
		char c = SeqQ[Start + k];
		int x = CharToLetter[c];
		if (x < 0)
			{
			StartKmer = 0;
			StartKmerValidPos = Start + k + 1;
			}
		else
			StartKmer = ((StartKmer << 2) | x) & Kmask;
		}

		{
		char c = SeqQ[End + k];
		int x = CharToLetter[c];
		if (x < 0)
			{
			EndKmer = 0;
			EndKmerValidPos = End + k + 1;
			}
		else
			EndKmer = ((EndKmer << 2) | x) & Kmask;

		if (End+1 >= EndKmerValidPos)
			{
			assert(EndKmer == GetKmer(SeqQ, End+1));
			AddToIndex(EndKmer, End+1);
			}
		}
		}

#if	DEBUG
	ValidateIndex(SeqQ, Start, Qlen - k);
#endif

// Special case for end of sequence, don't slide the index
// for the last Diameter bases.
	for (; Start < Qlen - k; ++Start)
		{
		{
		char c = SeqQ[Start + k];
		int x = CharToLetter[c];
		if (x < 0)
			{
			StartKmer = 0;
			StartKmerValidPos = Start + k + 1;
			}
		else
			StartKmer = ((StartKmer << 2) | x) & Kmask;
		}

		if (Start >= StartKmerValidPos)
			{
			for (DeclareListPtr(p) = GetListPtr(StartKmer); NotEndOfList(p); p = GetListNext(p))
				{
				int HitPos = GetListPos(p);
				CommonKmer(Start, HitPos);
				}
			}

		if (0 == --Ticker)
			{
			TubeEnd(Start);
			Ticker = TubeOffset;
			}
		}

	TubeEnd(Qlen - 1);

	int DiagFrom = CalcDiagIndex(Tlen - 1, Qlen - 1) - TubeWidth;
	int DiagTo = CalcDiagIndex(0, Qlen - 1) + TubeWidth;

	int TubeFrom = CalcTubeIndex(DiagFrom);
	if (TubeFrom < 0)
		TubeFrom = 0;

	int TubeTo = CalcTubeIndex(DiagTo);

	for (int TubeIndex = TubeFrom; TubeIndex <= TubeTo; ++TubeIndex)
		TubeFlush(TubeIndex);

	freemem(Tubes);
	}
void ParseArguments(int argc, char *argv[], configuration &state) {
  // Default Values
  state.index = INDEX_TYPE_BWTREE;
  state.scale_factor = 1;
  state.duration = 10;
  state.profile_duration = 1;
  state.backend_count = 2;
  state.column_count = 10;
  state.operation_count = 10;
  state.update_ratio = 0.5;
  state.zipf_theta = 0.0;
  state.exp_backoff = false;
  state.string_mode = false;
  state.gc_mode = false;
  state.gc_backend_count = 1;

  // Parse args
  while (1) {
    int idx = 0;
    int c = getopt_long(argc, argv, "hemgi:k:d:p:b:c:o:u:z:n:", opts, &idx);

    if (c == -1) break;

    switch (c) {
      case 'i': {
        char *index = optarg;
        if (strcmp(index, "btree") == 0) {
          state.index = INDEX_TYPE_BTREE;
        } else if (strcmp(index, "bwtree") == 0) {
          state.index = INDEX_TYPE_BWTREE;
        } else {
          LOG_ERROR("Unknown index: %s", index);
          exit(EXIT_FAILURE);
        }
        break;
      }
      case 'k':
        state.scale_factor = atoi(optarg);
        break;
      case 'd':
        state.duration = atof(optarg);
        break;
      case 'p':
        state.profile_duration = atof(optarg);
        break;
      case 'b':
        state.backend_count = atoi(optarg);
        break;
      case 'c':
        state.column_count = atoi(optarg);
        break;
      case 'o':
        state.operation_count = atoi(optarg);
        break;
      case 'u':
        state.update_ratio = atof(optarg);
        break;
      case 'z':
        state.zipf_theta = atof(optarg);
        break;
      case 'e':
        state.exp_backoff = true;
        break;
      case 'm':
        state.string_mode = true;
        break;
      case 'g':
        state.gc_mode = true;
        break;
      case 'n':
        state.gc_backend_count = atof(optarg);
        break;
        
      case 'h':
        Usage(stderr);
        exit(EXIT_FAILURE);
        break;

      default:
        LOG_ERROR("Unknown option: -%c-", c);
        Usage(stderr);
        exit(EXIT_FAILURE);
        break;
    }
  }

  // Print configuration
  ValidateIndex(state);
  ValidateScaleFactor(state);
  ValidateDuration(state);
  ValidateProfileDuration(state);
  ValidateBackendCount(state);
  ValidateColumnCount(state);
  ValidateOperationCount(state);
  ValidateUpdateRatio(state);
  ValidateZipfTheta(state);
  ValidateGCBackendCount(state);

  LOG_TRACE("%s : %d", "Run exponential backoff", state.exp_backoff);
  LOG_TRACE("%s : %d", "Run string mode", state.string_mode);
  LOG_TRACE("%s : %d", "Run garbage collection", state.gc_mode);
  
}
const wchar_t* FdoRdbmsSQLDataReader::GetColumnName(FdoInt32 index)
{
    ValidateIndex(index);
    return mColList[index].column;
}
FdoDataType FdoRdbmsSQLDataReader::GetColumnType(FdoInt32 index)
{
    ValidateIndex(index);
    return FdoRdbmsUtil::DbiToFdoType( mColList[index].datatype );
}