Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Incrementing characters

by legLess (Hermit)
on Sep 06, 2001 at 20:09 UTC ( [id://110609]=perlquestion: print w/replies, xml ) Need Help??

legLess has asked for the wisdom of the Perl Monks concerning the following question:

Monks ~

My CGI script is going to accept uploaded files and then put them somewhere. I don't want to overload one directory, so I'm using a three-level structure: "a/aa/aaa" to "z/zz/zzz". This way no directory has over 26 sub directories, no directory has more than $MAX (constant) files, and there are 26^3 possible directories.

my( $p1, $p2, $p3 ); # path parts, each one character, from database my( $count ); # number of directory items, from database if( $count > $DIR_MAX_ENTRIES ) { if( $p3 eq 'z' ) { $p3 = 'a'; if( $p2 eq 'z' ) { $p2 = 'a'; $p1 = chr( ord( $p1) + 1 ); } else { $p2 = chr( ord( $p2) + 1 ); } } else { $p3 = chr( ord( $p3) + 1 ); } }
It works as expected, with two caveats:
  1. If the first character passes 'z' it barfs. This is fine: if we ever approach 'z' then the system will need redesign for other reasons.
  2. '$count' may be susceptible to a race condition, since it's a stored number rather than an actual count of directory entries. This is fine: it's not meant to be high-precision, and $MAX will be low enough that some slop is ok.
Finally, though, I wonder if there's a faster or simpler way to do this. I'd thought about using an array of characters (rather than 'ord()' and 'chr()') and incrementing the subscript. This wouldn't eliminate the 'if eq z' check, though, just change its form and move it a bit.

Any advice from the monks? Thanks!
--
man with no legs, inc.

Replies are listed 'Best First'.
Re: Incrementing characters
by davorg (Chancellor) on Sep 06, 2001 at 20:15 UTC
Re: Incrementing characters
by bbfu (Curate) on Sep 06, 2001 at 20:16 UTC

    $var = "aaa"; ++$var; # or: $var++ print "Var is: $var\n"; __END__ Var is: aab

    Ah, the magic of Perl.

    Update: D'oh. davorg++ for speed. ;-)

    Update2: Oh, and just to make sure that it's clear: ($var = "az")++; $var == "ba";

    bbfu
    Seasons don't fear The Reaper.
    Nor do the wind, the sun, and the rain.
    We can be like they are.

Re: Incrementing characters
by andye (Curate) on Sep 06, 2001 at 20:56 UTC
    You could use a hash...
    my %h=map{$_++ => $_}('a'..'z'); $h{'z'}='a';
    gives you a hash which looks like this:
    a => b b => c c => d d => e e => f f => g g => h h => i i => j j => k k => l l => m m => n n => o o => p p => q q => r r => s s => t t => u u => v v => w w => x x => y y => z z => a
    andy.
Re: Incrementing characters
by George_Sherston (Vicar) on Sep 06, 2001 at 21:13 UTC
    Do you insist that your sub-sub-directory name has three characters? If not, then
    $s = $p1.$p2.$p3; $s++; $s =~ /(.*)(.{1})(.{1})/; ($p1,$p2,$p3) = ($1,$2,$3);
    Will generate an endless stream of path parts, with the added advantage you don't have to rewrite when you get to z/z/z because it goes straight on to aa/a/a.

    § George Sherston
Re: Incrementing characters
by John M. Dlugosz (Monsignor) on Sep 07, 2001 at 03:35 UTC
    If you're using NTFS you don't have to worry about "overloading a directory". (overloading Explorer when you browse it, maybe...) but in my application I have thousands of files in one dir and it's simple and elegant.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://110609]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (8)
As of 2024-04-25 11:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found