Ejemplo n.º 1
0
/* Pseudo-key (lien_url structure) hash function */
static inthash_keys key_adrfil_hashes_generic(void *arg, const char *value_, 
                                              const int former) {
  hash_struct *const hash = (hash_struct*) arg;
  const lien_url*const lien = (lien_url*) value_;
  const char *const adr = !former ? lien->adr : lien->former_adr;
  const char *const fil = !former ? lien->fil : lien->former_fil;
  const char *const adr_norm = adr != NULL ? 
    ( hash->normalized  ? jump_normalized(adr) : jump_identification(adr) )
    : NULL;

  // copy address
  assertf(adr_norm != NULL);
  strcpy(hash->normfil, adr_norm);

  // copy link
  assertf(fil != NULL);
  if (hash->normalized) {
    fil_normalized(fil, &hash->normfil[strlen(hash->normfil)]);
  } else {
    strcpy(&hash->normfil[strlen(hash->normfil)], fil);
  }

  // hash
  return inthash_hash_value(hash->normfil);
}
Ejemplo n.º 2
0
/* Pseudo-key (lien_url structure) comparison function */
static int key_adrfil_equals_generic(void *arg,
                                     coucal_key_const a_,
                                     coucal_key_const b_, 
                                     const int former) {
  hash_struct *const hash = (hash_struct*) arg;
  const int normalized = hash->normalized;
  const lien_url*const a = (const lien_url*) a_;
  const lien_url*const b = (const lien_url*) b_;
  const char *const a_adr = !former ? a->adr : a->former_adr;
  const char *const b_adr = !former ? b->adr : b->former_adr;
  const char *const a_fil = !former ? a->fil : a->former_fil;
  const char *const b_fil = !former ? b->fil : b->former_fil;
  const char *ja;
  const char *jb;

  // safety
  assertf(a_adr != NULL);
  assertf(b_adr != NULL);
  assertf(a_fil != NULL);
  assertf(b_fil != NULL);

  // skip scheme and authentication to the domain (possibly without www.)
  ja = normalized
    ? jump_normalized_const(a_adr) : jump_identification_const(a_adr);
  jb = normalized
    ? jump_normalized_const(b_adr) : jump_identification_const(b_adr);
  assertf(ja != NULL);
  assertf(jb != NULL);
  if (strcasecmp(ja, jb) != 0) {
    return 0;
  }

  // now compare pathes
  if (normalized) {
    fil_normalized(a_fil, hash->normfil);
    fil_normalized(b_fil, hash->normfil2);
    return strcmp(hash->normfil, hash->normfil2) == 0;
  } else {
    return strcmp(a_fil, b_fil) == 0;
  }
}
Ejemplo n.º 3
0
// GESTION DES TABLES DE HACHAGE
// Méthode à 2 clés (adr+fil), 2e cle facultative
// hash[no_enregistrement][pos]->hash est un index dans le tableau général liens
// #define HTS_HASH_SIZE 8191  (premier si possible!)
// type: numero enregistrement - 0 est case insensitive (sav) 1 (adr+fil) 2 (former_adr+former_fil)
// recherche dans la table selon nom1,nom2 et le no d'enregistrement
// retour: position ou -1 si non trouvé
int hash_read(const hash_struct* hash,char* nom1,char* nom2,int type,int normalized) {
  char BIGSTK normfil_[HTS_URLMAXSIZE*2];
	char catbuff[CATBUFF_SIZE];
  char* normfil;
  char* normadr;
  unsigned int cle;
  int pos; 
  // calculer la clé de recherche, non modulée
  if (type)
    cle = hash_cle(nom1,nom2);
  else
    cle = hash_cle(convtolower(catbuff,nom1),nom2);         // case insensitive
  // la position se calcule en modulant
  pos = (int) (cle%HTS_HASH_SIZE);
  // entrée trouvée?
  if (hash->hash[type][pos] >= 0) {             // un ou plusieurs enregistrement(s) avec une telle clé existe..
    // tester table de raccourcis (hash)
    // pos est maintenant la position recherchée dans liens
    pos = hash->hash[type][pos];
    while (pos>=0) {              // parcourir la chaine
      switch (type) {
      case 0:         // sav
        if (strfield2(nom1,hash->liens[pos]->sav)) {  // case insensitive
#if DEBUG_HASH==2
          printf("hash: found shortcut at %d\n",pos);
#endif
          return pos;
        }
        break;
      case 1:         // adr+fil
        {
          if (!normalized)
            normfil=hash->liens[pos]->fil;
          else
            normfil=fil_normalized(hash->liens[pos]->fil,normfil_);
          if (!normalized)
            normadr = jump_identification(hash->liens[pos]->adr);
          else
            normadr = jump_normalized(hash->liens[pos]->adr);
          if ((strfield2(nom1,normadr)!=0) && (strcmp(nom2,normfil)==0)) {
#if DEBUG_HASH==2
            printf("hash: found shortcut at %d\n",pos);
#endif
            return pos;
          }
        }
        break;
      case 2:         // former_adr+former_fil
        {
          if (hash->liens[pos]->former_adr) {
            if (!normalized)
              normfil=hash->liens[pos]->former_fil;
            else
              normfil=fil_normalized(hash->liens[pos]->former_fil,normfil_);
            if (!normalized)
              normadr = jump_identification(hash->liens[pos]->former_adr);
            else
              normadr = jump_normalized(hash->liens[pos]->former_adr);
            
            if ((strfield2(nom1,normadr)!=0) && (strcmp(nom2,normfil)==0)) {
#if DEBUG_HASH==2
              printf("hash: found shortcut at %d\n",pos);
#endif
              return pos;
            }
          }
        }
        break;
      }
      // calculer prochaine position dans la chaine
      {
        int old=pos;
        pos=hash->liens[pos]->hash_next[type];   // sinon prochain dans la chaine
        if (old==pos)
          pos=-1;         // erreur de bouclage (ne devrait pas arriver)
      }
    }
    
    // Ok va falloir chercher alors..
    /*pos=hash->max_lien;    // commencer à max_lien
    switch (type) {
    case 0:         // sav
      while(pos>=0) {
        if (hash->liens[pos]->hash_sav == cle ) {
          if (strcmp(nom1,hash->liens[pos]->sav)==0) {
            hash->hash[type][(int) (cle%HTS_HASH_SIZE)] = pos;    // noter plus récent dans shortcut table
#if DEBUG_HASH==2
            printf("hash: found long search at %d\n",pos);
#endif
            return pos;
          }
        }
        pos--;
      }
      break;
    case 1:         // adr+fil
      while(pos>=0) {
        if (hash->liens[pos]->hash_adrfil == cle ) {
          if ((strcmp(nom1,hash->liens[pos]->adr)==0) && (strcmp(nom2,hash->liens[pos]->fil)==0)) {
            hash->hash[type][(int) (cle%HTS_HASH_SIZE)] = pos;    // noter plus récent dans shortcut table
#if DEBUG_HASH==2
            printf("hash: found long search at %d\n",pos);
#endif
            return pos;
          }
        }
        pos--;
      }
      break;
    case 2:         // former_adr+former_fil
      while(pos>=0) {
        if (hash->liens[pos]->hash_fadrfil == cle ) {
          if (hash->liens[pos]->former_adr)
            if ((strcmp(nom1,hash->liens[pos]->former_adr)==0) && (strcmp(nom2,hash->liens[pos]->former_fil)==0)) {
            hash->hash[type][(int) (cle%HTS_HASH_SIZE)] = pos;    // noter plus récent dans shortcut table
#if DEBUG_HASH==2
            printf("hash: found long search at %d\n",pos);
#endif
            return pos;
          }
        }
        pos--;
      }
    }*/
#if DEBUG_HASH==1
    printf("hash: not found after test %s%s\n",nom1,nom2);
#endif
    return -1;    // non trouvé
  } else {
#if DEBUG_HASH==2
    printf("hash: not found %s%s\n",nom1,nom2);
#endif
    return -1;    // non trouvé : clé non entrée (même une fois)
  }
}
Ejemplo n.º 4
0
// enregistrement lien lpos dans les 3 tables hash1..3
void hash_write(hash_struct* hash,int lpos,int normalized) {
  char BIGSTK normfil_[HTS_URLMAXSIZE*2];
	char catbuff[CATBUFF_SIZE];
  char* normfil;
  unsigned int cle;
  int pos; 
  int* ptr;
  //
  if (hash->liens[lpos]) {                       // on sait jamais..
    hash->max_lien = max(hash->max_lien,lpos);
#if DEBUG_HASH
    hashnumber=hash->max_lien;
#endif
    // élément actuel sur -1 (fin de chaine)
    hash->liens[lpos]->hash_next[0]=hash->liens[lpos]->hash_next[1]=hash->liens[lpos]->hash_next[2]=-1;
    //
    cle = hash_cle(convtolower(catbuff,hash->liens[lpos]->sav),"");    // CASE INSENSITIVE
    pos = (int) (cle%HTS_HASH_SIZE);
    ptr = hash_calc_chaine(hash,0,pos);         // calculer adresse chaine
    *ptr = lpos;                   // noter dernier enregistré
#if DEBUG_HASH==3
    printf("[%d",pos);
#endif
    //
    if (!normalized)
      normfil=hash->liens[lpos]->fil;
    else
      normfil=fil_normalized(hash->liens[lpos]->fil,normfil_);
    if (!normalized)
      cle = hash_cle(jump_identification(hash->liens[lpos]->adr),normfil);
    else
      cle = hash_cle(jump_normalized(hash->liens[lpos]->adr),normfil);
    pos = (int) (cle%HTS_HASH_SIZE);
    ptr = hash_calc_chaine(hash,1,pos);         // calculer adresse chaine
    *ptr = lpos;                   // noter dernier enregistré
#if DEBUG_HASH==3
    printf(",%d",pos);
#endif
    //
    if (hash->liens[lpos]->former_adr) {         // former_adr existe?
      if (!normalized)
        normfil=hash->liens[lpos]->former_fil;
      else
        normfil=fil_normalized(hash->liens[lpos]->former_fil,normfil_);
      if (!normalized)
        cle = hash_cle(jump_identification(hash->liens[lpos]->former_adr),normfil);
      else
        cle = hash_cle(jump_normalized(hash->liens[lpos]->former_adr),normfil);
      pos = (int) (cle%HTS_HASH_SIZE);
      ptr = hash_calc_chaine(hash,2,pos);         // calculer adresse chaine
      *ptr = lpos;                   // noter dernier enregistré
#if DEBUG_HASH==3
      printf(",%d",pos);
#endif
    }
#if DEBUG_HASH==3
    printf("] "); fflush(stdout);
#endif
  }
#if DEBUT_HASH
  else {
    printf("* hash_write=0!!\n");
    abortLogFmt("unexpected error in hash_write (pos=%d)" _ pos);
    exit(1);
  }
#endif
  //
}