hashfile/src/hash_file.c
HT_ErrorCode HT_InsertEntry(int indexDesc, Record record) {
    // Read the number of buckets in the file. The bucket where the record should be inserted is given throught the hash function.
    // In this implementation the hash function uses the number of buckets: hash = id MOD no_of_buckets.

    char *data;
    BF_Block *block;
    BF_Block_Init(&block);

    // The number of buckets is stored in the first block of the hashfile.
    int buckets_number = table[indexDesc];
    int bucket_position = hash(record.id, buckets_number);

    // We need to find the last position where we add the record.
    int records;
    int next_block;
    int previous_block = bucket_position;
    CALL_BF(BF_GetBlock(indexDesc, bucket_position, block));
    data = BF_Block_GetData(block);
    memcpy(&records, data, sizeof(int));
    memcpy(&next_block, data+sizeof(int), sizeof(int));

    // Each time we know there exists a next_block and our block is full, we have to follow to that block, until we find the end.
    while(next_block != 0 && records == MAX_RECORDS){
	    CALL_BF(BF_UnpinBlock(block));
	    CALL_BF(BF_GetBlock(indexDesc, next_block, block));
	    data = BF_Block_GetData(block);
	    memcpy(&records, data, sizeof(int));
	    memcpy(&next_block, data+sizeof(int), sizeof(int));
    }
    // When there is no next_block, but our records are maxxed out, we have to allocate a new block and 'link' it.
    if(records == MAX_RECORDS){
	int blocks_number;
    	CALL_BF(BF_GetBlockCounter(indexDesc, &blocks_number));
	memcpy(data+sizeof(int), &blocks_number, sizeof(int));
	BF_Block_SetDirty(block);
	CALL_BF(BF_UnpinBlock(block));

	records = 1;
	next_block = 0;
	CALL_BF(BF_AllocateBlock(indexDesc, block));
	data = BF_Block_GetData(block);
	memcpy(data, &records, sizeof(int));
	memcpy(data+sizeof(int), &next_block, sizeof(int));
    } else {
    	// Otherwise, use this trick to increment the number of records in the block where the record will be added.
	records++;
	memcpy(data, &records, sizeof(int));
    }

    // All that remains, is to place the record in the correct position, meaning underneath all records.
    memcpy(data+sizeof(int)*2+sizeof(Record)*(records-1), &record, sizeof(Record));
    BF_Block_SetDirty(block);
    CALL_BF(BF_UnpinBlock(block));
    BF_Block_Destroy(&block);

    return HT_OK;
}
/**
 * To InsertEntry in the file all that needs to be done is:
 * 	1. Find its bucket.
 * 	2. Find the position (last record in the bucket).
 * 	3. Insert the record to that position.
 * If there is a need to allocate a new block to the bucket, make sure to chain it with the previous one.
 */
To InsertEntry in the file all that needs to be done is:
1. Find its bucket.
2. Find the position (last record in the bucket).
3. Insert the record to that position.
If there is a need to allocate a new block to the bucket, make sure to chain it with the previous one.
To InsertEntry in the file all that needs to be done is : 1 . Find its bucket . 2 . Find the position ( last record in the bucket ) . 3 . Insert the record to that position . If there is a need to allocate a new block to the bucket make sure to chain it with the previous one .
HT_ErrorCode HT_InsertEntry(int indexDesc, Record record) {
    char *data;
    BF_Block *block;
    BF_Block_Init(&block);
    int buckets_number = table[indexDesc];
    int bucket_position = hash(record.id, buckets_number);
    int records;
    int next_block;
    int previous_block = bucket_position;
    CALL_BF(BF_GetBlock(indexDesc, bucket_position, block));
    data = BF_Block_GetData(block);
    memcpy(&records, data, sizeof(int));
    memcpy(&next_block, data+sizeof(int), sizeof(int));
    while(next_block != 0 && records == MAX_RECORDS){
	    CALL_BF(BF_UnpinBlock(block));
	    CALL_BF(BF_GetBlock(indexDesc, next_block, block));
	    data = BF_Block_GetData(block);
	    memcpy(&records, data, sizeof(int));
	    memcpy(&next_block, data+sizeof(int), sizeof(int));
    }
    if(records == MAX_RECORDS){
	int blocks_number;
    	CALL_BF(BF_GetBlockCounter(indexDesc, &blocks_number));
	memcpy(data+sizeof(int), &blocks_number, sizeof(int));
	BF_Block_SetDirty(block);
	CALL_BF(BF_UnpinBlock(block));
	records = 1;
	next_block = 0;
	CALL_BF(BF_AllocateBlock(indexDesc, block));
	data = BF_Block_GetData(block);
	memcpy(data, &records, sizeof(int));
	memcpy(data+sizeof(int), &next_block, sizeof(int));
    } else {
	records++;
	memcpy(data, &records, sizeof(int));
    }
    memcpy(data+sizeof(int)*2+sizeof(Record)*(records-1), &record, sizeof(Record));
    BF_Block_SetDirty(block);
    CALL_BF(BF_UnpinBlock(block));
    BF_Block_Destroy(&block);
    return HT_OK;
}
HT_ErrorCode HT_InsertEntry ( int indexDesc , Record record ) { char * data ; BF_Block * block ; BF_Block_Init ( & block ) ; int buckets_number = table [ indexDesc ] ; int bucket_position = hash ( record . id , buckets_number ) ; int records ; int next_block ; int previous_block = bucket_position ; CALL_BF ( BF_GetBlock ( indexDesc , bucket_position , block ) ) ; data = BF_Block_GetData ( block ) ; memcpy ( & records , data , sizeof ( int ) ) ; memcpy ( & next_block , data + sizeof ( int ) , sizeof ( int ) ) ; while ( next_block != 0 && records == MAX_RECORDS ) { CALL_BF ( BF_UnpinBlock ( block ) ) ; CALL_BF ( BF_GetBlock ( indexDesc , next_block , block ) ) ; data = BF_Block_GetData ( block ) ; memcpy ( & records , data , sizeof ( int ) ) ; memcpy ( & next_block , data + sizeof ( int ) , sizeof ( int ) ) ; } if ( records == MAX_RECORDS ) { int blocks_number ; CALL_BF ( BF_GetBlockCounter ( indexDesc , & blocks_number ) ) ; memcpy ( data + sizeof ( int ) , & blocks_number , sizeof ( int ) ) ; BF_Block_SetDirty ( block ) ; CALL_BF ( BF_UnpinBlock ( block ) ) ; records = 1 ; next_block = 0 ; CALL_BF ( BF_AllocateBlock ( indexDesc , block ) ) ; data = BF_Block_GetData ( block ) ; memcpy ( data , & records , sizeof ( int ) ) ; memcpy ( data + sizeof ( int ) , & next_block , sizeof ( int ) ) ; } else { records ++ ; memcpy ( data , & records , sizeof ( int ) ) ; } memcpy ( data + sizeof ( int ) * 2 + sizeof ( Record ) * ( records - 1 ) , & record , sizeof ( Record ) ) ; BF_Block_SetDirty ( block ) ; CALL_BF ( BF_UnpinBlock ( block ) ) ; BF_Block_Destroy ( & block ) ; return HT_OK ; }
To InsertEntry in the file all that needs to be done is:
      1.
To InsertEntry in the file all that needs to be done is : 1 .
// Read the number of buckets in the file. The bucket where the record should be inserted is given throught the hash function. // In this implementation the hash function uses the number of buckets: hash = id MOD no_of_buckets. // The number of buckets is stored in the first block of the hashfile. // We need to find the last position where we add the record. // Each time we know there exists a next_block and our block is full, we have to follow to that block, until we find the end. // When there is no next_block, but our records are maxxed out, we have to allocate a new block and 'link' it. // Otherwise, use this trick to increment the number of records in the block where the record will be added. // All that remains, is to place the record in the correct position, meaning underneath all records.