Improve ranking mechanism

Change-Id: I23add5381ba7099485e5883bebad4997962b82ba
diff --git a/lib/Krawfish/Index/Fields.pm b/lib/Krawfish/Index/Fields.pm
index 59acb8f..fe29b6e 100644
--- a/lib/Krawfish/Index/Fields.pm
+++ b/lib/Krawfish/Index/Fields.pm
@@ -1,7 +1,8 @@
 package Krawfish::Index::Fields;
 use Krawfish::Index::Fields::Doc;
+use Krawfish::Index::Fields::Ranks;
 use Krawfish::Index::Fields::Pointer;
-use Krawfish::Index::Rank::Fields;
+# use Krawfish::Index::Rank::Fields;
 use Krawfish::Log;
 use warnings;
 use strict;
@@ -43,7 +44,8 @@
   my $class = shift;
   bless {
     docs => [],
-    last_doc_id => -1
+    last_doc_id => -1,
+    ranks => {}
   }, $class;
 };
 
@@ -62,7 +64,6 @@
   # TODO:
   #   use Krawfish::Index::Store::V1::Fields->new;
   $self->{docs}->[$self->last_doc_id] = Krawfish::Index::Fields::Doc->new($doc);
-
   return $doc_id;
 };
 
diff --git a/lib/Krawfish/Index/Fields/Doc.pm b/lib/Krawfish/Index/Fields/Doc.pm
index 71e9ddb..109466d 100644
--- a/lib/Krawfish/Index/Fields/Doc.pm
+++ b/lib/Krawfish/Index/Fields/Doc.pm
@@ -35,7 +35,6 @@
     };
   } @$fields;
 
-
   # Add field data
   my @data = ();
   foreach (@sorted_fields) {
@@ -49,6 +48,7 @@
     push @data, $_->value if $_->type eq 'int' || $_->type eq 'store';
   };
 
+
   push @data, 'EOF';
 
   print_log('fields_doc', 'The fields are ' . join(',', map { defined $_ ? $_ : '?' } @data)) if DEBUG;
diff --git a/lib/Krawfish/Index/Fields/Rank.pm b/lib/Krawfish/Index/Fields/Rank.pm
new file mode 100644
index 0000000..7935d09
--- /dev/null
+++ b/lib/Krawfish/Index/Fields/Rank.pm
@@ -0,0 +1,23 @@
+package Krawfish::Index::Fields::Rank;
+use strict;
+use warnings;
+
+sub new {
+  my $class = shift;
+  bless {
+    collation => shift,
+    prefix => [],
+    suffix => [],
+    plain => []
+  }, $class;
+};
+
+
+# Add an entry to the plain list
+sub add {
+  my $self = shift;
+  my ($value, $doc_id) = @_;
+  push @{$self->{plain}}, [$value, $doc_id];
+};
+
+1;
diff --git a/lib/Krawfish/Index/Fields/Ranks.pm b/lib/Krawfish/Index/Fields/Ranks.pm
new file mode 100644
index 0000000..73a85b9
--- /dev/null
+++ b/lib/Krawfish/Index/Fields/Ranks.pm
@@ -0,0 +1,25 @@
+package Krawfish::Index::Fields::Ranks;
+use Krawfish::Index::Fields::Rank;
+use strict;
+use warnings;
+
+sub new {
+  my $class = shift;
+  bless {}, $class;
+};
+
+# Get the rank by
+sub by {
+  my ($self, $field_id) = @_;
+
+  # Field may be ranked or not
+  return $self->{$field_id};
+};
+
+sub introduce_rank {
+  my ($self, $field_id, $collation) = @_;
+  $self->{$field_id} = Krawfish::Index::Fields::Rank->new($collation);
+};
+
+
+1;
diff --git a/lib/Krawfish/Index/Segment.pm b/lib/Krawfish/Index/Segment.pm
index 72cc5ac..03a3d11 100644
--- a/lib/Krawfish/Index/Segment.pm
+++ b/lib/Krawfish/Index/Segment.pm
@@ -1,5 +1,6 @@
 package Krawfish::Index::Segment;
 use Krawfish::Index::Fields;
+use Krawfish::Index::Fields::Ranks;
 use Krawfish::Index::PostingsLive;
 use Krawfish::Index::PostingsList;
 use Krawfish::Index::Forward;
@@ -61,9 +62,9 @@
     $self->{file}
   );
 
-  # $self->{field_ranks} = Krawfish::Index::Fields::Ranks->new(
-  #  $self->{file}
-  #);
+  $self->{field_ranks} = Krawfish::Index::Fields::Ranks->new(
+    $self->{file}
+  );
 
   # Create a list of docid -> uuid mappers
   # This may be problematic as uuids may need to be uint64,
@@ -96,9 +97,9 @@
 
 
 # Alias for last doc
-sub max_rank {
-  $_[0]->{live}->next_doc_id - 1;
-};
+#sub max_rank {
+#  $_[0]->{live}->next_doc_id - 1;
+#};
 
 
 # Get subtokens
@@ -125,6 +126,11 @@
 };
 
 
+sub field_ranks {
+  $_[0]->{field_ranks};
+};
+
+
 # Return a postings list based on a term_id
 sub postings {
   my ($self, $term_id) = @_;
@@ -141,6 +147,7 @@
 };
 
 
+
 # Add a prepared document to the index
 sub add {
   my ($self, $doc) = @_;
@@ -167,19 +174,26 @@
   #   Rank fields!
   # $self->field_ranks();
 
-  # TODO:
-  #   Deal with sortables!
-
   # $self->invert->add()
 
   # Create term index for fields
   my $fields = $doc->fields;
+  my $ranks  = $self->field_ranks;
   foreach (@$fields) {
     next if $_->type eq 'store';
     if (DEBUG) {
       print_log('seg', 'Added field #' . $_->term_id . ' for doc_id=' . $doc_id);
     };
     $self->postings($_->term_id)->append($doc_id);
+
+    # The field is sortable
+    if ($_->sortable) {
+
+      # Add field value to ranking
+      my $ranked_by = $ranks->by($_->key_id);
+
+      $ranked_by->add($_->value, $doc_id) if $ranked_by;
+    };
   };