[PATCHES] rmtree cleanup

2004-10-28 Thread Andrew Dunstan
The attached patch cleans up src/port/dirmod.c::rmtree() a bit. It moves 
the filename finding portion into its own function, and in that function 
only scans the directory once instead of twice.

cheers
andrew

Index: src/port/dirmod.c
===
RCS file: /home/cvsmirror/pgsql/src/port/dirmod.c,v
retrieving revision 1.31
diff -c -r1.31 dirmod.c
*** src/port/dirmod.c	18 Oct 2004 19:08:58 -	1.31
--- src/port/dirmod.c	28 Oct 2004 13:43:56 -
***
*** 273,331 
  #endif
  }
  
- 
  /*
!  *	rmtree
!  *
!  *	Delete a directory tree recursively.
!  *	Assumes path points to a valid directory.
!  *	Deletes everything under path.
!  *	If rmtopdir is true deletes the directory too.
   *
   */
! bool
! rmtree(char *path, bool rmtopdir)
  {
- 	char		filepath[MAXPGPATH];
  	DIR		   *dir;
  	struct dirent *file;
  	char	  **filenames;
- 	char	  **filename;
  	int			numnames = 0;
- 	struct stat statbuf;
- 
- 	/*
- 	 * we copy all the names out of the directory before we start
- 	 * modifying it.
- 	 */
- 
- 	dir = opendir(path);
- 	if (dir == NULL)
- 		return false;
  
! 	while ((file = readdir(dir)) != NULL)
! 	{
! 		if (strcmp(file-d_name, .) != 0  strcmp(file-d_name, ..) != 0)
! 			numnames++;
! 	}
! 
! 	rewinddir(dir);
  
  #ifdef FRONTEND
! 	if ((filenames = malloc((numnames + 2) * sizeof(char *))) == NULL)
  	{
  		fprintf(stderr, _(out of memory\n));
  		exit(1);
  	}
  #else
! 	filenames = palloc((numnames + 2) * sizeof(char *));
  #endif
  
! 	numnames = 0;
  
  	while ((file = readdir(dir)) != NULL)
  	{
  		if (strcmp(file-d_name, .) != 0  strcmp(file-d_name, ..) != 0)
  #ifdef FRONTEND
  			if ((filenames[numnames++] = strdup(file-d_name)) == NULL)
  			{
--- 273,331 
  #endif
  }
  
  /*
!  * fnames
   *
+  * return a list of the names of objects in the argument directory 
   */
! 
! static char **
! fnames(char * path)
  {
  	DIR		   *dir;
  	struct dirent *file;
  	char	  **filenames;
  	int			numnames = 0;
  
! 	int fnsize = 200; /* 200 will take care of many small dbs */
  
  #ifdef FRONTEND
! 	if ((filenames = malloc(fnsize * sizeof(char *))) == NULL)
  	{
  		fprintf(stderr, _(out of memory\n));
  		exit(1);
  	}
  #else
! 	filenames = palloc(fnsize * sizeof(char *));
  #endif
  
! 	dir = opendir(path);
! 	if (dir == NULL)
! 	{
! 		filenames[0]=NULL;
! 		rmt_cleanup(filenames);
! 		return NULL;
! 	}
  
  	while ((file = readdir(dir)) != NULL)
  	{
  		if (strcmp(file-d_name, .) != 0  strcmp(file-d_name, ..) != 0)
+ 		{
+ 			if (numnames+2 = fnsize)
+ 			{
+ fnsize += fnsize;
+ #ifdef FRONTEND
+ if ((filenames = realloc(filenames,
+ 		 fnsize * sizeof(char *))) == NULL)
+ {
+ 	fprintf(stderr, _(out of memory\n));
+ 	exit(1);
+ }
+ #else
+ filenames = repalloc(filenames, fnsize * sizeof(char *));
+ #endif
+ 			}
+ 
  #ifdef FRONTEND
  			if ((filenames[numnames++] = strdup(file-d_name)) == NULL)
  			{
***
*** 335,346 
--- 335,379 
  #else
  			filenames[numnames++] = pstrdup(file-d_name);
  #endif
+ 
+ 		}
  	}
  
+ 
  	filenames[numnames] = NULL;
  
  	closedir(dir);
  
+ 	return filenames;
+ 
+ }
+ 
+ /*
+  *	rmtree
+  *
+  *	Delete a directory tree recursively.
+  *	Assumes path points to a valid directory.
+  *	Deletes everything under path.
+  *	If rmtopdir is true deletes the directory too.
+  *
+  */
+ bool
+ rmtree(char *path, bool rmtopdir)
+ {
+ 	char		filepath[MAXPGPATH];
+ 	char	  **filenames;
+ 	char	  **filename;
+ 	struct stat statbuf;
+ 
+ 	/*
+ 	 * we copy all the names out of the directory before we start
+ 	 * modifying it.
+ 	 */
+ 	filenames = fnames(path);
+ 
+ 	if (filenames == NULL)
+ 		return false;
+ 
  	/* now we have the names we can start removing things */
  
  	for (filename = filenames; *filename; filename++)

---(end of broadcast)---
TIP 8: explain analyze is your friend


Re: [PATCHES] rmtree cleanup

2004-10-28 Thread Andrew Dunstan

Tom Lane wrote:
Andrew Dunstan [EMAIL PROTECTED] writes:
 

The attached patch cleans up src/port/dirmod.c::rmtree() a bit. It moves 
the filename finding portion into its own function, and in that function 
only scans the directory once instead of twice.
   

Applied, along with some further hacking to reduce the #ifdef clutter
by providing palloc substitute routines.  

Nice. It's actually readable now :-)
I checked it still works on
Unix, would you check I didn't break the Windows cases?
 

Yes, it works. Thanks.
andrew
---(end of broadcast)---
TIP 5: Have you checked our extensive FAQ?
  http://www.postgresql.org/docs/faqs/FAQ.html