예제 #1
0
void SampleVehicleSetupVehicleShapeQueryFilterData(PxFilterData* qryFilterData)
{
	CHECK_MSG(0==qryFilterData->word3, "word3 is reserved for filter data for vehicle raycast queries");
	qryFilterData->word3 = (PxU32)SAMPLEVEHICLE_UNDRIVABLE_SURFACE;
}
예제 #2
0
static int DEHT_queryEx(DEHT *ht, const unsigned char *key, int keyLength, const unsigned char *data, int dataMaxAllowedLength,
			byte_t * keyBlockOut, ulong_t keyBlockSize, DEHT_DISK_PTR * keyBlockDiskOffset, ulong_t * keyIndex)
{
	int ret = DEHT_STATUS_FAIL;

	int hashTableIndex = 0;
	byte_t * validationKey = NULL;

	KeyFilePair_t * currPair = NULL;

	DEHT_DISK_PTR dataBlockOffset = 0;
	ulong_t bytesRead = 0;

	TRACE_FUNC_ENTRY();

	CHECK(NULL != ht);
	CHECK(NULL != key);
	CHECK(NULL != data);

	CHECK(NULL != keyBlockOut);
	CHECK(KEY_FILE_BLOCK_SIZE(ht) <= keyBlockSize);

	CHECK(NULL != keyBlockDiskOffset);
	CHECK(NULL != keyIndex);

	TRACE_FPRINTF((stderr, "TRACE: %s:%d (%s): key=%s\n", __FILE__, __LINE__, __FUNCTION__, key));

	/* calc hash for key */
	CHECK(NULL != ht->hashFunc);
	hashTableIndex = ht->hashFunc(key, keyLength, ht->header.numEntriesInHashTable);
	TRACE_FPRINTF((stderr, "TRACE: %s:%d (%s): bucket index=%#x\n", __FILE__, __LINE__, __FUNCTION__, (uint_t) hashTableIndex));


	CHECK(DEHT_findFirstBlockForBucketAndAlloc(ht, hashTableIndex, keyBlockDiskOffset));
	CHECK(0 != *keyBlockDiskOffset);

	TRACE_FPRINTF((stderr, "TRACE: %s:%d (%s): first block for bucket %d at offset=%#x\n", __FILE__, __LINE__, __FUNCTION__, hashTableIndex, (uint_t) *keyBlockDiskOffset));

	/* If there is no block for this bucket, return with nothing */
	if (0 == *keyBlockDiskOffset) {
		ret = DEHT_STATUS_NOT_NEEDED;
		goto LBL_CLEANUP;
	}


	/* alloc space and calc validation key */
	validationKey = malloc(ht->header.nBytesPerValidationKey);
	CHECK_MSG("malloc", (NULL != validationKey));

	/*! Note: return value isn't checked since the spec does not include details regarding the key 
		  validation function interface */
	CHECK(NULL != ht->comparisonHashFunc);
	(void) ht->comparisonHashFunc(key, keyLength, validationKey);

	while (0 != *keyBlockDiskOffset) {
		/* read block to mem */
		CHECK_MSG(ht->sKeyfileName, (pfread(ht->keyFP, *keyBlockDiskOffset, keyBlockOut, KEY_FILE_BLOCK_SIZE(ht))));

		/* scan this block */
		for(*keyIndex = 0;  *keyIndex < ht->header.nPairsPerBlock;  ++*keyIndex) {

			currPair = GET_N_REC_PTR_IN_BLOCK(ht, keyBlockOut, *keyIndex);

			if (0 == memcmp(currPair->key, validationKey, ht->header.nBytesPerValidationKey)) {
				break;
			}	
		}

		if (*keyIndex < ht->header.nPairsPerBlock) {
			break;
		}

		/* disk offset of the next pointer is the last element in the block */
		*keyBlockDiskOffset = *( (DEHT_DISK_PTR *) (keyBlockOut + KEY_FILE_BLOCK_SIZE(ht) - sizeof(DEHT_DISK_PTR)) );
		TRACE_FPRINTF((stderr, "TRACE: %s:%d (%s): next ptr from disk: %#x\n", __FILE__, __LINE__, __FUNCTION__, (uint_t) *keyBlockDiskOffset));
	}

	dataBlockOffset = 0;
	if (*keyIndex < ht->header.nPairsPerBlock) {
		dataBlockOffset = currPair->dataOffset;
	}
	else {
		/* we scanned everything, but found no matching key */
		ret = DEHT_STATUS_NOT_NEEDED;
		TRACE("key not found");
		goto LBL_CLEANUP;
	}

	bytesRead = 0;
	CHECK(DEHT_readDataAtOffset(ht, dataBlockOffset, (byte_t *) data, dataMaxAllowedLength, &bytesRead));

	TRACE("key found");

	ret = bytesRead;
	goto LBL_CLEANUP;
	
LBL_ERROR:
	ret = DEHT_STATUS_FAIL;
	TRACE_FUNC_ERROR();

LBL_CLEANUP:
	FREE(validationKey);

	TRACE_FUNC_EXIT();
	return ret;
}
예제 #3
0
static DEHT * DEHT_initInstance (const char * prefix, char * fileMode, 
			   hashKeyIntoTableFunctionPtr hashfun, hashKeyforEfficientComparisonFunctionPtr validfun)
{
	bool_t filesAlreadyExist = FALSE;
	bool_t errorState = TRUE;
	bool_t deleteFilesOnError = FALSE;

	DEHT * ht = NULL;

	char tempFileMode[MAX_FILE_MODE_LEN] = {0};

	TRACE_FUNC_ENTRY();

	/* sanity */
	CHECK(NULL != prefix);
	CHECK(NULL != fileMode);
	CHECK(NULL != hashfun);
	CHECK(NULL != validfun);

	ht = malloc(sizeof(DEHT));
	CHECK_MSG("malloc", (NULL != ht));

	memset(ht, 0, sizeof(DEHT));

	SAFE_STRNCPY(ht->sKeyfileName, prefix, sizeof(ht->sKeyfileName));
	SAFE_STRNCAT(ht->sKeyfileName, KEY_FILE_EXT, sizeof(ht->sKeyfileName));

	SAFE_STRNCPY(ht->sDatafileName, prefix, sizeof(ht->sKeyfileName));
	SAFE_STRNCAT(ht->sDatafileName, DATA_FILE_EXT, sizeof(ht->sKeyfileName));

	/* Open key file. If file mode begins with 'c', first check that the file does not exist */
	SAFE_STRNCPY(tempFileMode, fileMode, sizeof(tempFileMode));
	if ('c' == tempFileMode[0]) {
		/* we were asked to make sure the files weren't already present first */
		ht->keyFP = fopen(ht->sKeyfileName, "rb");
		if (NULL != ht->keyFP) {
			deleteFilesOnError = FALSE;
			filesAlreadyExist = TRUE;
			fprintf(stderr, "Error: File \"%s\" already exist\n", ht->sKeyfileName);
		}

		ht->dataFP = fopen(ht->sDatafileName, "rb");
		if (NULL != ht->dataFP) {
			deleteFilesOnError = FALSE;
			filesAlreadyExist = TRUE;
			fprintf(stderr, "Error: File \"%s\" already exist\n", ht->sDatafileName);
		}

		/* fail if files already exist */
		CHECK(!filesAlreadyExist);

		/* that check passed. Now modify the file mode back to a standard one */
		tempFileMode[0] = 'w';
		/* From now on, if we fail, we'd like to clean up the files */
		deleteFilesOnError = TRUE;
	}

	/* Open key file */
	ht->keyFP = fopen(ht->sKeyfileName, tempFileMode);
	CHECK_MSG(ht->sKeyfileName, (NULL != ht->keyFP));

	/* Open data file */
	ht->dataFP = fopen(ht->sDatafileName, tempFileMode);
	CHECK_MSG(ht->sDatafileName, (NULL != ht->dataFP));
	
	ht->hashTableOfPointersImageInMemory = NULL;
	ht->hashPointersForLastBlockImageInMemory = NULL;

	ht->hashFunc = hashfun;
	ht->comparisonHashFunc = validfun;

	errorState = FALSE;
	goto LBL_CLEANUP;


LBL_ERROR:
	errorState = TRUE;
	TRACE_FUNC_ERROR();

LBL_CLEANUP:
	if (errorState) {
		if (NULL != ht) {
			DEHT_freeResources(ht, deleteFilesOnError);
		}
		ht = NULL;
	}

	TRACE_FUNC_EXIT();
	return ht;
}
예제 #4
0
int insert_uniquely_DEHT ( DEHT *ht, const unsigned char *key, int keyLength, 
				 const unsigned char *data, int dataLength)
{
	int ret = DEHT_STATUS_FAIL;

	byte_t * tempKeyBlock = NULL;
	DEHT_DISK_PTR keyBlockDiskOffset = 0;
	ulong_t keyIndex = 0;
	
	KeyFilePair_t * targetRecord = NULL;
	DEHT_DISK_PTR newDataOffset = 0;
	
	byte_t tempData[DEHT_MAX_DATA_LEN] = {0};

	TRACE_FUNC_ENTRY();

	CHECK(NULL != ht);
	CHECK(NULL != key);
	CHECK(NULL != data);

	/* allocate a buffer for DEHT_queryEx */
	tempKeyBlock = malloc(KEY_FILE_BLOCK_SIZE(ht));
	CHECK_MSG("malloc", (NULL != tempKeyBlock));
	
	ret = DEHT_queryEx(ht, key, keyLength, tempData, sizeof(tempData), tempKeyBlock, KEY_FILE_BLOCK_SIZE(ht), 
				  &keyBlockDiskOffset, &keyIndex);

	switch(ret) {
	case DEHT_STATUS_NOT_NEEDED:
		TRACE("simple insert");
		/* not found - just insert */
		CHECK(DEHT_STATUS_SUCCESS == add_DEHT (ht, key, keyLength, data, dataLength));

		ret = DEHT_STATUS_SUCCESS;

		break;

	case DEHT_STATUS_FAIL:
	default:
		if (0 >= ret) {
			/* internal error */
			goto LBL_ERROR;
		}


		/* if we got here, the key was found */
		TRACE_FPRINTF((stderr, "TRACE: %s:%d (%s): key already in DEHT. Updating record at %#x\n", __FILE__, __LINE__, __FUNCTION__, (uint_t) keyBlockDiskOffset));

		/* update data in the data file */
		CHECK(DEHT_addData(ht, data, dataLength, &newDataOffset)); 

		/* get the key record */
		targetRecord = GET_N_REC_PTR_IN_BLOCK(ht, tempKeyBlock, keyIndex);
		/* update key record */
		targetRecord->dataOffset = newDataOffset;

		/* update block on disk */
		CHECK_MSG(ht->sKeyfileName, (pfwrite(ht->keyFP, keyBlockDiskOffset, tempKeyBlock, KEY_FILE_BLOCK_SIZE(ht))));

		ret = DEHT_STATUS_NOT_NEEDED;
		
		break;
	}

	goto LBL_CLEANUP;	

LBL_ERROR:
	ret = DEHT_STATUS_FAIL;
	TRACE_FUNC_ERROR();

LBL_CLEANUP:
	FREE(tempKeyBlock);

	TRACE_FUNC_EXIT();
	return ret;
}
예제 #5
0
static bool_t DEHT_allocEmptyLocationInBucket(DEHT * ht, ulong_t bucketIndex,
					     byte_t * blockDataOut, ulong_t blockDataLen,
					     DEHT_DISK_PTR * blockDiskPtr, ulong_t * firstFreeIndex)
{
	bool_t ret = FALSE;

	DEHT_DISK_PTR newBlock = 0;

	TRACE_FUNC_ENTRY();

	CHECK(NULL != ht);
	CHECK(bucketIndex < ht->header.numEntriesInHashTable);
	CHECK(NULL != blockDataOut);
	CHECK(KEY_FILE_BLOCK_SIZE(ht) <= blockDataLen);
	CHECK(NULL != blockDiskPtr);
	CHECK(NULL != firstFreeIndex);

	CHECK(DEHT_findLastBlockForBucket(ht, bucketIndex, blockDiskPtr));
	if (0 == *blockDiskPtr) {
		/* if this is the first ever block, call DEHT_findFirstBlockForBucketAndAlloc() which will also alloc the first block */
		CHECK(DEHT_findFirstBlockForBucketAndAlloc(ht, bucketIndex, blockDiskPtr));
		CHECK(0 != *blockDiskPtr);
	}

	/* read it */
	CHECK_MSG(ht->sKeyfileName, (pfread(ht->keyFP, *blockDiskPtr, blockDataOut, KEY_FILE_BLOCK_SIZE(ht))));

	/* get the current used block count */
	*firstFreeIndex = GET_USED_RECORD_COUNT(blockDataOut);
	
	/* see if this block is full */
	if (*firstFreeIndex >= ht->header.nPairsPerBlock) {
	
		newBlock = DEHT_allocKeyBlock(ht);
		CHECK(0 != newBlock);

		/* update old block */
		SET_NEXT_BLOCK_PTR(ht, blockDataOut, newBlock);
	
		/* update last block reference if cache is present */
		if (NULL != ht->hashPointersForLastBlockImageInMemory) {
			ht->hashPointersForLastBlockImageInMemory[bucketIndex] = newBlock;
		}
		
		CHECK_MSG(ht->sKeyfileName, (pfwrite(ht->keyFP, *blockDiskPtr, blockDataOut, KEY_FILE_BLOCK_SIZE(ht))));
		
		/* now, just return the reference to the start of the new block */
		memset(blockDataOut, 0, KEY_FILE_BLOCK_SIZE(ht));
		*blockDiskPtr = newBlock;
		*firstFreeIndex = 0;
	}

	/* increase used pairs count by one. If & when the user will update the block on disk, this will be updated as well */
	SET_USED_RECORD_COUNT(blockDataOut, GET_USED_RECORD_COUNT(blockDataOut) + 1);

	ret = TRUE;
	goto LBL_CLEANUP;

LBL_ERROR:
	*blockDiskPtr = 0;
	*firstFreeIndex = 0;
	ret = FALSE;
	TRACE_FUNC_ERROR();

LBL_CLEANUP:
	TRACE_FUNC_EXIT();
	return ret;
}