Thanks, everyone, who's commented so far... here's the plan;

apr_status_t apr_stat(apr_finfo_t *finfo, const char *fname, 
                      apr_int32_t wantthis, apr_pool_t *p)

wantthis is the bit flag of attributes we are interested in.  
Some will always be returned, and the apr_stat function can
always return anything _they comes for free_.  

apr_stat will reply in a new member value, finfo_valid, to 
describe the results returned.  It will only fail for the 
current reasons.  If it can't get a particular result, it 
just goes on, and it's the caller's job to check finfo.valid.

#define APR_FINFO_LINK   0x00000001
#define APR_FINFO_MTIME  0x00000010
#define APR_FINFO_CTIME  0x00000020
#define APR_FINFO_ATIME  0x00000040
#define APR_FINFO_SIZE   0x00000100
#define APR_FINFO_ASIZE  0x00000200
#define APR_FINFO_CSIZE  0x00000400
#define APR_FINFO_DEV    0x00001000
#define APR_FINFO_INODE  0x00002000
#define APR_FINFO_TYPE   0x00008000
#define APR_FINFO_USER   0x00010000 
#define APR_FINFO_GROUP  0x00020000 
#define APR_FINFO_UPROT  0x00100000 
#define APR_FINFO_GPROT  0x00200000
#define APR_FINFO_WPROT  0x00400000
#define APR_FINFO_ICASE  0x01000000  /*  dev is case insensitive */
#define APR_FINFO_FCASE  0x02000000  /*  retrieve filename case */

#define APR_FINFO_MIN    0x00008170  /*  minimal: type, dates and size */
#define APR_FINFO_IDENT  0x00003000  /*  dev and inode */
#define APR_FINFO_OWNER  0x00030000  /*  user and group */
#define APR_FINFO_PROT   0x00700000  /*  all protections */

The first flag, APR_FINFO_LINK, superceeds the apr_lstat call.  If that
flag is set in finfo.valid, the call returned the stat of the link.

On systems that don't support them, dev should then be derived from 
a hash of the mount point and inode should be derived from a hash of
the full pathname.  If they come free, great.  Otherwise we may need
to parse, or cycle through the tree.  Don't ask unless you are willing 
to wait; canonical will walk the whole tree anyways and work these out
in a more optimal fashion.

Same goes for user/group/protections.  Some unices don't support
group concepts at all, and both prot and owner fields get very 
expensive on win32.  Again, if it doesn't matter, don't ask.

The rest should be blatently obvious, except the APR_FINFO_xCASE

The ICASE/FCASE flags should help somewhat to get the proper case
in an optimal fashion.  The fileinfo structure grows char *filespec,
which caches the name that was passed (for free).  If APR_FINFO_FCASE 
is specified, the char *filename member contains the file's name (no 
path).  If the case matched, this is optimized to be the offset into 
filespec.  Just what it does depends on the flags;

user requests neither [they don't care]
  *filename is null

user requests APR_FINFO_ICASE [just asking about the device]
  test dev for case sensitivity, set .valid |= APR_FINFO_ICASE if so
  *filename is null

user requests APR_FINFO_FCASE [doesn't know the case]
  test dev for case sensitivity, set .valid |= APR_FINFO_ICASE if so
  *filename is set to its true case plus .valid |= APR_FINFO_FCASE

user requests APR_FINFO_FCASE && APR_FINFO_ICASE [user remembers the dev]
  if user sets finfo.dev [known to be case insensitive] and dev = finfo.dev 
    we _skip_ the dev case sensitivity test and set .valid |= APR_FINFO_ICASE
  *filename is set to its true case and .valid |= APR_FINFO_FCASE

So this will help optimize any application that has performance issues
and a strong requirement to know the true file name (such as... apache ;-?)

Combinations will impact performance.  Asking on win32 for dev/inode
and the fcase effectively requires two stats.  Ask for just what you
need.

I'm suggesting we add asize (allocated size, e.g. for filesystems
with preallocation) and csize (the actual size consumed on disk.)
Apache may have no application, but other applications may.  These
may not come for free on all platforms.  size itself is the number
of bytes you get when you read the file byte for byte from front
to the end.  asize is the maximum allocated extent.  And csize may
factor compressions, and offset by blocking.  Expensive calculations
if you have to chase down the dev, unknowable on some platforms.

So let's hear it... this should be committed today to get us out of the
mess we are in with Win32.  I'll offer the 'patch' on the first hurrah.

Reply via email to