]> git.donarmstrong.com Git - biopieces.git/blobdiff - code_perl/Maasha/KISS/IO.pm
KISS browser working, but slow
[biopieces.git] / code_perl / Maasha / KISS / IO.pm
index 15f4292e11fda994d635f582456a22b83bd513d6..4c3ac1498dc85292acc8f56ec8e6c95b2544b45b 100644 (file)
@@ -31,6 +31,7 @@ package Maasha::KISS::IO;
 use warnings;
 use strict;
 use Data::Dumper;
+use Maasha::Common;
 use Maasha::Filesys;
 use Maasha::SQL;
 use vars qw( @ISA @EXPORT );
@@ -155,7 +156,7 @@ sub kiss_sql_get
     my ( $sql, $entries );
 
     # $sql = "SELECT * FROM $table WHERE S_BEG >= $s_beg AND S_END <= $s_end ORDER BY S_BEG,S_END";
-    $sql = "SELECT S_BEG,S_END,ALIGN FROM $table WHERE S_BEG >= $s_beg AND S_END <= $s_end";
+    $sql = "SELECT S_BEG,S_END,Q_ID,ALIGN FROM $table WHERE S_BEG >= $s_beg AND S_END <= $s_end";
 
     $entries = Maasha::SQL::query_hashref_list( $dbh, $sql );
 
@@ -163,6 +164,143 @@ sub kiss_sql_get
 }
 
 
+sub kiss_index
+{
+    # Martin A, Hansen, October 2009.
+
+    # Creates an index of a sorted KISS file that
+    # allowing the location of the byte position
+    # from where records can be read given a
+    # specific S_BEG position. The index consists of
+    # triples: [ beg, end, bytepos ], where beg and
+    # end denotes the interval where the next KISS
+    # record begins at bytepos.
+
+    my ( $fh,   # filehandle to KISS file
+       ) = @_;
+
+    # Returns a list.
+
+    my ( $line, @fields, $beg, $end, $pos, @index );
+
+    $beg = 0;
+    $pos = 0;
+
+    while ( $line = <$fh> )
+    {
+        chomp $line;
+
+        @fields = split /\t/, $line, 3;
+        
+        $end = $fields[ S_BEG ];
+
+        if ( $end == 0 )
+        {
+            push @index, [ $beg, $end, $pos ];
+            $beg = 1;
+        }
+        elsif ( $end > $beg )
+        {
+            push @index, [ $beg, $end - 1, $pos ];
+            $beg = $end;
+        }
+        elsif( $end < $beg )
+        {
+            Maasha::Common::error( qq(KISS file not sorted: $end < $beg) );
+        }
+
+        $pos += 1 + length $line;
+    }
+
+    return wantarray ? @index : \@index;
+}
+
+
+sub kiss_index_store
+{
+    my ( $path,
+         $index,
+       ) = @_;
+
+    Maasha::Filesys::file_store( $path, $index );
+}
+
+
+sub kiss_index_retrieve
+{
+    my ( $path,
+       ) = @_;
+
+    my $index;
+
+    $index = Maasha::Filesys::file_retrieve( $path );
+
+    return wantarray ? @{ $index } : $index;
+}
+
+
+sub kiss_index_search
+{
+    my ( $index,
+         $num,
+       ) = @_;
+
+    # Returns a number.
+
+    my ( $high, $low, $try );
+
+    $low  = 0;
+    $high = scalar @{ $index };
+
+    while ( $low <= $high )
+    {
+        $try = int( ( $high + $low ) / 2 );
+    
+        # print "low: $low   high: $high   try: $try\n";
+        
+        if ( $num < $index->[ $try ]->[ 0 ] ) {
+            $high = $try;
+        } elsif ( $num > $index->[ $try ]->[ 1 ] ) {
+            $low = $try + 1;
+        } else {
+            return $index->[ $try ]->[ 2 ];
+        }
+    }
+
+    Maasha::Common::error( "Could not find number->$num in index" );
+}
+
+
+sub kiss_index_get
+{
+    my ( $file,
+         $beg,
+         $end,
+       ) = @_;
+
+    my ( $index, $offset, $fh, $entry, @entries );
+
+    $index = Maasha::KISS::IO::kiss_index_retrieve( "$file.index" );
+
+    $offset = Maasha::KISS::IO::kiss_index_search( $index, $beg );
+
+    $fh = Maasha::Filesys::file_read_open( $file );
+
+    sysseek( $fh, $offset, 0 );
+
+    while ( $entry = kiss_entry_get( $fh ) )
+    {
+        push @entries, $entry;
+
+        last if $entry->{ 'S_END' } > $end;
+    }
+
+    close $fh;
+
+    return wantarray ? @entries : \@entries;
+}
+
+
 sub kiss2biopiece
 {
     my ( $entry,   # KISS entry