Re: [AD] [ alleg-Patches-1103334 ] fsel.c > 2048 files

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


> As  discussed with Evert, this is a patch to allow the file 
> selector to handle files with more than 2048 entries.
> It uses a variable sized array with realloc, so it has minimal 
> impact on the rest of the file. The file selector could be 
> optimized, I think, by doing a qsort on the full file list, 
> instead of an insertion sort as the list is being built, but I 
> don't see much benefit in this.
> This compiles ok for me on OSX, please test on other 
> platforms. Also, the indentation is not correct because OSX's 
> indent program does not recognise all the settings in 
> Allegro's indent.pro

Works fine for me in Linux. I've commited the attached patch, which is 
identical to the original up to formatting.

Evert
Index: src/fsel.c
===================================================================
RCS file: /cvsroot/alleg/allegro/src/fsel.c,v
retrieving revision 1.39
diff -u -p -r1.39 fsel.c
--- src/fsel.c	22 Jun 2003 21:24:09 -0000	1.39
+++ src/fsel.c	16 Jan 2005 17:38:14 -0000
@@ -55,14 +55,21 @@ static char *fs_dlist_getter(int, int *)
 
 #endif
 
-
-#define FLIST_SIZE      2048
+/* Number of entries is limited by available memory
+ * Initial capacity is given by FLIST_START_CAPACITY, structure can grow beyond
+ * this. Normally keeps the structure in memory between invocations, but it
+ * attempts to free memory after processing a directory with more than 
+ * FLIST_UPPER_CAPACITY 
+ */
+#define FLIST_START_CAPACITY 128
+#define FLIST_UPPER_CAPACITY 2048
 
 typedef struct FLIST
 {
    char dir[1024];
    int size;
-   char *name[FLIST_SIZE];
+   int capacity;
+   char** name;
 } FLIST;
 
 static FLIST *flist = NULL;
@@ -427,7 +434,7 @@ static int fs_flist_putter(AL_CONST char
       }
    }
 
-   if ((flist->size < FLIST_SIZE) && ((ugetc(s) != '.') || (ugetat(s, 1)))) {
+   if (((ugetc(s) != '.') || (ugetat(s, 1)))) {
       int size = ustrsizez(s) + ((attrib & FA_DIREC) ? ucwidth(OTHER_PATH_SEPARATOR) : 0);
       name = malloc(size);
       if (!name)
@@ -451,6 +458,17 @@ static int fs_flist_putter(AL_CONST char
 	       break;
 	 }
       }
+      /* Do we need to allocate more space in the structure? */
+      /* This doubles the capacity of the array each time, */
+      /* which gives 'linear' compexity */
+      if (flist->size==flist->capacity) {
+	 flist->name=_al_sane_realloc(flist->name, sizeof(char*)*(flist->capacity*=2));
+	 if (flist->name==NULL) {
+	    *allegro_error=ENOMEM;
+	    /* Stop the enumeration by returning non-zero */
+	    return -1;
+	 }
+      }
 
       /* Shift in preparation for inserting the new entry. */
       for (c2=flist->size; c2>c; c2--)
@@ -520,11 +538,29 @@ static int fs_flist_proc(int msg, DIALOG
 	    *allegro_errno = ENOMEM;
 	    return D_CLOSE; 
 	 }
+	 flist->capacity=FLIST_START_CAPACITY;
+	 flist->name=malloc(flist->capacity*sizeof(char*));
+	 if (!flist->name) {
+	    *allegro_errno = ENOMEM;
+	    return D_CLOSE;
+         }
       }
       else {
 	 for (i=0; i<flist->size; i++)
-	    if (flist->name[i])
+	    if (flist->name[i]) {
 	       free(flist->name[i]);
+	       /* PH add: maybe avoid multiple frees */
+	       flist->name[i]=NULL;
+	    }
+	 /* Maybe shrink the structure */
+	 if (flist->capacity>FLIST_UPPER_CAPACITY) {
+	    flist->name=_al_sane_realloc(flist->name, sizeof(char*)*(flist->capacity=FLIST_UPPER_CAPACITY));
+	    if (!flist) {
+	       /* Oops! Should never happen, I hope */
+	       *allegro_errno = ENOMEM;
+	       return D_CLOSE;
+	    }
+	 }
       }
 
       flist->size = 0;


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/