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 -0000	1.31
--- src/port/dirmod.c	28 Oct 2004 13:43:56 -0000
***************
*** 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

Reply via email to