Logo Search packages:      
Sourcecode: baobab version File versions  Download package

hardlinks.c

#include <config.h>

#include <glib.h>

#include <sys/stat.h>
#include <sys/types.h>

#include "hardlinks.h"



struct _baobab_hardlinks_array
{
      /* Array of GnomeFileInfo *
         as long as we're optimistic about hardlinks count
         over the whole system (250 files with st_nlink > 1 here),
         we keep linear search.

         TODO: get real timings about this code. find out the average
         number of files with st_nlink > 1 on average computer.

         MAYBE: store only { inode, dev } instead of full struct stat.
         I don't know if dev_t and ino_t are standard enough so i guess
         i would be safier to store both as guint64.
         On my ppc :
         - dev_t is 8 bytes
         - ino_t is 4 bytes
         - struct stat is 88 bytes

         MAYBE: turn into a hashtable or tree for faster lookups.
         Would use st_ino or (st_ino and st_dev) for hash
         and use st_ino and st_dev for equality.
         Again, as we don't know the sizeof of these st_*, i don't
         think using g_direct_hash / g_direct_equal / boxing st_something
         into a void* would be safe.

         EDIT: /me stupid. I realize that this code was not called that often
         1 call per file with st_nlink > 1. BUT, i'm using pdumpfs to backup
         my /etc. pdumpfs massively uses hard links. So there are more than
         5000 files with st_nlink > 1. I believe this is the worst case.
      */

      GArray *inodes;
};



baobab_hardlinks_array * baobab_hardlinks_array_create(void)
{
      baobab_hardlinks_array *array;

      array = g_new(baobab_hardlinks_array, 1);
      array->inodes = g_array_new(FALSE, FALSE, sizeof(GnomeVFSFileInfo));

      return array;
}



gboolean baobab_hardlinks_array_has(baobab_hardlinks_array *a,
                            GnomeVFSFileInfo *s)
{
      guint i;

      for (i = 0; i < a->inodes->len; ++i) {
            GnomeVFSFileInfo *cur = &g_array_index(a->inodes, GnomeVFSFileInfo, i);

            /* cur->st_dev == s->st_dev is the common case and may be more
               expansive than cur->st_ino == s->st_ino
               so keep this order */
            if (cur->inode == s->inode && cur->device == s->device)
                  return TRUE;
      }

      return FALSE;
}


void baobab_hardlinks_array_add(baobab_hardlinks_array *a,
                        GnomeVFSFileInfo *s)
{
      /* FIXME: maybe slow check */
      g_assert(!baobab_hardlinks_array_has(a, s));
      g_array_append_val(a->inodes, *s);
}


void baobab_hardlinks_array_free(baobab_hardlinks_array *a)
{
      /*
      g_print("HL len was %u (size %u)\n",
            a->inodes->len,
            (unsigned) a->inodes->len * sizeof(struct stat));
      */
      g_array_free(a->inodes, TRUE);      
      g_free(a);
}


Generated by  Doxygen 1.6.0   Back to index