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;