long long find_free_list_tail(INDEX_FILE *index_file){ FILE *fp; long long free_head; void *bucket; long long last; bucket = calloc(BSIZE,sizeof(char)); if (bucket==NULL){ printf("Malloc failed"); exit(1); } fp=fopen(index_file->overflow_path,"r"); if (fp == NULL){ printf("fail to open file\n"); exit(1); } fseek(fp, 3*sizeof(long long), SEEK_SET); fread(&free_head, sizeof(long long),1,fp); if (free_head == -1){ fclose(fp); free(bucket); return -1; } else { do{ read_bucket(bucket, free_head, index_file->overflow_path); last = free_head; free_head = ((long long*)(bucket+4))[0]; } while (free_head != -1); fclose(fp); free(bucket); return last; } }
int find_bucket(long long hash_index, long long *bid, int*mo, INDEX_FILE *index_file){ void *bucket; int tmp_bid; bucket = calloc(BSIZE,sizeof(char)); if (bucket==NULL){ printf("Malloc failed"); exit(1); } read_bucket(bucket, hash_index, index_file->main_path); if (((long long*)(bucket+4))[0]==-1){ if (((int*)bucket)[0] < BSIZE-sizeof(long long)-atoi((index_file->type)+1)) { *bid = hash_index; *mo = 0; free(bucket); return 0; } else { *bid = create_overflow_bucket(index_file); mylink(hash_index, 0, *bid, index_file); *mo = 1; free(bucket); return 1; } } else { long long next_bid = ((long long*)(bucket+4))[0]; do { read_bucket(bucket, next_bid, index_file->overflow_path); tmp_bid = next_bid; next_bid = ((long long*)(bucket+4))[0]; } while(next_bid != -1); if (((int*)bucket)[0] < BSIZE-sizeof(long long)-atoi((index_file->type)+1)) { *bid = tmp_bid; *mo = 1; free(bucket); return 0; } else { *bid = create_overflow_bucket(index_file); mylink(tmp_bid, 1, *bid, index_file); *mo = 1; free(bucket); return 1; } } }
void mylink(long long from, int frommo, long long to, INDEX_FILE *index_file){ void *bucket; char *path; bucket = calloc(BSIZE,sizeof(char)); if (bucket==NULL){ printf("Malloc failed"); exit(1); } if(frommo == 0){ path = index_file->main_path; read_bucket(bucket, from, path); }else{ path = index_file->overflow_path; read_bucket(bucket, from, path); } ((long long*)(bucket+4))[0]=to; write_bucket(bucket, from, path); free(bucket); return; }
uint16_t next_message(uint16_t id, uint16_t start, struct Bucket *buf) { uint16_t address = id_next_message(id, start); if (address == END_REACHED) buf->state = 0; else { read_bucket(address, buf); buf->state |= 1; } return address; }
void hash_record(HFILE *hf, void* record, int i, RID rid, INDEX_FILE *index_file){ //void *buf; int offset=0; int j; long long hash_index; long long bid; int split; int mo; void *bucket; char *path; bucket = calloc(BSIZE,sizeof(char)); if (bucket==NULL){ printf("Malloc failed"); exit(1); } //buf = malloc(105*sizeof(char)); /*if (buf==NULL){ printf("Malloc failed"); exit(1); }*/ for(j=0;j<i;j++){ offset+=atoi((hf->schema[j])+1); } //(*decode[hf->schema_array[i]])(record, buf, &offset,atoi((hf->schema[i])+1)); hash_index = (*calculate_index[hf->schema_array[i]])(record,index_file->s,index_file->n,offset); split = find_bucket(hash_index, &bid, &mo, index_file); if (mo==0){ path = index_file->main_path; } else { path = index_file->overflow_path; } read_bucket(bucket, bid, path); (*update_bucket[hf->schema_array[i]])(bucket,record,rid,atoi((hf->schema[i])+1)+sizeof(long long),offset); write_bucket(bucket, bid, path); if (split==1){ rehash(hf, i, index_file); } free(bucket); //free(buf); }
/** * @brief Prepare a packet containing a message, ready to be sent. * * @param address the address of the message in memory. * * msg should be built the following way: * bytes 0-7: hash * bytes 8-11: emission date * bytes 12-15: expiration date * bytes 16-17: source address * bytes 18-19: destination address * bytes 20+: content of the message, up to 140 characters * * The packet header should be 00000003 (protocol version, packet identifier), * followed by an octet indicating the length of the packet, stripped of the * header(for an empty message, that would be 20). */ static void prepare_message(uint16_t address) { tx_buffer[0] = (FIRST_BYTE << 4) | MESSAGE; struct Bucket bucket; read_bucket(address, &bucket); memcpy(tx_buffer + 2, &bucket.type.id, 8); *((uint32_t *) (tx_buffer + 10)) = bucket.emission_date; *((uint32_t *) (tx_buffer + 14)) = bucket.expiration_date; *((uint16_t *) (tx_buffer + 18)) = bucket.source_address; *((uint16_t *) (tx_buffer + 20)) = bucket.destination_address; int i = 0; while (bucket.message[i]) { tx_buffer[22 + i] = bucket.message[i]; i++; } tx_buffer[1] = 20 + i; }
long long create_overflow_bucket(INDEX_FILE *index_file){ FILE *fp; long long free_head; void * bucket; long long n_buckets; bucket = calloc(BSIZE,sizeof(char)); if (bucket==NULL){ printf("Malloc failed"); exit(1); } fp=fopen(index_file->overflow_path,"r+"); if (fp == NULL){ printf("fail to open file\n"); exit(1); } fseek(fp, 3*sizeof(long long), SEEK_SET); fread(&free_head, sizeof(long long),1,fp); fread(&n_buckets, sizeof(long long),1,fp); if (free_head == -1){ init_bucket(bucket); write_bucket(bucket, n_buckets, index_file->overflow_path); n_buckets++; fseek(fp, 4*sizeof(long long), SEEK_SET); fwrite(&n_buckets, sizeof(long long),1,fp); fclose(fp); free(bucket); return n_buckets-1; //allocate new } else { read_bucket(bucket, free_head, index_file->overflow_path); long long next_free = ((long long*)(bucket+4))[0]; fseek(fp, 3*sizeof(long long), SEEK_SET); fwrite(&next_free, sizeof(long long), 1, fp); init_bucket(bucket); write_bucket(bucket, free_head, index_file->overflow_path); fclose(fp); free(bucket); return free_head; } }
void print_index(HFILE *hf, int i, INDEX_FILE *index_file){ FILE *fp1, *fp2; fp1 = fopen(index_file->main_path,"r"); fp2 = fopen(index_file->overflow_path,"r"); void *bucket; bucket = calloc(BSIZE,sizeof(char)); int iter; int j; long long free_head; long long n_buckets; int zero = 0; void *buf = calloc(105,sizeof(char)); if (buf==NULL){ printf("Malloc failed"); exit(1); } char *line = (char*)calloc(105,sizeof(char)); if (line==NULL){ printf("Malloc failed"); exit(1); } fseek(fp2, 3*sizeof(long long), SEEK_SET); fread(&free_head, sizeof(long long),1,fp2); fread(&n_buckets, sizeof(long long),1,fp2); fclose(fp1); fclose(fp2); printf("basic info: next=%lld, n=%lld, s=%lld, free_list_header=%lld, number of buckets in overflow=%lld\n",index_file->next,index_file->n, index_file->s, free_head,n_buckets); printf("main bucket:\n"); for (iter=0; iter <index_file->n; iter++){ read_bucket(bucket, iter, index_file->main_path); int offset = ((int*)bucket)[0]; long long pointer = ((long long*)(bucket+4))[0]; printf("offset=%d, pointer=%lld\n",offset,pointer); printf("key-rid pairs:\n"); int original_usage = ((int*)bucket)[0]; for (j = 12; j < original_usage; j += atoi((hf->schema[i])+1)+sizeof(long long)){ RID rid = (*read_keypair[hf->schema_array[i]])(bucket, buf, j, atoi((hf->schema[i])+1)); (*decode[hf->schema_array[i]])(buf, line, &zero,atoi((hf->schema[i])+1)); zero = 0; printf("(key:%s rid:%lld) ",line, rid); } printf("\n"); } printf("overflow bucket:\n"); for (iter=0; iter <n_buckets; iter++){ read_bucket(bucket, iter, index_file->overflow_path); int offset = ((int*)bucket)[0]; long long pointer = ((long long*)(bucket+4))[0]; printf("offset=%d, pointer=%lld\n",offset,pointer); printf("key-rid pairs:\n"); int original_usage = ((int*)bucket)[0]; for (j = 12; j < original_usage; j += atoi((hf->schema[i])+1)+sizeof(long long)){ RID rid = (*read_keypair[hf->schema_array[i]])(bucket, buf, j, atoi((hf->schema[i])+1)); (*decode[hf->schema_array[i]])(buf, line, &zero,atoi((hf->schema[i])+1)); zero = 0; printf("(key:%s rid:%lld) ",line, rid); } printf("\n"); } free(bucket); free(buf); free(line); }
void rehash_keys(HFILE *hf, int i, INDEX_FILE *index_file){ void *original_bucket; void *old_bucket; void *new_bucket; void *buf; int original_offset=12; int original_usage; int old_bucket_write_position = -1; int new_bucket_write_position = -1; int free_start_point; original_bucket = calloc(BSIZE,sizeof(char)); if (original_bucket==NULL){ printf("Malloc failed"); exit(1); } old_bucket = calloc(BSIZE,sizeof(char)); if (old_bucket==NULL){ printf("Malloc failed"); exit(1); } new_bucket = calloc(BSIZE,sizeof(char)); if (new_bucket==NULL){ printf("Malloc failed"); exit(1); } buf = calloc(105,sizeof(char)); if (buf==NULL){ printf("Malloc failed"); exit(1); } read_bucket(original_bucket, index_file->next, index_file->main_path); original_usage = ((int*)original_bucket)[0]; read_bucket(old_bucket, index_file->next, index_file->main_path); ((int*)old_bucket)[0]=12; read_bucket(new_bucket, index_file->n, index_file->main_path); for (original_offset = 12; original_offset < original_usage; original_offset += atoi((hf->schema[i])+1)+sizeof(long long)){ RID rid = (*read_keypair[hf->schema_array[i]])(original_bucket, buf, original_offset, atoi((hf->schema[i])+1)); long long new_index = (*calculate_index[hf->schema_array[i]])(buf,index_file->s,index_file->n+1, 0); if (new_index==index_file->next){//old if (((int*)old_bucket)[0] >= BSIZE-sizeof(long long)-atoi((index_file->type)+1)){//full, allocate new if (old_bucket_write_position == -1){ write_bucket(old_bucket, index_file->next, index_file->main_path); } else { write_bucket(old_bucket, old_bucket_write_position, index_file->overflow_path); } old_bucket_write_position = ((long long*)(old_bucket+4))[0]; read_bucket(old_bucket, old_bucket_write_position, index_file->overflow_path); ((int*)old_bucket)[0]=12; } (*update_bucket[hf->schema_array[i]])(old_bucket,buf,rid,atoi((hf->schema[i])+1)+sizeof(long long),0); } else { //new if (((int*)new_bucket)[0] >= BSIZE-sizeof(long long)-atoi((index_file->type)+1)){//full, allocate new if (new_bucket_write_position == -1){ write_bucket(new_bucket, index_file->n, index_file->main_path); new_bucket_write_position = create_overflow_bucket(index_file); mylink(index_file->n, 0, new_bucket_write_position, index_file); } else { RID tmp = new_bucket_write_position; write_bucket(new_bucket, new_bucket_write_position, index_file->overflow_path); new_bucket_write_position = create_overflow_bucket(index_file); mylink(tmp, 1, new_bucket_write_position, index_file); } read_bucket(new_bucket, new_bucket_write_position, index_file->overflow_path); } (*update_bucket[hf->schema_array[i]])(new_bucket,buf,rid,atoi((hf->schema[i])+1)+sizeof(long long),0); } } while (((long long*)(original_bucket+4))[0]!=-1){ read_bucket(original_bucket, ((long long*)(original_bucket+4))[0], index_file->overflow_path); original_usage = ((int*)original_bucket)[0]; for (original_offset = 12; original_offset < original_usage; original_offset += atoi((hf->schema[i])+1)+sizeof(long long)){ RID rid = (*read_keypair[hf->schema_array[i]])(original_bucket, buf, original_offset, atoi((hf->schema[i])+1)); long long new_index = (*calculate_index[hf->schema_array[i]])(buf,index_file->s,index_file->n+1, 0); if (new_index==index_file->next){//old if (((int*)old_bucket)[0] >= BSIZE-sizeof(long long)-atoi((index_file->type)+1)){//full, allocate new if (old_bucket_write_position == -1){ write_bucket(old_bucket, index_file->next, index_file->main_path); } else { write_bucket(old_bucket, old_bucket_write_position, index_file->overflow_path); } old_bucket_write_position = ((long long*)(old_bucket+4))[0]; read_bucket(old_bucket, old_bucket_write_position, index_file->overflow_path); ((int*)old_bucket)[0]=12; } (*update_bucket[hf->schema_array[i]])(old_bucket,buf,rid,atoi((hf->schema[i])+1)+sizeof(long long),0); } else { //new if (((int*)new_bucket)[0] >= BSIZE-sizeof(long long)-atoi((index_file->type)+1)){//full, allocate new if (new_bucket_write_position == -1){ write_bucket(new_bucket, index_file->n, index_file->main_path); new_bucket_write_position = create_overflow_bucket(index_file); mylink(index_file->n, 0, new_bucket_write_position, index_file); } else { RID tmp = new_bucket_write_position; write_bucket(new_bucket, new_bucket_write_position, index_file->overflow_path); new_bucket_write_position = create_overflow_bucket(index_file); mylink(tmp, 1, new_bucket_write_position, index_file); } read_bucket(new_bucket, new_bucket_write_position, index_file->overflow_path); } (*update_bucket[hf->schema_array[i]])(new_bucket,buf,rid,atoi((hf->schema[i])+1)+sizeof(long long),0); } } } free_start_point = ((long long*)(old_bucket+4))[0]; if (free_start_point != -1){ int original_free_tail = find_free_list_tail(index_file); if (original_free_tail != -1) { mylink(original_free_tail, 1, free_start_point, index_file); } else { add_to_free_list(free_start_point, index_file); } } ((long long*)(old_bucket+4))[0] = -1; if (old_bucket_write_position == -1){ write_bucket(old_bucket, index_file->next, index_file->main_path); } else { write_bucket(old_bucket, old_bucket_write_position, index_file->overflow_path); } if (new_bucket_write_position == -1){ write_bucket(new_bucket, index_file->n, index_file->main_path); } else { write_bucket(new_bucket, new_bucket_write_position, index_file->overflow_path); } free(original_bucket); free(old_bucket); free(new_bucket); free(buf); }
/* get the next entry of a scan returns the RID of the next record that meets all the conditions returns (rid_t) -1 in case we are out of records */ RID hf_scan_next(CURSOR *cur, void *record){ if (cur->index == -1){ long long schema_space = 2*cur->hf->n_fields; long long record_space = (cur->hf->n_records) * hf_record_length(cur->hf); long long file_size = sizeof(long long) + sizeof(int) + schema_space + record_space; if (cur->current >= file_size) return -1; hf_record(cur->hf, cur->current, record); cur->current += hf_record_length(cur->hf); // if the current record doesn't meet all the conditions, fetch and check the next while (filter(record, cur->con, cur->conditions, cur->hf) == 0){ if (cur->current >= file_size) return -1; hf_record(cur->hf, cur->current, record); cur->current += hf_record_length(cur->hf); } return cur->current - hf_record_length(cur->hf); } else { INDEX_FILE *index_file; index_file = open_index(cur->con[cur->index].field-1, cur->hf); void *buf2 = calloc(105,sizeof(char)); int zero = 0; if (buf2==NULL){ printf("Malloc failed"); exit(1); } if (cur->index_current_bucket == -1){ (*encode[cur->hf->schema_array[cur->con[cur->index].field-1]])(buf2, (char*)cur->con[cur->index].value, &zero,atoi((cur->hf->schema[cur->con[cur->index].field-1])+1)); zero = 0; cur->index_current_bucket = (*calculate_index[cur->hf->schema_array[cur->con[cur->index].field-1]])(buf2,index_file->s,index_file->n,0); } int i = cur->con[cur->index].field-1; int original_offset; int original_usage; void *original_bucket = calloc(BSIZE,sizeof(char)); //void *bucket; //bucket = calloc(BSIZE,sizeof(char)); if (original_bucket==NULL){ printf("Malloc failed"); exit(1); } void *buf = calloc(105,sizeof(char)); if (buf==NULL){ printf("Malloc failed"); exit(1); } if (cur->index_mo == 0){ read_bucket(original_bucket, cur->index_current_bucket, index_file->main_path); } else { read_bucket(original_bucket, cur->index_current_bucket, index_file->overflow_path); } original_usage = ((int*)original_bucket)[0]; for (original_offset = cur->index_bucket_offset; original_offset < original_usage; original_offset += atoi((cur->hf->schema[i])+1)+sizeof(long long)){ RID rid = (*read_keypair[cur->hf->schema_array[i]])(original_bucket, buf, original_offset, atoi((cur->hf->schema[i])+1)); hf_record(cur->hf, rid, record); if (filter(record, cur->con, cur->conditions, cur->hf) == 1){ cur->index_bucket_offset = original_offset + atoi((cur->hf->schema[i])+1)+sizeof(long long); free(original_bucket); free(buf); return rid; } } while (((long long*)(original_bucket+4))[0]!=-1){ int current_bucket = ((long long*)(original_bucket+4))[0]; read_bucket(original_bucket, ((long long*)(original_bucket+4))[0], index_file->overflow_path); original_usage = ((int*)original_bucket)[0]; for (original_offset = 12; original_offset < original_usage; original_offset += atoi((cur->hf->schema[i])+1)+sizeof(long long)){ RID rid = (*read_keypair[cur->hf->schema_array[i]])(original_bucket, buf, original_offset, atoi((cur->hf->schema[i])+1)); hf_record(cur->hf, rid, record); if (filter(record, cur->con, cur->conditions, cur->hf) == 1){ cur->index_bucket_offset = original_offset + atoi((cur->hf->schema[i])+1)+sizeof(long long); cur->index_current_bucket = current_bucket; cur->index_mo = 1; free(original_bucket); free(buf); return rid; } } } free(original_bucket); free(buf); free(buf2); return -1; } }