Advertisement
Guest User

Untitled

a guest
Apr 27th, 2017
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.85 KB | None | 0 0
  1.  
  2. #include "vault_utils.h"
  3. #include "priority_queue.h"
  4. #include "includes.h"
  5.  
  6. /*create - fails if:
  7. -requasted file size isnt big enough
  8. //TODO - check what they mean
  9. //TODO - check if i need another for just to initilize
  10. */
  11. vault* create_vault(char* vault_name, ssize_t size){//???
  12.     vault* v=(vault*)malloc(sizeof(vault));
  13.     if(v==NULL){
  14.         //TODO - check malloc
  15.     }
  16.     v->vault_size = size;
  17.     v->biggest_pq.type=MAX;
  18.     v->biggest_pq.seg_num=0;
  19.     v->closest_pq.type=MIN;
  20.     v->closest_pq.seg_num=0;
  21.     v->free_space=size;
  22.     v->empty_seg_num=1;
  23.     v->seg_arr[0].offset=sizeof(vault)+1;
  24.     v->seg_arr[0].size=size;
  25.     v->seg_arr[0].pos=0;
  26.     q_insert(&v->biggest_pq,&v->seg_arr[0]);
  27.     v->creation_time = time(NULL);//???TODO
  28.     int fd = open(vault_name,O_RDWR|O_CREAT,0755);
  29.     if(fd<0){
  30.         //TODO - print error
  31.     }
  32.     v->fd=fd;
  33.     return v;
  34.     }
  35.  
  36.  
  37. void print_fat(vault* v){
  38.     for(int i =0;i<v->number_of_files;i++){
  39.                 print_file(&v->fat[i]);
  40.         }
  41. }
  42.  
  43.  
  44. vault* read_vault(char* vault_name){
  45.     vault* v=(vault*)malloc(sizeof(vault));
  46.     int fd = open(vault_name,O_RDWR,0777);
  47.     if(fd<0||read(fd,v,sizeof(vault))<0){
  48.         free(v);
  49.         //TODO -print msg
  50.         return NULL;   
  51.     }
  52.     //initilise closest pq
  53.     //list_vault(v);
  54.     for(int i=0;i<v->number_of_files;i++){
  55.         for(int j=0;j<(v->fat)[i].seg_num;j++){
  56.             v->closest_pq.arr[(v->fat)[i].seg_arr[j].pos]=
  57.                     &(v->fat)[i].seg_arr[j];
  58.         }
  59.     }
  60.     //initilise biggest pq
  61.     for(int i=0;i<v->empty_seg_num;i++){
  62.             v->biggest_pq.arr[v->seg_arr[i].pos]=
  63.                     &v->seg_arr[i];
  64.     }
  65.  
  66.     v->fd=fd;
  67.     return v;
  68. }
  69.  
  70.  
  71.  
  72.  
  73. void write_vault(vault* v){
  74.     if(lseek(v->fd,0,SEEK_SET)<0){
  75.         //TODO -fix seek
  76.     }
  77.     int just_written = write(v->fd,v,sizeof(vault));
  78.     if(just_written<0){
  79.         //TODO -handle
  80.     }
  81.     return;
  82. }
  83.  
  84. void list_vault(vault* v){
  85.     file_record tmp;
  86.     for(int i=0;i< v->number_of_files;i++){
  87.         tmp=v->fat[i];
  88.         printf("%s \t %zu \t %d \t %zu \n",tmp.file_name,
  89.             tmp.file_size,
  90.             tmp.perm,
  91.             tmp.insertion_time);//TODO - check how to print time_t and st_mode
  92.     }
  93.     print_fat(v);
  94. }
  95.  
  96. void print_vault_status(vault* v){//sum the spaces in the queue.
  97.     //we find the last segement in the seg_num/2 last elements and
  98.     // reduce the current capcicity from the sum of segements->
  99.     queue* pq=&(v->closest_pq);
  100.     ssize_t sum=v->first_gap;
  101.     off_t last=0;
  102.     for(int i=0;i<pq->seg_num/2-1;i++){
  103.         sum+=pq->arr[i]->size;
  104.     }
  105.     for(int i=pq->seg_num/2;i<pq->seg_num;i++){
  106.         sum+=pq->arr[i]->size;
  107.         last=MAX(pq->arr[i]->offset,last);
  108.     }
  109. }
  110.  
  111. /*add - fails if:
  112. -file name exists already
  113. -no free space available
  114. -has free space but content has to be fragmented into more then 3 blocks
  115. */
  116. //remember to cleanup if this fails
  117. int add_to_vault(vault* v,char* file_name){
  118.     if(linear_search(v,file_name)<0){
  119.         //TODO -print error
  120.     }
  121.     int file_fd = open(file_name,O_RDWR);
  122.     if(file_fd<0){
  123.         printf("ERROR: opening input file : %s\n",strerror(errno));
  124.         return errno;  
  125.     }
  126.  
  127.     struct stat statbuf;
  128.     if(fstat(file_fd,&statbuf)<0){
  129.         close(file_fd);
  130.         printf("ERROR: getting stat of input file : %s\n",strerror(errno));
  131.         return errno;
  132.     }
  133.  
  134.     ssize_t file_s = statbuf.st_size;
  135.     v->fat[v->number_of_files].perm=statbuf.st_mode;
  136.     //notice we have in file_name the full path and only have to keep the last part
  137.     //TODO - check if file exists
  138.     queue* pq=&(v->biggest_pq);
  139.     if(file_s>v->free_space){
  140.         //TODO -return error - not enough free space
  141.     }
  142.     ssize_t sum=0;
  143.     int file_seg_num=0;
  144.     while(file_seg_num<MIN(3,pq->seg_num)&&file_s>sum){
  145.         sum+=pq->arr[file_seg_num++]->size;
  146.     }
  147.     q_print_pq(pq);
  148.     if(file_s>sum){
  149.         printf("Error: file need to be fragmented more then 3 blocks\n");
  150.         exit(1);
  151.     }
  152.    
  153.     v->fat[v->number_of_files].seg_arr;
  154.     v->fat[v->number_of_files].file_size=file_s;
  155.     strcpy(v->fat[v->number_of_files].file_name,file_name);
  156.  
  157.     v->fat[v->number_of_files].insertion_time=time(NULL);
  158.    
  159.     ssize_t write_amount;
  160.     ssize_t left_to_write=file_s;
  161.     int j=0;
  162.     segment* tmp;
  163.     for(;j<file_seg_num;j++){
  164.         write_amount=MIN(pq->arr[j]->size,left_to_write);
  165.         tmp = write_seg(v,file_fd,(pq->arr[j]),write_amount);
  166.         v->fat[v->number_of_files].seg_arr[j]=*tmp;
  167.         free(tmp);
  168.         left_to_write-=write_amount;
  169.     }
  170.     v->fat[v->number_of_files].seg_num=file_seg_num;
  171.     v->number_of_files++;
  172.    
  173.  
  174. }
  175.  
  176.  
  177. /*rm fails if:
  178. -no such file exists
  179. */
  180. void remove_from_vault(vault* v,char* file_name){
  181.     //we need to merge gaps
  182.     //once we found we go through and remove the segments from the queue
  183.     //also we need to decrease the key of some of the elements in the queue
  184.     //also to check if we need to update first_gap
  185.     int file_index=linear_search(v,file_name);
  186.     if(file_index<0){
  187.         //TODO - print error
  188.     }
  189.     printf("%s,%d\n",file_name,file_index);
  190.     file_record* file = v->fat+file_index;
  191.     printf("%d\n", file_index);
  192.     for(int i=0;i< file->seg_num;i++){
  193.         printf("deleting:\n");
  194.         print_file(file);//DEBUG print
  195.         delete_seg(v,file->seg_arr+i);
  196.         q_delete(&(v->closest_pq),file->seg_arr[i].pos);
  197. /*      while(){//go over the empty segments
  198.             if(need_to_merge){
  199.                 merge_empty_seg(v,NULL,file.seg_arr[i]);//TODO
  200.             }
  201.         }*/
  202.     }
  203.  
  204.    
  205.     file_record* fat = v->fat;
  206.     for(int i=file_index;i<v->number_of_files-1;i++){
  207.         fat[i]=fat[i+1];
  208.     }
  209.     v->number_of_files--;
  210. }
  211.  
  212.  
  213. /*fetch fails if:
  214. -no such file exists
  215. -we dont have write permision for the current directory
  216. */
  217. int fetch_from_vault(vault* v,char* file_name){
  218.     //use fstat on v to get dir and then check if we belong in the write group
  219.     //ask ariel for help
  220.     int file_index;
  221.     if(file_index=linear_search(v,file_name)<0){
  222.         printf("Error: file not found");
  223.         return 1;
  224.         }
  225.     int file_fd = open(file_name,O_WRONLY | O_CREAT | O_TRUNC, 0775);
  226.     if(file_fd<0){
  227.         printf("Error opening vault file: %s\n", strerror(errno));
  228.         return errno;
  229.     }
  230.     file_record file = (v->fat[file_index]);
  231.     segment file_seg;
  232.     file_seg.offset=0;
  233.     for(int i=0;i<file.seg_num;i++){
  234.         file_seg.size=file.seg_arr[i].size;
  235.         segment* tmp_seg = &(file.seg_arr[i]);
  236.         copy_seg(v->fd,file_fd,tmp_seg,&file_seg);
  237.         file_seg.offset+=file.seg_arr[i].size;
  238.     }
  239.     return 0;
  240. }
  241.  
  242.  
  243. void defrag_vault(vault* v){//use heapsort thing on queue and move every block to the left
  244.     queue* pq=&(v->closest_pq);
  245.     segment* tmp_seg;
  246.     while(!is_empty(pq)){
  247.         tmp_seg=q_extract(pq);
  248.         //we update first_gap because when we move
  249.         //the segment to the left we set his new offset as first_gap
  250.         move_to_left(v,tmp_seg);
  251.     }
  252.     //TODO - we need to restart biggest_pq and closest_pq
  253. }
  254.  
  255.  
  256.  
  257.  
  258. //copy the read_seg from input_fd to the out_seg in the output_fd -- NO DELIMITER
  259. int copy_seg(int read_fd, int write_fd, segment* read_seg, segment* write_seg){
  260.     ssize_t bytes_left = read_seg->size;
  261.     ssize_t amount;
  262.     int just_written;
  263.     char* buff=(char*)malloc(BUFF_SIZE);//TODO
  264.     if(buff==NULL){
  265.         printf("Error allocating memory: %s\n", strerror(errno));
  266.         return errno;
  267.     }
  268.     if(lseek(read_fd, read_seg->offset,SEEK_SET)<0){
  269.         printf("Error using lseek: %s\n", strerror(errno));
  270.         return errno;
  271.     }
  272.     if(lseek(write_fd, write_seg->offset,SEEK_SET)<0){
  273.             printf("Error using lseek: %s\n", strerror(errno));
  274.             return errno;
  275.             }
  276.     while(bytes_left>0){
  277.         amount=MIN(bytes_left,BUFF_SIZE);
  278.         if(read(read_fd,buff,amount)<0){
  279.             printf("Error reading from file: %s\n", strerror(errno));
  280.             return errno;
  281.         }
  282.         just_written = write(write_fd,buff,amount);
  283.         if(just_written<0){
  284.             printf("Error writing into file: %s\n", strerror(errno));
  285.             return errno;
  286.         }
  287.         bytes_left-=just_written;
  288.     }
  289.     free(buff);
  290.     return 0;
  291. }
  292.  
  293.  
  294.  
  295. void move_to_left(vault* v,segment* seg){
  296.     segment s;
  297.     s.offset = v->first_gap;
  298.     s.size = (seg->offset)-(v->first_gap);
  299.     write_seg(v,v->fd,&s,seg->size);
  300.     delete_seg(v,seg);
  301.     //tehn write_to_vault on appropriate segment
  302. }
  303.  
  304.  
  305. void print_seg(segment* s){
  306.     printf("size: %zu offset: %zu pos: %d\n",s->size,s->offset,s->pos);
  307. }
  308.  
  309. void print_file(file_record* f){
  310.     printf("%s\n",f->file_name);
  311.     for(int i=0;i<f->seg_num;i++){
  312.         print_seg(&f->seg_arr[i]);
  313.     }
  314. }
  315.  
  316. //can be linear
  317. void merge_empty_seg(vault* v,segment* pq_seg,segment* removed_seg){
  318.  
  319.  
  320. }
  321.  
  322. //writes a segment of size amount to the vault from the current position of input_fd
  323. //MUST ACCOUNT FOR OVERLAP - when used by move_to_left
  324. segment* write_seg(vault* v,int input_fd ,segment* empty_seg,ssize_t amount){
  325.     queue* c_pq=&(v->closest_pq);
  326.     queue* b_pq=&(v->biggest_pq);
  327.     segment* s=(segment*)malloc(sizeof(segment));
  328.     if(s->offset=lseek(input_fd, 0,SEEK_CUR)<0){
  329.         //TODO - print error
  330.     }
  331.     s->size=amount;
  332.     copy_seg(input_fd,v->fd,s,empty_seg);
  333.     s->offset = empty_seg->offset;
  334.     empty_seg->offset += amount;
  335.     if(amount==empty_seg->size){
  336.         q_delete(b_pq,empty_seg->pos);
  337.     }
  338.     else{
  339.         q_update(b_pq,empty_seg->pos,empty_seg->size-amount);
  340.     }
  341.     s->pos = q_insert(c_pq,s);
  342.     v->free_space -= amount;
  343.     return s;
  344. }
  345.  
  346. //deletes a segment from the vault
  347. //needs to be O(lgn)
  348. void delete_seg(vault* v,segment* seg){
  349.     //may be inefficent with some extra reads
  350.     int zero_fd = open("/dev/zero",O_RDWR,0755);
  351.     copy_seg(zero_fd,v->fd,seg,seg);
  352.     q_insert(&(v->biggest_pq),seg);
  353.     v->free_space += seg->size;
  354.     v->first_gap=MIN(seg->offset,v->first_gap);//TODO -write MIN
  355.     close(zero_fd);
  356. }
  357.  
  358. int linear_search(vault* v,char* key){
  359.     file_record* fat = v->fat;
  360.     for(int i=0;i<v->number_of_files;i++){
  361.         if(strcmp(key,fat[i].file_name)==0){
  362.             printf("index: %d\n",i );
  363.             return i;
  364.  
  365.         }
  366.     }
  367.     return -1;
  368. }
  369.  
  370.  
  371. ssize_t pharse(char* str){
  372.     int data_offset=0;
  373.     int arlen = strlen(str)-1;
  374.     char data_prefix = str[arlen];
  375.     str[arlen] = '\0';
  376.     ssize_t data_amount = atoi(str);
  377.     switch(toupper(data_prefix)){
  378.     case 'B':
  379.         break;
  380.     case 'K':
  381.         data_offset=10;
  382.         break; 
  383.     case 'M':
  384.         data_offset=20;
  385.         break;
  386.     case 'G':
  387.         data_offset=30;
  388.         break;
  389.     default:
  390.         printf("ERROR: wrong usage of arguments\n");//TODO-print diffrent error
  391.         return 1;
  392.     }
  393.     return data_amount<<data_offset;
  394. }
  395.  
  396. char* lowercase(char* str){
  397.     for (int i = 0; i < strlen(str); ++i) {
  398.         str[i] = tolower(str[i]);
  399.     }
  400.     return str;
  401. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement