[Bf-blender-cvs] [979d16e] asset-experiments: BLI filelist: get rid of strings for size/time/mode/etc.

Bastien Montagne noreply at git.blender.org
Mon Apr 6 19:57:31 CEST 2015


Commit: 979d16e52ff2e321748ff6ae99fdb81e3ee5d429
Author: Bastien Montagne
Date:   Sun Apr 5 15:40:41 2015 +0200
Branches: asset-experiments
https://developer.blender.org/rB979d16e52ff2e321748ff6ae99fdb81e3ee5d429

BLI filelist: get rid of strings for size/time/mode/etc.

Those were eating quite a bit of bites, not neglectable with thousands of entries...
Also, useless to print those info most of the time, they are not used!

So now, we only store 'raw' stat data, and expose funcs to convert them to readable
strings on demand.

===================================================================

M	source/blender/blenlib/BLI_fileops.h
M	source/blender/blenlib/BLI_fileops_types.h
M	source/blender/blenlib/intern/BLI_filelist.c

===================================================================

diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index f4edf2c..fb9d445 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -97,6 +97,11 @@ void BLI_filelist_duplicate(struct direntry **dest_filelist, struct direntry *sr
 void BLI_filelist_entry_free(struct direntry *entry);
 void BLI_filelist_free(struct direntry *filelist, unsigned int nrentries);
 
+void BLI_filelist_entry_size_to_string(struct stat *st, char r_size[]);
+void BLI_filelist_entry_mode_to_string(struct stat *st, char r_mode1[], char r_mode2[], char r_mode3[]);
+void BLI_filelist_entry_owner_to_string(struct stat *st, char r_owner[]);
+void BLI_filelist_entry_datetime_to_string(struct stat *st, char r_time[], char r_date[]);
+
 /* Files */
 
 FILE  *BLI_fopen(const char *filename, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
diff --git a/source/blender/blenlib/BLI_fileops_types.h b/source/blender/blenlib/BLI_fileops_types.h
index 96e39f8..060aa3a 100644
--- a/source/blender/blenlib/BLI_fileops_types.h
+++ b/source/blender/blenlib/BLI_fileops_types.h
@@ -39,6 +39,12 @@
 typedef unsigned int mode_t;
 #endif
 
+#define FILELIST_DIRENTRY_SIZE_LEN  16
+#define FILELIST_DIRENTRY_MODE_LEN  4
+#define FILELIST_DIRENTRY_OWNER_LEN 16
+#define FILELIST_DIRENTRY_TIME_LEN  8
+#define FILELIST_DIRENTRY_DATE_LEN  16
+
 struct direntry {
 	mode_t  type;
 	char   *relname;
@@ -54,13 +60,6 @@ struct direntry {
 #else
 	struct stat s;
 #endif
-	char    size[16];
-	char    mode1[4];
-	char    mode2[4];
-	char    mode3[4];
-	char    owner[16];
-	char    time[8];
-	char    date[16];
 };
 
 struct dirlink {
diff --git a/source/blender/blenlib/intern/BLI_filelist.c b/source/blender/blenlib/intern/BLI_filelist.c
index da9b7ff..8391a56 100644
--- a/source/blender/blenlib/intern/BLI_filelist.c
+++ b/source/blender/blenlib/intern/BLI_filelist.c
@@ -175,130 +175,144 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname)
 }
 
 /**
- * Fills in the "mode[123]", "size" and "string" fields in the elements of the files
- * array with descriptive details about each item. "string" will have a format similar to "ls -l".
+ * Scans the contents of the directory named *dirname, and allocates and fills in an
+ * array of entries describing them in *filelist.
+ *
+ * \return The length of filelist array.
  */
-static void bli_adddirstrings(struct BuildDirCtx *dir_ctx)
+unsigned int BLI_filelist_dir_contents(const char *dirname,  struct direntry **filelist)
 {
-	const char *types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
-	/* symbolic display, indexed by mode field value */
-	int num;
-#ifdef WIN32
-	__int64 st_size;
-#else
-	off_t st_size;
-	int mode;
-#endif
-
-	struct direntry *file;
-	struct tm *tm;
-	time_t zero = 0;
-
-	for (num = 0, file = dir_ctx->files; num < dir_ctx->nrfiles; num++, file++) {
-
+	struct BuildDirCtx dir_ctx;
 
-		/* Mode */
-#ifdef WIN32
-		BLI_strncpy(file->mode1, types[0], sizeof(file->mode1));
-		BLI_strncpy(file->mode2, types[0], sizeof(file->mode2));
-		BLI_strncpy(file->mode3, types[0], sizeof(file->mode3));
-#else
-		mode = file->s.st_mode;
+	dir_ctx.nrfiles = 0;
+	dir_ctx.files = NULL;
 
-		BLI_strncpy(file->mode1, types[(mode & 0700) >> 6], sizeof(file->mode1));
-		BLI_strncpy(file->mode2, types[(mode & 0070) >> 3], sizeof(file->mode2));
-		BLI_strncpy(file->mode3, types[(mode & 0007)],      sizeof(file->mode3));
+	bli_builddir(&dir_ctx, dirname);
 
-		if (((mode & S_ISGID) == S_ISGID) && (file->mode2[2] == '-')) file->mode2[2] = 'l';
+	if (dir_ctx.files) {
+		*filelist = dir_ctx.files;
+	}
+	else {
+		// keep blender happy. Blender stores this in a variable
+		// where 0 has special meaning.....
+		*filelist = MEM_mallocN(sizeof(**filelist), __func__);
+	}
 
-		if (mode & (S_ISUID | S_ISGID)) {
-			if (file->mode1[2] == 'x') file->mode1[2] = 's';
-			else file->mode1[2] = 'S';
+	return dir_ctx.nrfiles;
+}
 
-			if (file->mode2[2] == 'x') file->mode2[2] = 's';
-		}
+/**
+ * Convert given entry's size into human-readable strings.
+ *
+ */
+void BLI_filelist_entry_size_to_string(struct stat *st, char r_size[FILELIST_DIRENTRY_SIZE_LEN])
+{
+	double size;
+	const char *fmt;
+
+	/*
+	 * Seems st_size is signed 32-bit value in *nix and Windows.  This
+	 * will buy us some time until files get bigger than 4GB or until
+	 * everyone starts using __USE_FILE_OFFSET64 or equivalent.
+	 */
+	size = (double)st->st_size;
+
+	if (size > 1024.0 * 1024.0 * 1024.0) {
+		size /= (1024.0 * 1024.0 * 1024.0);
+		fmt = "%.2f GiB";
+	}
+	else if (size > 1024.0 * 1024.0) {
+		size /= (1024.0 * 1024.0);
+		fmt = "%.2f MiB";
+	}
+	else if (size > 1024.0) {
+		size /= 1024.0;
+		fmt = "%.2f KiB";
+	}
+	else {
+		fmt = "%.0f B";
+	}
 
-		if (mode & S_ISVTX) {
-			if (file->mode3[2] == 'x') file->mode3[2] = 't';
-			else file->mode3[2] = 'T';
-		}
-#endif
+	BLI_snprintf(r_size, sizeof(*r_size) * FILELIST_DIRENTRY_SIZE_LEN, fmt, size);
+}
 
+/**
+ * Convert given entry's modes into human-readable strings.
+ *
+ */
+void BLI_filelist_entry_mode_to_string(
+        struct stat *st, char r_mode1[FILELIST_DIRENTRY_MODE_LEN],
+        char r_mode2[FILELIST_DIRENTRY_MODE_LEN], char r_mode3[FILELIST_DIRENTRY_MODE_LEN])
+{
+	const char *types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
 
-		/* User */
 #ifdef WIN32
-		strcpy(file->owner, "user");
+	BLI_strncpy(r_mode1, types[0], sizeof(*r_mode1) * FILELIST_DIRENTRY_MODE_LEN);
+	BLI_strncpy(r_mode2, types[0], sizeof(*r_mode2) * FILELIST_DIRENTRY_MODE_LEN);
+	BLI_strncpy(r_mode3, types[0], sizeof(*r_mode3) * FILELIST_DIRENTRY_MODE_LEN);
 #else
-		{
-			struct passwd *pwuser;
-			pwuser = getpwuid(file->s.st_uid);
-			if (pwuser) {
-				BLI_strncpy(file->owner, pwuser->pw_name, sizeof(file->owner));
-			}
-			else {
-				BLI_snprintf(file->owner, sizeof(file->owner), "%u", file->s.st_uid);
-			}
-		}
-#endif
+	const int mode = st->st_mode;
 
+	BLI_strncpy(r_mode1, types[(mode & 0700) >> 6], sizeof(*r_mode1) * FILELIST_DIRENTRY_MODE_LEN);
+	BLI_strncpy(r_mode2, types[(mode & 0070) >> 3], sizeof(*r_mode2) * FILELIST_DIRENTRY_MODE_LEN);
+	BLI_strncpy(r_mode3, types[(mode & 0007)],      sizeof(*r_mode3) * FILELIST_DIRENTRY_MODE_LEN);
 
-		/* Time */
-		tm = localtime(&file->s.st_mtime);
-		// prevent impossible dates in windows
-		if (tm == NULL) tm = localtime(&zero);
-		strftime(file->time, sizeof(file->time), "%H:%M", tm);
-		strftime(file->date, sizeof(file->date), "%d-%b-%y", tm);
+	if (((mode & S_ISGID) == S_ISGID) && (r_mode2[2] == '-')) r_mode2[2] = 'l';
 
+	if (mode & (S_ISUID | S_ISGID)) {
+		if (r_mode1[2] == 'x') r_mode1[2] = 's';
+		else r_mode1[2] = 'S';
 
-		/* Size */
-		/*
-		 * Seems st_size is signed 32-bit value in *nix and Windows.  This
-		 * will buy us some time until files get bigger than 4GB or until
-		 * everyone starts using __USE_FILE_OFFSET64 or equivalent.
-		 */
-		st_size = file->s.st_size;
+		if (r_mode2[2] == 'x') r_mode2[2] = 's';
+	}
 
-		if (st_size > 1024 * 1024 * 1024) {
-			BLI_snprintf(file->size, sizeof(file->size), "%.2f GiB", ((double)st_size) / (1024 * 1024 * 1024));
-		}
-		else if (st_size > 1024 * 1024) {
-			BLI_snprintf(file->size, sizeof(file->size), "%.1f MiB", ((double)st_size) / (1024 * 1024));
-		}
-		else if (st_size > 1024) {
-			BLI_snprintf(file->size, sizeof(file->size), "%d KiB", (int)(st_size / 1024));
-		}
-		else {
-			BLI_snprintf(file->size, sizeof(file->size), "%d B", (int)st_size);
-		}
+	if (mode & S_ISVTX) {
+		if (r_mode3[2] == 'x') r_mode3[2] = 't';
+		else r_mode3[2] = 'T';
 	}
+#endif
 }
 
 /**
- * Scans the contents of the directory named *dirname, and allocates and fills in an
- * array of entries describing them in *filelist.
+ * Convert given entry's owner into human-readable strings.
  *
- * \return The length of filelist array.
  */
-unsigned int BLI_filelist_dir_contents(const char *dirname,  struct direntry **filelist)
+void BLI_filelist_entry_owner_to_string(struct stat *st, char r_owner[FILELIST_DIRENTRY_OWNER_LEN])
 {
-	struct BuildDirCtx dir_ctx;
-
-	dir_ctx.nrfiles = 0;
-	dir_ctx.files = NULL;
-
-	bli_builddir(&dir_ctx, dirname);
-	bli_adddirstrings(&dir_ctx);
+#ifdef WIN32
+	strcpy(r_owner, "unknown");
+#else
+	struct passwd *pwuser = getpwuid(st->st_uid);
 
-	if (dir_ctx.files) {
-		*filelist = dir_ctx.files;
+	if (pwuser) {
+		BLI_strncpy(r_owner, pwuser->pw_name, sizeof(*r_owner) * FILELIST_DIRENTRY_OWNER_LEN);
 	}
 	else {
-		// keep blender happy. Blender stores this in a variable
-		// where 0 has special meaning.....
-		*filelist = MEM_mallocN(sizeof(**filelist), __func__);
+		BLI_snprintf(r_owner, sizeof(*r_owner) * FILELIST_DIRENTRY_OWNER_LEN, "%u", st->st_uid);
 	}
+#endif
+}
 
-	return dir_ctx.nrfiles;
+/**
+ * Convert given entry's time into human-readable strings.
+ */
+void BLI_filelist_entry_datetime_to_string(
+        struct stat *st, char r_time[FILELIST_DIRENTRY_TIME_LEN], char r_date[FILELIST_DIRENTRY_DATE_LEN])
+{
+	const struct tm *tm = localtime(&st->st_mtime);
+	const time_t zero = 0;
+
+	/* Prevent impossible dates in windows. */
+	if (tm == NULL) {
+		tm = localtime(&zero);
+	}
+
+	if (r_time) {
+		strftime(r_time, sizeof(*r_time) * FILELIST_DIRENTRY_TIME_LEN, "%H:%M", tm);
+	}
+	if (r_date) {
+		strftime(r_date, sizeof(*r_date) * FILELIST_DIRENTRY_DATE_LEN, "%d-%b-%y", tm);
+	}
 }
 
 /**




More information about the Bf-blender-cvs mailing list