Tag
Hash :
7f01591a
Author :
Date :
2006-11-12T17:35:38
Make fts (in FTS_CWDFD mode) more efficient by caching a few open
file descriptors. This also averts a failure on systems with
native openat support when a traversed directory lacks "x" access.
* lib/fts_.h: Include "i-ring.h"
(struct FTS) [fts_fd_ring]: New member.
* lib/fts.c (RESTORE_INITIAL_CWD): Also call fd_ring_clear.
(FCHDIR): Add parentheses.
(fd_ring_check, fd_ring_print) [!FTS_DEBUG]: Define away.
(cwd_advance_fd): Add a 3rd parameter. Adjust all callers.
When descending, rather than simply closing the previous
fts_cwd_fd value, push that file descriptor onto the ring.
(same_fd, fd_ring_print, fd_ring_check) [FTS_DEBUG]: New functions.
(fts_open): Initialize the new fd_ring member.
(fts_close): Clear the ring.
(fts_safe_changedir): When possible, use our new fd_ring to skip
the diropen and fstat and dev/ino comparison that would normally
accompany a virtual `chdir ("..")'.
* modules/fts (Depends-on): Add i-ring.
* modules/i-ring: New module.
* lib/i-ring.c, lib/i-ring.h, lib/i-ring-test.c: New files.
* m4/i-ring.m4: New file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
/* definitions for a simple ring buffer
Copyright (C) 2006 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#include <stdbool.h>
#include "verify.h"
enum { I_RING_SIZE = 4 };
verify (1 <= I_RING_SIZE);
/* When ir_empty is true, the ring is empty.
Otherwise, ir_data[B..F] are defined, where B..F is the contiguous
range of indices, modulo I_RING_SIZE, from back to front, inclusive.
Undefined elements of ir_data are always set to ir_default_val.
Popping from an empty ring aborts.
Pushing onto a full ring returns the displaced value.
An empty ring has F==B and ir_empty == true.
A ring with one entry still has F==B, but now ir_empty == false. */
struct I_ring
{
int ir_data[I_RING_SIZE];
int ir_default_val;
unsigned int ir_front;
unsigned int ir_back;
bool ir_empty;
};
typedef struct I_ring I_ring;
void i_ring_init (I_ring *ir, int ir_default_val);
int i_ring_push (I_ring *ir, int val);
int i_ring_pop (I_ring *ir);
bool i_ring_empty (I_ring const *ir);