int join(int r, int s) { int addr_r = r, addr_s = s; int ret = BLKNUM; unsigned char * blkr, *blks; while(addr_r != 0) { blkr = readBlockFromDisk(addr_r, &buf); for(int ii = 0; ii < 7; ii++) { int a = *(blkr+ii*8+0); addr_s = s; while(addr_s != 0) { blks = readBlockFromDisk(addr_s, &buf); blk = getNewBlockInBuffer(&buf); for(int jj = 0; jj < 7; jj++) { int c = *(blks+jj*8+0); *(blk+jj*8+0) = a; *(blk+jj*8+4) = c; } addr_s = *(blks+BLKSIZE-4); //printf(" addr = %d\n", addr_s); *(blk+BLKSIZE-4) = BLKNUM+1; writeBlockToDisk(blk,BLKNUM,&buf); BLKNUM++; freeBlockInBuffer(blks, &buf); } } addr_r = *(blkr+BLKSIZE-4); freeBlockInBuffer(blkr,&buf); } blk = readBlockFromDisk(BLKNUM-1, &buf); *(blk+BLKSIZE-4) = 0; writeBlockToDisk(blk, BLKNUM-1,&buf); return ret; }
int binaryselect(int addr, int val) { int barray[16]; Buffer buf; unsigned int *blkr = NULL, *blkw = NULL; int j = 0, i = 0; int waddr = 1300; //先把磁盘上之前的select结果块们删掉 for (i = 0; i < 48; i++) { if (dropBlockOnDisk(waddr + i * 100) == -1) break; } if (!initBuffer(520, 64, &buf)) { perror("Buffer Initialization Failed!\n"); return -1; } //---------------------------------------------- blkw = (unsigned int *)getNewBlockInBuffer(&buf);//要一块缓冲区块,用来暂存要写回磁盘的块 for (i = 0; i < 16; i++) barray[i] = 0; i = 0; while (addr != 0)//读下一个块 { if ((blkr = (unsigned int *)readBlockFromDisk(addr, &buf)) == NULL) { perror("Reading Block Failed!\n"); return -1; } barray[i * 2] = *(blkr); barray[i * 2 + 1] = *(blkr + 12); addr = *(blkr + 15); i++; } addr = 8000+(binarysort(barray,val)/2); if ((blkr = (unsigned int *)readBlockFromDisk(addr, &buf)) == NULL) { perror("Reading Block Failed!\n"); return -1; } int flag = 0; for (i = 0; i < 8; i++) { if (*(blkr + i * 2) == val) { flag = 1; break; } } if (flag = 1) { *blkw = *(blkr + i * 2); *(blkw + 1) = *(blkr + i * 2 + 1); writeBlockToDisk((unsigned char *)blkw, waddr, &buf); return waddr; } else return 0; }
int findfirst(int start, int value) { int ans = BLKNUM; int addr = start; unsigned char *tarblk; tarblk = getNewBlockInBuffer(&buf); int i = 0; while(addr != 0) { blk = readBlockFromDisk(addr, &buf); for(int j = 0; j < group_in_blk; j++) { int a = *(blk+j*8+0); int b = *(blk+j*8+4); if(value == a) { *(tarblk+i*8+0)=a; *(tarblk+i*8+4)=b; i++; if(i >= 7) { *(tarblk+BLKSIZE-4) = BLKNUM+1; writeBlockToDisk(tarblk, BLKNUM, &buf); tarblk = getNewBlockInBuffer(&buf); BLKNUM++; i = 0; } } } addr = *(blk+BLKSIZE-4); freeBlockInBuffer(blk, &buf); } if(i != 0) { for(; i<=7; i++) { *(tarblk+i*8+0)=0; *(tarblk+i*8+4)=0; } writeBlockToDisk(tarblk, BLKNUM, &buf); BLKNUM++; } else { blk = readBlockFromDisk(BLKNUM-1, &buf); *(blk+BLKSIZE-4) = 0; writeBlockToDisk(blk, BLKNUM, &buf); } return ans; }
int projection(int start) { int ans = BLKNUM; int i = 0; unsigned char *blks[6]; for(int k = 0; k < 6; k++) { blks[k] = getNewBlockInBuffer(&buf);; for(int j = 0; j < 64; j++) *(blks[k]+j) = 0; } int addr = start; while(addr != 0) { blk = readBlockFromDisk(addr, &buf); for(int j = 0; j < group_in_blk; j++) { int a = *(blk+j*8+0); bool flag = false; for(int k = 0; k < 6; k++) { if(issaved(a, blks[k])) flag = true; } if(!flag) { int ii = i%7; int jj = i/7; *(blks[jj]+ii*8+0) = a; i++; } } addr = *(blk+BLKSIZE-4); freeBlockInBuffer(blk, &buf); } int jj = i/7; for(int k = 0; k <= jj; k++) { if(k == jj) *(blks[k]+BLKSIZE-4) = 0; else *(blks[k]+BLKSIZE-4) = BLKNUM+1; writeBlockToDisk(blks[k],BLKNUM,&buf); BLKNUM++; } for(int k = jj+1; k < 6; k++) { freeBlockInBuffer(blks[k], &buf); } return ans; }
int initGroup(int group_count, int a_min, int a_max, int b_min, int b_max) { //blk = getNewBlockInBuffer(&buf); int startnum = BLKNUM; for(int i = 0; i < group_count / group_in_blk; i++) { blk = getNewBlockInBuffer(&buf); for(int j = 0; j < group_in_blk; j++) { unsigned int a = getRandom(a_min, a_max); unsigned int b = getRandom(b_min, b_max); *(blk+j*8+0) = a; *(blk+j*8+4) = b; } if(i == (group_count / group_in_blk - 1)) *(blk+BLKSIZE-4) = (unsigned int)0; else *(blk+BLKSIZE-4) = (unsigned int)(BLKNUM+1); //printf("addr == %d\n", *(blk+BLKSIZE-4)); writeBlockToDisk(blk, BLKNUM, &buf); BLKNUM++; } return startnum; }
int linearselect(int addr, int val) { Buffer buf; unsigned int *blkr = NULL, *blkw = NULL; int j = 0, i = 0; int waddr = 1200; FILE *fo; //先把磁盘上之前的select结果块们删掉 for (i = 0; i < 48; i++) { if (dropBlockOnDisk(waddr + i * 100) == -1) break; } if ((fo = fopen("OUTwhenSelect.txt", "wb")) == NULL) { printf("打不开文件whenSelect.txt\n"); return 0; } if (!initBuffer(520, 64, &buf)) { perror("Buffer Initialization Failed!\n"); return -1; } //---------------------------------------------- if ((blkr = (unsigned int *)readBlockFromDisk(addr, &buf)) == NULL) { perror("Reading Block Failed!\n"); return -1; } blkw = (unsigned int *)getNewBlockInBuffer(&buf);//要一块缓冲区块,用来暂存要写回磁盘的块 while (addr != 0)//读下一个块 { fprintf(fo, "现在是第%d块\n", addr); for (i = 0; i < 7; i++)//遍历块中的元组 {//处理读取块中的单个元组 fprintf(fo, "A %d, B %d\n", *(blkr + 2 * i), *(blkr + 2 * i + 1)); if (*(blkr + 2 * i) == val) { //把当前的查询到的复制到申请的缓存块中 *(blkw + j) = *(blkr + 2 * i); *(blkw + j + 1) = *(blkr + 2 * i + 1); j = (j + 2) % 16; fprintf(fo, "^\n"); if (j == 0) { *(blkw + 15) = waddr; waddr += 100; writeBlockToDisk((unsigned char *)blkw, waddr, &buf); //freeBlockInBuffer((unsigned char *)blkw,&buf); //blkw = (unsigned int *)getNewBlockInBuffer(&buf);//要一块缓冲区块,用来暂存要写回磁盘的块 } } } addr = *(blkr + 15); freeBlockInBuffer((unsigned char *)blkr, &buf); printf("SELECT next: %d\n", addr); if (addr != 0) { if ((blkr = (unsigned int *)readBlockFromDisk(addr, &buf)) == NULL) { perror("Reading Block Failed!\n"); return -1; } } } //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //最后判断一下是否有往磁盘上写过块,若没有,则写一次。因为如果未写过,说明选择到的记录不到7条(不满一个blk) if (j != 0) { writeBlockToDisk((unsigned char *)blkw, waddr, &buf); } fclose(fo); freeBuffer(&buf); return waddr; }
int main() { struct A array_a[N_a]; struct B array_b[N_b]; struct A a; struct B b; Buffer buf; /* A buffer */ unsigned char *blk; /* A pointer to a block */ int * iblk;/*A input blk*/ int iblk_count;/*Record the position of the last data in the iblk*/ int * iblk2;/*A input blk*/ int iblk2_count;/*Record the position of the last data in the iblk2*/ int * oblk;/*A output blk*/ int oblk_count;/*Record the position of the last data input in the oblk*/ int i = 0; int j=0; int seq_a=1;/*The start sequance number of the relation R*/ int seq_b=101;/*The start sequance number of the realtion S*/ int seq_1=201;/*The start sequance number of the 1st operation*/ int seq_2=301;/*The start sequance number of the 2nd operation*/ int seq_3=401;/*The start sequance number of the 3nd operation*/ srand((int)time(0)); //Generate A and B for (i=0;i<N_a;i++) { array_a[i].A=i % 40+1; array_a[i].B=i%1000+1; } for (i=0;i<N_b;i++) { array_b[i].C=i%41+20; array_b[i].D=i%1000+1; } array_b[N_b-1].C=60; //Write data into disk /* Initialize the buffer */ if (!initBuffer(520, 64, &buf)) { perror("Buffer Initialization Failed!\n"); return -1; } /* Fill data into the block And write the block into disk */ /*Relation R*/ j=0; while(j<N_a) { /* Get a new block in the buffer */ blk = getNewBlockInBuffer(&buf); iblk=(int *)blk; for (i = 0; i < NumOFBlk-2; i=i+2) { *(iblk + i) = array_a[j].A; *(iblk+i+1)=array_a[j].B; j=j+1; //处理块未存满的情况 if (j>=N_a&&i-1<NumOFBlk-2) { *(iblk+NumOFBlk-1)=0; } } if (j==N_a) { *(iblk+NumOFBlk-1)=0; } else { *(iblk+i+1)=seq_a+1; } /* Write the block to the hard disk */ if (writeBlockToDisk(blk, seq_a, &buf) != 0) { perror("Writing Block Failed!\n"); return -1; } seq_a++; } /*Relation S*/ j=0; while(j<N_b) { /* Get a new block in the buffer */ blk = getNewBlockInBuffer(&buf); iblk=(int *)blk; for (i = 0; i < NumOFBlk-2; i=i+2) { *(iblk + i) = array_b[j].C; *(iblk+i+1)=array_b[j].D; j=j+1; //处理块未存满的情况 if (j>=N_b&&i-1<NumOFBlk-2) { *(iblk+NumOFBlk-1)=0; } } if (j==N_b) { *(iblk+NumOFBlk-1)=0; } else { *(iblk+i+1)=seq_b+1; } /* Write the block to the hard disk */ if (writeBlockToDisk(blk, seq_b, &buf) != 0) { perror("Writing Block Failed!\n"); return -1; } seq_b++; } //output the data to test the process is correct printf("***********Input Data***************\n"); for (i=0;i<N_a;i++) { printf("%d:%d %d\n",i,array_a[i].A,array_a[i].B); } for (i=0;i<N_b;i++) { printf("%d:%d %d\n",i,array_b[i].C,array_b[i].D); } //read from the disk and to print seq_a=1; seq_b=101; //Read relation R from disk j=0; while(seq_a!=0) { if ((blk = readBlockFromDisk(seq_a, &buf)) == NULL) { perror("Reading Block Failed!\n"); return -1; } iblk=(int *)blk; for (i=0;i<NumOFBlk-2;i=i+2) { a.A=*(iblk+i); a.B=*(iblk+i+1); printf("%d: %d %d\n",j,a.A,a.B); j++; } seq_a=*(iblk+NumOFBlk-1); freeBlockInBuffer(blk,&buf); } //Read relation S from disk j=0; while(seq_b!=0) { if ((blk = readBlockFromDisk(seq_b, &buf)) == NULL) { perror("Reading Block Failed!\n"); return -1; } iblk=(int *)blk; for (i=0;i<NumOFBlk-2;i=i+2) { b.C=*(iblk+i); b.D=*(iblk+i+1); printf("%d: %d %d\n",j,b.C,b.D); j++; } seq_b=*(iblk+NumOFBlk-1); freeBlockInBuffer(blk,&buf); } /* 1. select operation R.A=40 or S.C=60 */ oblk=(int *)getNewBlockInBuffer(&buf); oblk_count=0; seq_a=1; while(seq_a!=0) { if ((iblk=(int*)readBlockFromDisk(seq_a,&buf))==NULL) { perror("Reading Block Failed!\n"); return -1; } for (i=0;i<NumOFBlk-2;i=i+2) { a.A=*(iblk+i); a.B=*(iblk+i+1); /*Put the data in the oblk*/ if (a.A==40) { /*If the block is full then write into the disk*/ if (oblk_count==NumOFBlk-2) { *(oblk+NumOFBlk-2)=NumOFBlk-2; *(oblk+NumOFBlk-1)=seq_1+1; if (writeBlockToDisk((unsigned char*)oblk, seq_1, &buf) != 0) { perror("Writing Block Failed!\n"); return -1; } memset(oblk,0,16*sizeof(int)); oblk_count=0; seq_1++; } if (oblk_count<=NumOFBlk-2-num_int_A)//the rest room is enough { *(oblk+oblk_count)=a.A; oblk_count++; *(oblk+oblk_count)=a.B; oblk_count++; } } } seq_a=*(iblk+NumOFBlk-1); freeBlockInBuffer((unsigned char*)iblk,&buf); } seq_b=101; while(seq_b!=0) { if ((iblk=(int*)readBlockFromDisk(seq_b,&buf))==NULL) { perror("Reading Block Failed!\n"); return -1; } for (i=0;i<NumOFBlk-2;i=i+2) { b.C=*(iblk+i); b.D=*(iblk+i+1); /*Put the data in the oblk*/ if (b.C==60) { /*If the block is full then write into the disk*/ if (oblk_count==NumOFBlk-2) { *(oblk+NumOFBlk-2)=NumOFBlk-2; *(oblk+NumOFBlk-1)=seq_1+1; if (writeBlockToDisk((unsigned char*)oblk, seq_1, &buf) != 0) { perror("Writing Block Failed!\n"); return -1; } oblk=(int *)getNewBlockInBuffer(&buf); memset(oblk,0,16*sizeof(int)); oblk_count=0; seq_1++; } if (oblk_count<=NumOFBlk-2-num_int_B)//the rest room is enough { *(oblk+oblk_count)=b.C; oblk_count++; *(oblk+oblk_count)=b.D; oblk_count++; } } } seq_b=*(iblk+NumOFBlk-1); freeBlockInBuffer((unsigned char*)iblk,&buf); } /*Output the last block*/ *(oblk+NumOFBlk-2)=oblk_count; *(oblk+NumOFBlk-1)=0; if (writeBlockToDisk((unsigned char*)oblk, seq_1, &buf) != 0) { perror("Writing Block Failed!\n"); return -1; } oblk = (int*)getNewBlockInBuffer(&buf); memset(oblk,0,16*sizeof(int)); oblk_count=0; /* *Second Operation */ seq_a=1; oblk_count=0; while(seq_a!=0) { if ((iblk=(int*)readBlockFromDisk(seq_a,&buf))==NULL) { perror("Reading Block Failed!\n"); return -1; } for (i=0;i<NumOFBlk-2;i=i+2) { a.A=*(iblk+i); a.B=*(iblk+i+1); /*Put the data in the oblk*/ /*If the block is full then write into the disk*/ if (oblk_count==NumOFBlk-2) { *(oblk+NumOFBlk-2)=NumOFBlk-2; *(oblk+NumOFBlk-1)=seq_2+1; if (writeBlockToDisk((unsigned char*)oblk, seq_2, &buf) != 0) { perror("Writing Block Failed!\n"); return -1; } oblk = (int*)getNewBlockInBuffer(&buf); memset(oblk,0,16*sizeof(int)); oblk_count=0; seq_2++; } if (oblk_count<=NumOFBlk-2-1)//the rest room is enough { *(oblk+oblk_count)=a.A; oblk_count++; } } seq_a=*(iblk+NumOFBlk-1); freeBlockInBuffer((unsigned char*)iblk,&buf); } /*Output the last block*/ *(oblk+NumOFBlk-2)=oblk_count; *(oblk+NumOFBlk-1)=0; if (writeBlockToDisk((unsigned char*)oblk, seq_2, &buf) != 0) { perror("Writing Block Failed!\n"); return -1; } memset(oblk,0,16*sizeof(int)); oblk_count=0; /* 3rd Operation */ /*set the sequence number of the relation R and S*/ seq_a=1; seq_b=101; /*Apply for a new block for output block*/ oblk=(int*)getNewBlockInBuffer(&buf); oblk_count=0; while(seq_a!=0) { /*Read a block of the R*/ if ((iblk=(int*)readBlockFromDisk(seq_a,&buf))==NULL) { perror("Reading Block Failed!\n"); return -1; } for (i=0;i<NumOFBlk-2;i=i+2) { a.A=*(iblk+i); a.B=*(iblk+i+1); /*Compared with every in S*/ seq_b=101; while(seq_b!=0) { /*Read a block of the S*/ if ((iblk2=(int*)readBlockFromDisk(seq_b,&buf))==NULL) { perror("Reading Block Failed!\n"); return -1; } for (j=0;j<NumOFBlk-2;j=j+2) { b.C=*(iblk2+j); b.D=*(iblk2+j+1); if (a.A==b.C) { /*Deal with the full output block*/ if (oblk_count>NumOFBlk-2-num_int_B-num_int_A) { *(oblk+NumOFBlk-2)=oblk_count; *(oblk+NumOFBlk-1)=seq_3+1; if (writeBlockToDisk((unsigned char*)oblk, seq_3, &buf) != 0) { perror("Writing Block Failed!\n"); return -1; } seq_3++; /*Apply for a new output block*/ oblk=(int*)getNewBlockInBuffer(&buf); oblk_count=0; } *(oblk+oblk_count)=a.A; *(oblk+oblk_count+1)=a.B; *(oblk+oblk_count+2)=b.C; *(oblk+oblk_count+3)=b.D; oblk_count=oblk_count+4; } } seq_b=*(iblk2+NumOFBlk-1); freeBlockInBuffer((unsigned char*)iblk2,&buf); } } seq_a=*(iblk+NumOFBlk-1); freeBlockInBuffer((unsigned char*)iblk,&buf); } return 0; }