All:
I was going to suggest Tie::SortHash as a possible solution to this node requesting help when sorting hashes, but decided not to. I looked under the hood and saw that it was using deprecated pseudo hashes. It has been nearly three years since this module was touched. I have contacted Casey, the author, to see if they plan on updating it. I would like to see one of three two things happen:
  • Casey update the module, possibly with input
  • I take over maintenance of the module
  • I upload a new module that does the same thing only more

    I have enclosed my proposed first draft of code as well as some comparisons with the original. Please provide your feedback on the code as well as any other advice that might be helpful.

    package Tie::SortHash; use strict; use constant HASH => 0; use constant LOOKUP => 1; use constant ARRAY => 2; use constant SORT => 3; use constant CHANGED => 4; use vars qw($VERSION); $VERSION = '1.02'; sub TIEHASH { my $class = shift; my $hash = shift || {}; my $sort = shift || q($a cmp $b || $a <=> $b); my $self = bless [], $class; $self->_Build($hash, $sort); return $self; } sub FETCH { my($self, $key) = @_; $self->[HASH]{$key}; } sub STORE { my($self, $key, $value) = @_; $self->[HASH]{$key} = $value; $self->[CHANGED] = 1; } sub EXISTS { my($self, $key) = @_; return exists $self->[HASH]{$key}; } sub DELETE { my($self, $key) = @_; delete $self->[HASH]{$key}; splice(@{$self->[ARRAY]}, $self->[LOOKUP]{$key}, 1); delete $self->[LOOKUP]{$key}; } sub FIRSTKEY { my $self = shift; $self->_ReOrder if $self->[CHANGED]; $self->_Iterate; } sub NEXTKEY { my ($self, $lastkey) = @_; $self->_ReOrder if $self->[CHANGED]; $self->_Iterate($self->[LOOKUP]{$lastkey}); } sub CLEAR { my $self = shift; $self->[HASH] = {}; $self->[CHANGED] = 1; } sub DESTROY { } sub _Build { my ($self, $hash, $sort) = @_; @{$self->[HASH]}{keys %$hash} = values %$hash; $self->sortblock($sort); $self->_ReOrder; } sub _ReOrder { my $self = shift; $self->[LOOKUP] = (); $self->[ARRAY] = (); my $index = 0; my $hash = $self->[HASH]; for my $key (eval $self->[SORT]) { $self->[LOOKUP]{$key} = $index; $self->[ARRAY][$index] = $key; $index++; } $self->[CHANGED] = 0; } sub _Iterate { my ($self, $index) = @_; $index = -1 unless defined $index; $index++; defined $self->[ARRAY][$index] ? $self->[ARRAY][$index] : undef; } sub sortblock { my($self, $sort) = @_; my $hash = $self->[HASH]; $sort =~ s/\$hash/\$hash->/g; $self->[SORT] = "sort { $sort } keys %\$hash"; eval $self->[SORT]; die $@ if $@; $self->[CHANGED] = 1; } 1;

    Comparisons
  • Original uses pseudo hashes, proposed replacement does not
  • Original sorts hash every time each/keys/values is called. Proposed only when needed.
  • Both modules use eval to allow arbitrary sort routines
  • Original module should be much slower
  • Original module should consume far less memory
  • Original uses a manual form of garbage collection for delete, proposed module does not.
  • Requested Feedback
  • Code critique
  • Provide a way to prefer saving memory over speed
  • Get rid of the eval - not sure if possible
  • If anyone is using the original, does the proposed module continue to work? If yes, is it faster?
  • A better test suite
  • With the choice of memory/speed - how can it be optimized to be most efficient for either one
  • Thanks in advance. I will by flying to Dallas tomorrow (10 Aug 03), so I apologize in advance for not being able to reply immediately.

    Cheers - L~R


    In reply to RFC - inplace upgrade for Tie::SortHash by Limbic~Region

    Title:
    Use:  <p> text here (a paragraph) </p>
    and:  <code> code here </code>
    to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.