LCOV - code coverage report
Current view: top level - src/server/protocol2/champ_chooser - candidate.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 15 82 18.3 %
Date: 2016-01-31 Functions: 3 8 37.5 %

          Line data    Source code
       1             : #include "../../../burp.h"
       2             : #include "../../../alloc.h"
       3             : #include "../../../log.h"
       4             : #include "../../../sbuf.h"
       5             : #include "../../../protocol2/blk.h"
       6             : #include "candidate.h"
       7             : #include "incoming.h"
       8             : #include "scores.h"
       9             : #include "sparse.h"
      10             : 
      11             : #include <assert.h>
      12             : 
      13             : struct candidate **candidates=NULL;
      14             : size_t candidates_len=0;
      15             : 
      16           7 : struct candidate *candidate_alloc(void)
      17             : {
      18             :         return (struct candidate *)
      19           7 :                 calloc_w(1, sizeof(struct candidate), __func__);
      20             : }
      21             : 
      22           0 : void candidate_free_content(struct candidate *c)
      23             : {
      24           7 :         if(!c) return;
      25           7 :         free_w(&c->path);
      26             : }
      27             : 
      28           7 : void candidate_free(struct candidate **c)
      29             : {
      30          14 :         if(!c) return;
      31           7 :         candidate_free_content(*c);
      32           7 :         free_v((void **)c);
      33             : }
      34             : 
      35           0 : void candidates_set_score_pointers(struct candidate **candidates, size_t clen,
      36             :         struct scores *scores)
      37             : {
      38             :         size_t a;
      39           0 :         for(a=0; candidates && a<candidates_len; a++)
      40           0 :                 candidates[a]->score=&(scores->scores[a]);
      41           0 : }
      42             : 
      43           0 : struct candidate *candidates_add_new(void)
      44             : {
      45             :         struct candidate *candidate;
      46             : 
      47           0 :         if(!(candidate=candidate_alloc())) return NULL;
      48             : 
      49           0 :         if(!(candidates=(struct candidate **)realloc_w(candidates,
      50           0 :                 (candidates_len+1)*sizeof(struct candidate *), __func__)))
      51             :                         return NULL;
      52           0 :         candidates[candidates_len++]=candidate;
      53           0 :         return candidate;
      54             : }
      55             : 
      56             : // This deals with reading in the sparse index, as well as actual candidate
      57             : // manifests.
      58           0 : enum cand_ret candidate_load(struct candidate *candidate, const char *path,
      59             :         struct scores *scores)
      60             : {
      61           0 :         enum cand_ret ret=CAND_RET_PERM;
      62           0 :         struct fzp *fzp=NULL;
      63           0 :         struct sbuf *sb=NULL;
      64           0 :         struct blk *blk=NULL;
      65             : 
      66           0 :         if(!(sb=sbuf_alloc(PROTO_2))
      67           0 :           || !(blk=blk_alloc()))
      68             :         {
      69             :                 ret=CAND_RET_PERM;
      70             :                 goto error;
      71             :         }
      72             :         
      73           0 :         if(!(fzp=fzp_gzopen(path, "rb")))
      74             :         {
      75             :                 ret=CAND_RET_TEMP;
      76             :                 goto error;
      77             :         }
      78           0 :         while(fzp)
      79             :         {
      80           0 :                 sbuf_free_content(sb);
      81           0 :                 switch(sbuf_fill_from_file(sb, fzp, blk, NULL))
      82             :                 {
      83             :                         case 1: goto end;
      84             :                         case -1:
      85             :                                 logp("Error reading %s in %s, pos %lld\n",
      86           0 :                                         path, __func__, (long long)fzp_tell(fzp));
      87           0 :                                 ret=CAND_RET_TEMP;
      88           0 :                                 goto error;
      89             :                 }
      90           0 :                 if(blk_fingerprint_is_hook(blk))
      91             :                 {
      92           0 :                         if(sparse_add_candidate(&blk->fingerprint, candidate))
      93             :                         {
      94             :                                 ret=CAND_RET_PERM;
      95             :                                 goto error;
      96             :                         }
      97             :                 }
      98           0 :                 else if(sb->path.cmd==CMD_MANIFEST)
      99             :                 {
     100           0 :                         if(!(candidate=candidates_add_new()))
     101             :                         {
     102             :                                 ret=CAND_RET_PERM;
     103             :                                 goto error;
     104             :                         }
     105           0 :                         candidate->path=sb->path.buf;
     106           0 :                         sb->path.buf=NULL;
     107             :                 }
     108           0 :                 blk->fingerprint=0;
     109             :         }
     110             : 
     111             : end:
     112           0 :         if(scores_grow(scores, candidates_len))
     113             :         {
     114             :                 ret=CAND_RET_PERM;
     115             :                 goto error;
     116             :         }
     117           0 :         candidates_set_score_pointers(candidates, candidates_len, scores);
     118           0 :         scores_reset(scores);
     119             :         //logp("Now have %d candidates\n", (int)candidates_len);
     120           0 :         ret=CAND_RET_OK;
     121             : error:
     122           0 :         fzp_close(&fzp);
     123           0 :         sbuf_free(&sb);
     124           0 :         blk_free(&blk);
     125           0 :         return ret;
     126             : }
     127             : 
     128             : // When a backup is ongoing, use this to add newly complete candidates.
     129           0 : int candidate_add_fresh(const char *path, const char *directory,
     130             :         struct scores *scores)
     131             : {
     132           0 :         const char *cp=NULL;
     133           0 :         struct candidate *candidate=NULL;
     134             : 
     135           0 :         if(!(candidate=candidates_add_new()))
     136             :                 goto error;
     137           0 :         cp=path+strlen(directory);
     138           0 :         while(cp && *cp=='/') cp++;
     139           0 :         if(!(candidate->path=strdup_w(cp, __func__)))
     140             :                 goto error;
     141             : 
     142           0 :         switch(candidate_load(candidate, path, scores))
     143             :         {
     144             :                 case CAND_RET_PERM:
     145             :                         goto error;
     146             :                 case CAND_RET_TEMP:
     147             :                         // Had an error - try to carry on. Errors can happen
     148             :                         // when loading a fresh candidate because the backup
     149             :                         // process can move to the next phase and rename the
     150             :                         // candidates.
     151           0 :                         logp("Removing candidate.\n");
     152           0 :                         candidates_len--;
     153           0 :                         sparse_delete_fresh_candidate(candidate);
     154           0 :                         candidate_free(&candidate);
     155             :                         // Fall through.
     156             :                 case CAND_RET_OK:
     157             :                         return 0;
     158             :         }
     159             : error:
     160           0 :         candidate_free(&candidate);
     161           0 :         return -1;
     162             : }
     163             : 
     164           1 : struct candidate *candidates_choose_champ(struct incoming *in,
     165             :         struct candidate *champ_last, struct scores *scores)
     166             : {
     167             :         static uint16_t i;
     168             :         static uint16_t s;
     169             :         static struct sparse *sparse;
     170             :         static struct candidate *best;
     171             :         static struct candidate *candidate;
     172             :         static uint16_t *score;
     173             : 
     174           1 :         best=NULL;
     175             : 
     176             :         //struct timespec tstart={0,0}, tend={0,0};
     177             :         //clock_gettime(CLOCK_MONOTONIC, &tstart);
     178             : 
     179           1 :         scores_reset(scores);
     180             : 
     181        4097 :         for(i=0; i<in->size; i++)
     182             :         {
     183        4096 :                 if(in->found[i]) continue;
     184             : 
     185        4096 :                 if(!(sparse=sparse_find(&in->fingerprints[i])))
     186             :                         continue;
     187           0 :                 for(s=0; s<sparse->size; s++)
     188             :                 {
     189           0 :                         candidate=sparse->candidates[s];
     190           0 :                         if(candidate->deleted) continue;
     191           0 :                         if(candidate==champ_last)
     192             :                         {
     193             :                                 int t;
     194             :                                 // Want to exclude sparse entries that have
     195             :                                 // already been found.
     196           0 :                                 in->found[i]=1;
     197             :                                 // Need to go back up the list, subtracting
     198             :                                 // scores.
     199           0 :                                 for(t=s-1; t>=0; t--)
     200             :                                 {
     201           0 :                                         (*(sparse->candidates[t]->score))--;
     202             : //      printf("%d %s   fix: %d\n", i, candidate->path, *(sparse->candidates[t]->score));
     203             :                                 }
     204             :                                 break;
     205             :                         }
     206           0 :                         score=candidate->score;
     207           0 :                         (*score)++;
     208             : //                      printf("%d %s score: %d\n", i, candidate->path, *score);
     209           0 :                         assert(*score<=in->size);
     210           0 :                         if(!best
     211             :                         // Maybe should check for candidate!=best here too.
     212           0 :                           || *score>*(best->score))
     213             :                         {
     214           0 :                                 best=candidate;
     215             : /*
     216             :                                 printf("%s is now best:\n",
     217             :                                         best->path);
     218             :                                 printf("    score %p %d\n",
     219             :                                         best->score, *(best->score));
     220             : */
     221             :                         }
     222             :                         // FIX THIS: figure out a way of giving preference to
     223             :                         // newer candidates.
     224             :                 }
     225             :         }
     226             :         //clock_gettime(CLOCK_MONOTONIC, &tend);
     227             :         //printf("champ_chooser took about %.5f seconds\n",
     228             :         //      ((double)tend.tv_sec + 1.0e-9*tend.tv_nsec) - 
     229             :         //      ((double)tstart.tv_sec + 1.0e-9*tstart.tv_nsec));
     230             : 
     231             : /*
     232             :         if(best)
     233             :                 printf("%s is choice:\nscore %p %d\n", best->path, best->score, *(best->score));
     234             :         else
     235             :                 printf("no choice\n");
     236             : */
     237           1 :         return best;
     238             : }

Generated by: LCOV version 1.10