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))
next prev 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.