Forráskód Böngészése

Optimize DirAccessUnix::get_next() for some file systems

On some file systems, like ext4 on Linux, readdir() gives enough
information to determine the entry type in order to avoid doing
a stat() system call.

Use this information and call stat() only if necessary: for file
systems that do not support this feature and for links.
Hadrien 6 éve
szülő
commit
e02c5ef48a
1 módosított fájl, 13 hozzáadás és 18 törlés
  1. 13 18
      drivers/unix/dir_access_unix.cpp

+ 13 - 18
drivers/unix/dir_access_unix.cpp

@@ -126,37 +126,32 @@ String DirAccessUnix::get_next() {
 
 
 	if (!dir_stream)
 	if (!dir_stream)
 		return "";
 		return "";
-	dirent *entry;
 
 
-	entry = readdir(dir_stream);
+	dirent *entry = readdir(dir_stream);
 
 
 	if (entry == NULL) {
 	if (entry == NULL) {
-
 		list_dir_end();
 		list_dir_end();
 		return "";
 		return "";
 	}
 	}
 
 
-	//typedef struct stat Stat;
-	struct stat flags;
-
 	String fname = fix_unicode_name(entry->d_name);
 	String fname = fix_unicode_name(entry->d_name);
 
 
-	String f = current_dir.plus_file(fname);
-
-	if (stat(f.utf8().get_data(), &flags) == 0) {
-
-		if (S_ISDIR(flags.st_mode)) {
-
-			_cisdir = true;
-
+	// Look at d_type to determine if the entry is a directory, unless
+	// its type is unknown (the file system does not support it) or if
+	// the type is a link, in that case we want to resolve the link to
+	// known if it points to a directory. stat() will resolve the link
+	// for us.
+	if (entry->d_type == DT_UNKNOWN || entry->d_type == DT_LNK) {
+		String f = current_dir.plus_file(fname);
+
+		struct stat flags;
+		if (stat(f.utf8().get_data(), &flags) == 0) {
+			_cisdir = S_ISDIR(flags.st_mode);
 		} else {
 		} else {
-
 			_cisdir = false;
 			_cisdir = false;
 		}
 		}
-
 	} else {
 	} else {
-
-		_cisdir = false;
+		_cisdir = (entry->d_type == DT_DIR);
 	}
 	}
 
 
 	_cishidden = (fname != "." && fname != ".." && fname.begins_with("."));
 	_cishidden = (fname != "." && fname != ".." && fname.begins_with("."));