diff options
| author | root <root> | 2009-06-14 20:36:59 +0000 | 
|---|---|---|
| committer | root <root> | 2009-06-14 20:36:59 +0000 | 
| commit | 931d536a4c70efe39722b61a885c0bdfdf9250d4 (patch) | |
| tree | d34122a532e173bcd9056c42389aaa29b1ba365c | |
| parent | 17ae00914756419ccbbc460c94a016d5457989a8 (diff) | |
*** empty log message ***
| -rw-r--r-- | eio.c | 75 | 
1 files changed, 41 insertions, 34 deletions
| @@ -1000,6 +1000,7 @@ eio_dent_cmp (const eio_dirent *a, const eio_dirent *b)  }  #define EIO_DENT_CMP(i,op,j) eio_dent_cmp (&i, &j) op 0 +#define EIO_DENT_NUM_SCORES 9  #define EIO_QSORT_CUTOFF 30 /* quite high, but performs well on many filesystems */  #define EIO_QSORT_SKIP   60 /* when to skip qsort completely */ @@ -1007,8 +1008,6 @@ eio_dent_cmp (const eio_dirent *a, const eio_dirent *b)  static void  eio_dent_sort (eio_dirent *dents, int size)  { -  int i, j; -    if (size <= 1)      return; /* our insertion sort relies on size > 0 */ @@ -1016,37 +1015,39 @@ eio_dent_sort (eio_dirent *dents, int size)      {        /* first, use quicksort */        /* should be good for 2**31 entries */ -      struct rng { int l, r; } rng [32]; +      int i; +      struct rng { eio_dirent *l, *r; } rng [32];        i = 0; -      rng[0].l = 0; -      rng[0].r = size; +      rng[0].l = dents; +      rng[0].r = dents + size;        while (expect_true (i >= 0))          { -          int L = rng [i].l; -          int R = rng [i].r - 1; +          eio_dirent *L = rng [i].l; +          eio_dirent *R = rng [i].r - 1;            if (expect_false (L + EIO_QSORT_CUTOFF < R))              { -              eio_dirent piv = dents [L]; +              eio_dirent *mid = &dents [((L - dents) + (R - dents)) >> 1]; +              eio_dirent piv = *mid; *mid = *L; *L = piv;                while (L < R)                  { -                  while (EIO_DENT_CMP (dents [R], >=, piv) && L < R) +                  while (EIO_DENT_CMP (*R, >=, piv) && L < R)                      --R;                    if (L < R) -                    dents [L++] = dents [R]; +                    *L++ = *R; -                  while (EIO_DENT_CMP (dents [L], <=, piv) && L < R) +                  while (EIO_DENT_CMP (*L, <=, piv) && L < R)                      ++L;                    if (L < R) -                    dents [R--] = dents [L]; +                    *R-- = *L;                  } -              dents [L] = piv; +              *L = piv;                ++i;                rng [i].l = L + 1; @@ -1068,31 +1069,33 @@ eio_dent_sort (eio_dirent *dents, int size)    /* use an insertion sort after qsort, or for small arrays */    /* first move the smallest element to the front, to act as a sentinel */    { -    int min = 0; - +    int i; +    eio_dirent *min = dents; +          for (i = size > EIO_QSORT_SKIP ? EIO_QSORT_CUTOFF + 1 : size; --i; ) -      if (EIO_DENT_CMP (dents [i], <, dents [min])) -        min = i; +      if (EIO_DENT_CMP (dents [i], <, *min)) +        min = &dents [i];      /* swap elements 0 and j (minimum) */      { -      eio_dirent tmp = dents [0]; dents [0] = dents [min]; dents [min] = tmp; +      eio_dirent tmp = *dents; *dents = *min; *min = tmp;      }    } -  /* then do standard insertion sort */ -  for (i = 1; i < size; ++i) -    { -      eio_dirent value = dents [i]; +  { +    /* then do standard insertion sort */ +    eio_dirent *i, *j; -      for (j = i - 1; EIO_DENT_CMP (dents [j], >, value); --j) -        { -          assert (j >= 0); -        dents [j + 1] = dents [j]; -        } +    for (i = dents + 1; i < dents + size; ++i) +      { +        eio_dirent value = *i; -      dents [j + 1] = value; -    } +        for (j = i - 1; EIO_DENT_CMP (*j, >, value); --j) +          j [1] = j [0]; + +        j [1] = value; +      } +  }  }  /* read a full directory */ @@ -1159,7 +1162,10 @@ eio__scandir (eio_req *req, etp_worker *self)                  while (ent > dir)                    {                      if (dir->type == DT_DIR) -                      ++dir; +                      { +                        dir->score = 0; +                        ++dir; +                      }                      else                         {                          --ent; @@ -1170,6 +1176,7 @@ eio__scandir (eio_req *req, etp_worker *self)                              *dir = *ent;                              *ent = tmp; +                            dir->score = 0;                              ++dir;                            }                        } @@ -1232,7 +1239,7 @@ eio__scandir (eio_req *req, etp_worker *self)                  ent->name    = (char *)(size_t)namesoffs; /* rather dirtily we store the offset in the pointer */                  ent->namelen = len - 1; -                ent->inode   = D_INO (entp); +                ent->inode   = D_INO (entp) ? D_INO (entp) : dentoffs;                  switch (D_TYPE (entp))                    { @@ -1292,12 +1299,12 @@ eio__scandir (eio_req *req, etp_worker *self)                      if (ent->type == EIO_DT_UNKNOWN)                        {                          if (*name == '.') /* leading dots are likely directories, and, in any case, rare */ -                          ent->score = 98; +                          ent->score = 7;                          else if (!strchr (name, '.')) /* absense of dots indicate likely dirs */ -                          ent->score = len <= 2 ? len + 6 : len <= 4 ? 5 : len <= 7 ? 4 : 1; /* shorter == more likely dir, but avoid too many classes */ +                          ent->score = len <= 2 ? len + 4 : len <= 4 ? 3 : len <= 7 ? 2 : 1; /* shorter == more likely dir, but avoid too many classes */                        }                      else if (ent->type == EIO_DT_DIR) -                      ent->score = 100; +                      ent->score = 8;                    }                } | 
