in reply to What is the perl equivelant to a 'Set' column type in mysql?

Actually, I dont think that does excatly what I want to do -- but it is the right topic.

I have a set of music genres that a band can be: rock, pop, jazz, metal, etc -- the set is longer, but finite.

I have several bands, and want to compute a storable value for each band relating to the genres that they span (ie, a jazzy rock band).

So, I need to basically contruct a 2 functions - one that takes the list of genres for a band and returns a storable number/string based on a reference set of available generes, and another that does the reverse.

Does this make sense? I basically want to replicate the functionality of mysql in this regard, so I'm not tied to using them as a backend datastore.
  • Comment on Re: What is the perl equivelant to a 'Set' column type in mysql?

Replies are listed 'Best First'.
Re: Re: What is the perl equivelant to a 'Set' column type in mysql?
by sgifford (Prior) on Apr 30, 2004 at 22:16 UTC
    What MySQL basically does is assign each set value a number, then uses those numbers to set and clear bits in an integer. For example:
    use constant GENRE_ROCK => 0; use constant GENRE_POP => 1; use constant GENRE_JAZZ => 2; use constant GENRE_METAL => 3; use constant GENRE_LAST => 3; sub pack_set { my $bits == 0; foreach my $genre (@_) { $bits |= (1<<$genre); } $bits; } sub unpack_set { my($bits)=@_; my @ret = (); my $i = 0; while ($bits) { if ($bits & 1) { push(@ret,$i); } $i++; $bits >>= 1; } @ret; } my $ella = pack_set(GENRE_POP, GENRE_JAZZ); warn "Packed set is $ella\n"; print "Ella's Genres: "; foreach my $genre (unpack_set($ella)) { $genre == GENRE_ROCK and print "rock "; $genre == GENRE_POP and print "pop "; $genre == GENRE_JAZZ and print "jazz "; $genre == GENRE_METAL and print "metal "; } print "\n";

    Storing the numbers in a hash instead of with constants would make it easier to print them.

      Small logic nit. The set bits are 0 1 2 4 8.... In your example a jazzy pop band would be a metal entity as well as a last....It is also worth noting that you can only rely on 31-32 (sign bit) genres unless you can guarantee long 64 bit ints.

      cheers

      tachyon

        I think you missed the part where I used the sequential numbers as a count for which bits to set or check; if not please elaborate, as I don't see the bug. In fact, the example I gave is a jazzy pop singer, and it works properly.

        Using powers of 2 for the constants is a good idea, though; I just thought it would be easier to explain this way.

      awesome -- I knew thats the logic behind how mysql did it, I just didn't know the way it processed it you rock. like a hurricane.