Ken Williams

NAME

Tie::LLHash.pm - ordered hashes

DESCRIPTION

This class implements an ordered hash-like object. It's a cross between a Perl hash and a linked list. Use it whenever you want the speed and structure of a Perl hash, but the orderedness of a list.

Don't use it if you want to be able to address your hash entries by number, like you can in a real list ($list[5]).

See also Tie::IxHash by Gurusamy Sarathy. It's similar (it also does ordered hashes), but it has a different internal data structure and a different flavor of usage. IxHash stores its data internally as both a hash and an array in parallel. LLHash stores its data as a bidirectional linked list, making both inserts and deletes very fast. IxHash therefore makes your hash behave more like a list than LLHash does. This module keeps more of the hash flavor.

SYNOPSIS

 use Tie::LLHash;
 
 # A new empty ordered hash:
 tie (%hash, "Tie::LLHash");
 # A new ordered hash with stuff in it:
 tie (%hash2, "Tie::LLHash", key1=>$val1, key2=>$val2);
 # Allow easy insertions at the end of the hash:
 tie (%hash2, "Tie::LLHash", {lazy=>1}, key1=>$val1, key2=>$val2);
 
 # Add some entries:
 (tied %hash)->first('the' => 'hash');
 (tied %hash)->insert('here' => 'now', 'the'); 
 (tied %hash)->first('All' => 'the');
 (tied %hash)->insert('are' => 'right', 'the');
 (tied %hash)->insert('things' => 'in', 'All');
 (tied %hash)->last('by' => 'gum');

 $value = $hash{'things'}; # Look up a value
 $hash{'here'} = 'NOW';    # Set the value of an EXISTING RECORD!
 
 
 $key = (tied %hash)->key_before('in');  # Returns the previous key
 $key = (tied %hash)->key_after('in');   # Returns the next key
 
 # Luxury routines:
 $key = (tied %hash)->current_key;
 $val = (tied %hash)->current_value;
 (tied %hash)->next;
 (tied %hash)->prev;
 (tied %hash)->reset;

 # If lazy-mode is set, new keys will be added at the end.
 $hash{newkey} = 'newval';
 $hash{newkey2} = 'newval2';

METHODS

  • insert(key, value, previous_key)

    This inserts a new key-value pair into the hash right after the previous_key key. If previous_key is undefined (or not supplied), this is exactly equivalent to first(key, value). If previous_key is defined, then it must be a string which is already a key in the hash - otherwise we'll croak().

  • first(key, value) (or) first()

    Gets or sets the first key in the hash. Without arguments, simply returns a string which is the first key in the database. With arguments, it inserts a new key-value pair at the beginning of the hash.

  • last(key, value) (or) last()

    Gets or sets the last key in the hash. Without arguments, simply returns a string which is the last key in the database. With arguments, it inserts a new key-value pair at the end of the hash.

  • key_before(key)

    Returns the name of the key immediately before the given key. If no keys are before the given key, returns undef.

  • key_after(key)

    Returns the name of the key immediately after the given key. If no keys are after the given key, returns undef.

  • current_key()

    When iterating through the hash, this returns the key at the current position in the hash.

  • current_value()

    When iterating through the hash, this returns the value at the current position in the hash.

  • next()

    Increments the current position in the hash forward one item. Returns the new current key, or undef if there are no more entries.

  • prev()

    Increments the current position in the hash backward one item. Returns the new current key, or undef if there are no more entries.

  • reset()

    Resets the current position to be the start of the order. Returns the new current key, or undef if there are no keys.

ITERATION TECHNIQUES

Here is a smattering of ways you can iterate over the hash. I include it here simply because iteration is probably important to people who need ordered data.

 while (($key, $val) = each %hash) {
    print ("$key: $val\n");
 }
 
 foreach $key (keys %hash) {
    print ("$key: $hash{$key}\n");
 }
 
 my $obj = tied %hash;  # For the following examples

 $key = $obj->reset;
 while (exists $hash{$key}) {
    print ("$key: $hash{$key}\n");
    $key = $obj->next;
 }

 $obj->reset;
 while (exists $hash{$obj->current_key}) {
    $key = $obj->current_key;
    print ("$key: $hash{$key}\n");
    $obj->next;
 }

WARNINGS

  • Unless you're using lazy-mode, don't add new elements to the hash by simple assignment, a la <$hash{$new_key} = $value>, because LLHash won't know where in the order to put the new element.

TO DO

I could speed up the keys() routine in a scalar context if I knew how to sense when NEXTKEY is being called on behalf of keys(). Not sure whether this is possible.

I may also want to add a method for... um, I forgot. Something.

AUTHOR

Ken Williams <ken@forum.swarthmore.edu>

Copyright (c) 1998 Swarthmore College. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 389:

You forgot a '=back' before '=head1'




Hosting generously
sponsored by Bytemark