all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Arthur Miller <arthur.miller@live.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: Michael Albinus <michael.albinus@gmx.de>, emacs-devel@gnu.org
Subject: Re: empty-directory predicate, native implementation
Date: Wed, 14 Oct 2020 03:52:42 +0200	[thread overview]
Message-ID: <VI1PR06MB452688C9C71D5463D9497A2A96050@VI1PR06MB4526.eurprd06.prod.outlook.com> (raw)
In-Reply-To: <83blh60wgr.fsf@gnu.org> (Eli Zaretskii's message of "Tue, 13 Oct 2020 22:14:44 +0300")

[-- Attachment #1: Type: text/plain, Size: 1833 bytes --]

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Michael Albinus <michael.albinus@gmx.de>
>> Cc: Arthur Miller <arthur.miller@live.com>,  emacs-devel@gnu.org
>> Date: Tue, 13 Oct 2020 20:44:18 +0200
>> 
>> > As a bonus, we will be able to return the file names we read, not just
>> > ignore them.
>> 
>> I agree with your proposal. However, I don't see why it is a bonus to
>> know which file names have read already, because they are taken in
>> random order.
>
> The order depends on the filesystem.  For example, MS-Windows
> filesystems always report in alphabetic order.
>
>> I fail to see how does it help, whether a file name is returned
>> under the first N matches, or not.
>
> Well, it is easy to disregard the names if they aren't needed.

Your idea was definitely much simpler to implement, rather trivial :-).
I just tested for myself, and it seems to work well.

The only thing I am not sure about is how to deal with 0 count; I
mean if user explicitly ask for 0 count; the case when count is not
NILP. I have chosen not to deal with it all, I check for zer set
explicit limit for count to be [1,COUNT]. I am not sure if that is best
thing to do; maybe just to return Qnil? I am probably doing something
else wrong, advice apprecaiated. 

I had some problems until I realized i used wrong number converter; I
used fixnum, seems like I need fixnat. I am still not sure if I am
correct but it seems to work now. 

I tested this compared to my old "native" predicate, on GNU/Linux only
and just to run naked predicate on a big number of dirs, and it seems to
be just very slight difference; ~0.002 vs ~0.004 definitely not dramatic
as entire decimal place.

I needed to "touch" 2 other files due to chagned signature of
directory_files: lisp.h and sysdep.c.

In attached .el file are two small tests (I run them with M-:).


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: dired.c.patch --]
[-- Type: text/x-patch, Size: 5123 bytes --]

--- src/dired.c	2020-10-14 03:35:16.781786426 +0200
+++ ../dired2.c	2020-10-14 03:35:05.271568190 +0200
@@ -20,6 +20,7 @@
 
 #include <config.h>
 
+#include <stddef.h>
 #include <sys/stat.h>
 
 #ifdef HAVE_PWD_H
@@ -165,7 +166,7 @@
 Lisp_Object
 directory_files_internal (Lisp_Object directory, Lisp_Object full,
 			  Lisp_Object match, Lisp_Object nosort, bool attrs,
-			  Lisp_Object id_format)
+			  Lisp_Object id_format, Lisp_Object count_to_return)
 {
   if (!NILP (match))
     CHECK_STRING (match);
@@ -223,7 +224,14 @@
 #ifdef WINDOWSNT
   case_table = BVAR (&buffer_defaults, case_canon_table);
 #endif
-
+  
+  ptrdiff_t ind = 0, last = 0;
+  if(!NILP(count_to_return) && FIXNATP(count_to_return))
+      last = XFIXNAT(count_to_return);
+  
+  if(!last)
+    last = 1;
+  
   /* Read directory entries and accumulate them into LIST.  */
   Lisp_Object list = Qnil;
   for (struct dirent *dp; (dp = read_dirent (d, directory)); )
@@ -267,6 +275,13 @@
       else
 	finalname = name;
 
+      if(!NILP(count_to_return) && FIXNATP(count_to_return))
+        {
+          if(ind == last)
+            break;
+          ind ++;
+        }
+      
       list = Fcons (attrs ? Fcons (finalname, fileattrs) : finalname, list);
     }
 
@@ -282,13 +297,13 @@
   if (NILP (nosort))
     list = Fsort (Fnreverse (list),
 		  attrs ? Qfile_attributes_lessp : Qstring_lessp);
-
+  
   (void) directory_volatile;
   return list;
 }
 
 
-DEFUN ("directory-files", Fdirectory_files, Sdirectory_files, 1, 4, 0,
+DEFUN ("directory-files", Fdirectory_files, Sdirectory_files, 1, 5, 0,
        doc: /* Return a list of names of files in DIRECTORY.
 There are three optional arguments:
 If FULL is non-nil, return absolute file names.  Otherwise return names
@@ -296,9 +311,14 @@
 If MATCH is non-nil, mention only file names that match the regexp MATCH.
 If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
  Otherwise, the list returned is sorted with `string-lessp'.
- NOSORT is useful if you plan to sort the result yourself.  */)
+ NOSORT is useful if you plan to sort the result yourself. 
+If COUNT is  non-nil, the function will return max (COUNT,length)
+ files, where length means number of files in directory. Order
+ in which files are returned is not guaranteed and is file system and
+ OS dependent. COUNT has to be an integral number in interval
+ [1,COUNT]. */) 
   (Lisp_Object directory, Lisp_Object full, Lisp_Object match,
-   Lisp_Object nosort)
+   Lisp_Object nosort, Lisp_Object count)
 {
   directory = Fexpand_file_name (directory, Qnil);
 
@@ -306,14 +326,15 @@
      call the corresponding file name handler.  */
   Lisp_Object handler = Ffind_file_name_handler (directory, Qdirectory_files);
   if (!NILP (handler))
-    return call5 (handler, Qdirectory_files, directory,
-                  full, match, nosort);
+    return call6 (handler, Qdirectory_files, directory,
+                  full, match, nosort, count);
 
-  return directory_files_internal (directory, full, match, nosort, false, Qnil);
+  return directory_files_internal (directory, full, match, nosort,
+                                   false, Qnil, count);
 }
 
 DEFUN ("directory-files-and-attributes", Fdirectory_files_and_attributes,
-       Sdirectory_files_and_attributes, 1, 5, 0,
+       Sdirectory_files_and_attributes, 1, 6, 0,
        doc: /* Return a list of names of files and their attributes in DIRECTORY.
 Value is a list of the form:
 
@@ -331,9 +352,14 @@
 ID-FORMAT specifies the preferred format of attributes uid and gid, see
 `file-attributes' for further documentation.
 On MS-Windows, performance depends on `w32-get-true-file-attributes',
-which see.  */)
-  (Lisp_Object directory, Lisp_Object full, Lisp_Object match,
-   Lisp_Object nosort, Lisp_Object id_format)
+which see. 
+If COUNT is  non-nil, the function will return max (COUNT,length)
+ files, where length means number of files in directory. Order
+ in which files are returned is not guaranteed and is file system and
+ OS dependent. COUNT has to be an integral number in interval
+ [1,COUNT]. */)
+(Lisp_Object directory, Lisp_Object full, Lisp_Object match,
+   Lisp_Object nosort, Lisp_Object id_format, Lisp_Object count)
 {
   directory = Fexpand_file_name (directory, Qnil);
 
@@ -342,11 +368,11 @@
   Lisp_Object handler
     = Ffind_file_name_handler (directory, Qdirectory_files_and_attributes);
   if (!NILP (handler))
-    return call6 (handler, Qdirectory_files_and_attributes,
-                  directory, full, match, nosort, id_format);
+    return call7 (handler, Qdirectory_files_and_attributes,
+                  directory, full, match, nosort, id_format, count);
 
   return directory_files_internal (directory, full, match, nosort,
-				   true, id_format);
+				   true, id_format, count);
 }
 
 \f
@@ -929,7 +955,7 @@
   struct stat s;
 
   /* An array to hold the mode string generated by filemodestring,
-     including its terminating space and null byte.  */
+     including its terminating space and NUL byte.  */
   char modes[sizeof "-rwxr-xr-x "];
 
   char *uname = NULL, *gname = NULL;

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: sysdep.c.patch --]
[-- Type: text/x-patch, Size: 534 bytes --]

--- src/sysdep.c	2020-10-13 23:22:37.521367461 +0200
+++ ../sysdep.c	2020-10-13 22:53:04.272682143 +0200
@@ -2892,7 +2892,8 @@
      process.  */
   procdir = build_string ("/proc");
   match = build_string ("[0-9]+");
-  proclist = directory_files_internal (procdir, Qnil, match, Qt, false, Qnil);
+  proclist = directory_files_internal (procdir, Qnil, match, Qt,
+                                       false, Qnil, Qnil);
 
   /* `proclist' gives process IDs as strings.  Destructively convert
      each string into a number.  */

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: lisp.h.patch --]
[-- Type: text/x-patch, Size: 510 bytes --]

--- src/lisp.h	2020-10-13 23:20:23.555386699 +0200
+++ ../lisp.h	2020-10-13 22:47:04.192203245 +0200
@@ -4633,7 +4633,7 @@
 extern void syms_of_dired (void);
 extern Lisp_Object directory_files_internal (Lisp_Object, Lisp_Object,
                                              Lisp_Object, Lisp_Object,
-                                             bool, Lisp_Object);
+                                             bool, Lisp_Object, Lisp_Object);
 
 /* Defined in term.c.  */
 extern int *char_ins_del_vector;

[-- Attachment #5: dired-mark-empty.el --]
[-- Type: text/plain, Size: 2395 bytes --]

(require 'dired)

(defvar nodots "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*")

(defun dired-go-to-first ()
    (interactive)
    (goto-char (point-min))
    (dired-next-line 1)
    (skip-chars-forward " \n\t"))

(defun dired-is-empty-p (directory-name)
  (null (directory-files directory-name nil nodots t 1)))

(defun directory-number-files (directory-name &optional omit-filter)
  (length (directory-files directory-name nil omit-filter t)))

(defun dired-mark-empty-dirs ()
  (interactive)
  (when (equal major-mode 'dired-mode)
    (let ((curr-dir))
      (save-excursion
        (dired-go-to-first)
        
        (while (not (eobp))
          (setq curr-dir (dired-file-name-at-point))
          (cond ((or (null curr-dir)
                     (string= curr-dir ".")
                     (string= curr-dir ".."))
                     ;; do nothing here
                 )
                ((file-directory-p curr-dir)
                 (when (dired-is-empty-p curr-dir)
                   (dired-mark 1)
                   (dired-previous-line 1))))
          (dired-next-line 1))))))

(defun test-1 (dir-name count)
  "Ask for COUNT number of files from directory DIR-NAME."
  (let ((max (length (directory-files dir-name nil nil t)))
        (res (length (directory-files dir-name nil nil t count))))
    (cond ((>= max count)
           (if (= res count)
               (message "passed: asked: %d get: %d number files in dir: %d" count
                        res max)
             (message "not-passed: asked: %s get: %s number files in dir: %s" count
                      res max)))
          ((< max count)
           (if (< res count)
              (message "passed: asked: %d get: %d number files in dir: %d" count
                       res max)
            (message "not-passed: asked: %s get: %s number files in dir: %s" count
                     res max)))
          (t
           (message "Invalid case!")))))

(defun test-2 (dir-name count)
  "Ask for random number of files in interval [1,COUNT] files from every subdir
of directory DIR-NAME."
  (let ((dirs (directory-files dir-name t nodots t)))
    (dolist (curr-dir dirs)
      (when (file-directory-p curr-dir)
        (test-1 curr-dir (+ 1 (random count)))))))

;;(benchmark-run-compiled 10 (dired-is-empty-p "/some/path"))

;; must be in some dired buffer for this
;;(benchmark-run-compiled 10 (dired-mark-empty-dirs))

  parent reply	other threads:[~2020-10-14  1:52 UTC|newest]

Thread overview: 71+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-13  2:22 empty-directory predicate, native implementation Arthur Miller
2020-10-13  8:01 ` Michael Albinus
2020-10-13 11:42   ` Arthur Miller
2020-10-13 13:16     ` Michael Albinus
2020-10-13 18:32       ` Arthur Miller
2020-10-13 18:39         ` Michael Albinus
2020-10-13 23:20           ` Arthur Miller
2020-10-14  9:19             ` Michael Albinus
2020-10-14 13:53               ` Arthur Miller
2020-10-13 14:48 ` Eli Zaretskii
2020-10-13 18:43   ` Arthur Miller
2020-10-13 19:12     ` Eli Zaretskii
2020-10-13 19:59       ` Arthur Miller
2020-10-14 14:08         ` Eli Zaretskii
2020-10-14 14:43           ` Arthur Miller
2020-10-13 18:44   ` Michael Albinus
2020-10-13 19:14     ` Eli Zaretskii
2020-10-13 20:08       ` Arthur Miller
2020-10-14  1:52       ` Arthur Miller [this message]
2020-10-14  9:21         ` Michael Albinus
2020-10-14 13:56           ` Arthur Miller
2020-10-14 14:41             ` Michael Albinus
2020-10-14 15:07               ` Arthur Miller
2020-10-14 15:53                 ` Michael Albinus
2020-10-14 16:12                   ` Eli Zaretskii
2020-10-14 16:21                     ` Michael Albinus
2020-10-14 16:29                       ` Eli Zaretskii
2020-10-15  5:53                         ` Arthur Miller
2020-10-15  9:12                           ` Michael Albinus
2020-10-15 11:33                             ` Arthur Miller
2020-10-15 12:21                               ` Michael Albinus
2020-10-15 13:29                                 ` Arthur Miller
2020-10-15 14:01                                 ` Arthur Miller
2020-10-15 14:41                                   ` Michael Albinus
2020-10-15 15:22                                     ` Arthur Miller
2020-10-16 23:31                                 ` Arthur Miller
2020-10-17  8:13                                   ` Michael Albinus
2020-10-17 19:03                                     ` Arthur Miller
2020-10-17 20:03                                       ` Drew Adams
2020-10-17 20:27                                         ` Arthur Miller
2020-10-17 21:18                                           ` Drew Adams
2020-10-17 22:06                                             ` Arthur Miller
2020-10-17 21:02                                         ` Arthur Miller
2020-10-17 21:27                                           ` Drew Adams
2020-10-17 21:58                                             ` Arthur Miller
2020-10-18 12:06                                               ` Michael Albinus
2020-10-18  2:47                                         ` Eli Zaretskii
2020-10-18 11:52                                       ` Michael Albinus
2020-10-18 16:15                                         ` Drew Adams
2020-10-18 16:43                                           ` Michael Albinus
2020-10-18 20:15                                           ` Stefan Monnier
2020-10-18 21:25                                             ` Drew Adams
2020-10-19  0:03                                           ` Arthur Miller
2020-10-18 22:21                                         ` Arthur Miller
2020-10-19  8:04                                           ` Michael Albinus
2020-10-19 14:01                                             ` Arthur Miller
2020-10-19 14:50                                               ` Michael Albinus
     [not found]                                         ` <VI1PR06MB45266BE5DFC72AEB27567A6C961E0@VI1PR06MB4526.eurprd06.prod.outlook.com>
     [not found]                                           ` <87a6wixoim.fsf@gmx.de>
     [not found]                                             ` <VI1PR06MB4526280D5B81531D06E58BC1961D0@VI1PR06MB4526.eurprd06.prod.outlook.com>
     [not found]                                               ` <87wnzev6i3.fsf@gmx.de>
     [not found]                                                 ` <VI1PR06MB45264E1CB34EECE86672581C96100@VI1PR06MB4526.eurprd06.prod.outlook.com>
2020-11-02 17:02                                                   ` Michael Albinus
2020-11-03 15:20                                                     ` Arthur Miller
2020-10-15 13:38                               ` Stefan Monnier
2020-10-16 23:33                                 ` Arthur Miller
2020-10-14 14:49             ` Arthur Miller
     [not found] <<VI1PR06MB4526ACBABDE795DDD49A5A5896040@VI1PR06MB4526.eurprd06.prod.outlook.com>
     [not found] ` <<83y2ka18t7.fsf@gnu.org>
     [not found]   ` <<87y2kaj799.fsf@gmx.de>
     [not found]     ` <<83blh60wgr.fsf@gnu.org>
     [not found]       ` <<VI1PR06MB452688C9C71D5463D9497A2A96050@VI1PR06MB4526.eurprd06.prod.outlook.com>
     [not found]         ` <<87h7qxjh7g.fsf@gmx.de>
     [not found]           ` <<VI1PR06MB45269B3924B44A555428F00596050@VI1PR06MB4526.eurprd06.prod.outlook.com>
     [not found]             ` <<878sc8kgy8.fsf@gmx.de>
     [not found]               ` <<VI1PR06MB4526FDD3D3EB4867AF837C8F96050@VI1PR06MB4526.eurprd06.prod.outlook.com>
     [not found]                 ` <<87imbcls71.fsf@gmx.de>
     [not found]                   ` <<83eem0zt0b.fsf@gnu.org>
     [not found]                     ` <<87k0vsrd6m.fsf@gmx.de>
     [not found]                       ` <<83a6wozs7h.fsf@gnu.org>
     [not found]                         ` <<VI1PR06MB45267C7D83E77C3F307FF34E96020@VI1PR06MB4526.eurprd06.prod.outlook.com>
     [not found]                           ` <<87sgafq2e2.fsf@gmx.de>
     [not found]                             ` <<AM6PR06MB4518BCD25B93987390D7D6D596020@AM6PR06MB4518.eurprd06.prod.outlook.com>
     [not found]                               ` <<87h7qvptm3.fsf@gmx.de>
     [not found]                                 ` <<VI1PR06MB452605D66CDE84BAA25A257696030@VI1PR06MB4526.eurprd06.prod.outlook.com>
     [not found]                                   ` <<871rhxp8we.fsf@gmx.de>
     [not found]                                     ` <<VI1PR06MB45261F3309D31EC7DEDE4C8B96000@VI1PR06MB4526.eurprd06.prod.outlook.com>
     [not found]                                       ` <<237bd21b-96c7-4433-a5bc-34b64a9f4250@default>
     [not found]                                         ` <<83ft6cs10u.fsf@gnu.org>
2020-10-18  4:05                                           ` Drew Adams
  -- strict thread matches above, loose matches on Subject: below --
2020-10-18 21:13 Drew Adams
2020-10-18 22:15 ` Stefan Monnier
2020-10-19  7:54   ` Michael Albinus
2020-10-19  0:24 ` Arthur Miller
2020-10-19  0:37   ` Drew Adams
2020-10-19  2:15     ` Arthur Miller
2020-10-19  7:51 ` Michael Albinus
2020-10-19 15:25   ` Drew Adams

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=VI1PR06MB452688C9C71D5463D9497A2A96050@VI1PR06MB4526.eurprd06.prod.outlook.com \
    --to=arthur.miller@live.com \
    --cc=eliz@gnu.org \
    --cc=emacs-devel@gnu.org \
    --cc=michael.albinus@gmx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.