Cache docvecs to reduce memory footprint

Change-Id: I985b9935b2f7cc41583f93250b8202cdcd3cd10c
diff --git a/lib/KorAP/VirtualCorpus/Doc.pm b/lib/KorAP/VirtualCorpus/Doc.pm
index e635d3d..dff1ee4 100644
--- a/lib/KorAP/VirtualCorpus/Doc.pm
+++ b/lib/KorAP/VirtualCorpus/Doc.pm
@@ -3,6 +3,9 @@
 use warnings;
 use base 'KorAP::VirtualCorpus';
 
+# TODO:
+# Maybe replaceble with DocVec
+
 # Constructor
 sub new {
   my $class = shift;
@@ -76,7 +79,6 @@
   return $self->{value};
 };
 
-
 # Stringify fragment
 sub _to_fragment {
   my $self = shift;
diff --git a/lib/KorAP/VirtualCorpus/DocVec.pm b/lib/KorAP/VirtualCorpus/DocVec.pm
index 49fefb8..ae7aefb 100644
--- a/lib/KorAP/VirtualCorpus/DocVec.pm
+++ b/lib/KorAP/VirtualCorpus/DocVec.pm
@@ -29,6 +29,12 @@
   return $self->{value};
 };
 
+# Add value;
+sub add {
+  my $self = shift;
+  push @{$self->{value}}, shift;
+};
+
 # Stringify fragment
 sub _to_fragment {
   my $self = shift;
@@ -37,8 +43,12 @@
   $json .= '"type":"type:' . $self->type . '",';
   $json .= '"match":"match:' . $self->match . '",';
   $json .= '"key":"' . $self->key . '",';
-  $json .= '"value":[' . join(',', map { $self->quote($_) } @{$self->value}) . ']';
-
+  if (@{$self->value} == 1) {
+    $json .= '"value":'.$self->quote($self->value->[0]);
+  }
+  else {
+    $json .= '"value":[' . join(',', map { $self->quote($_) } @{$self->value}) . ']';
+  };
   # Set at the end, when all comments are done
   $json .= $self->_commentparam_to_string;
   return $json . '}';
diff --git a/lib/KorAP/VirtualCorpus/Group.pm b/lib/KorAP/VirtualCorpus/Group.pm
index 4062cf9..bcdc95c 100644
--- a/lib/KorAP/VirtualCorpus/Group.pm
+++ b/lib/KorAP/VirtualCorpus/Group.pm
@@ -14,7 +14,8 @@
   bless {
     # New try
     ops => undef,
-    type => undef
+    type => undef,
+    field_ops => {}
   }, $class;
 };
 
@@ -26,6 +27,7 @@
   $clone->{ops} = [@{$self->{ops}}] if $self->{ops};
   $clone->{type} = $self->{type};
   $clone->{name} = $self->{name};
+  $clone->{field_ops} = {};
   bless $clone, __PACKAGE__;
 };
 
@@ -105,11 +107,20 @@
 # Define a field that should be "or"ed
 sub union_field {
   my $self = shift;
-  my $field = shift;
+  my $key = shift;
   my $value = shift;
-  $self->union(
-    KorAP::VirtualCorpus::Doc->new($field)->value($value)
-  );
+
+  my $field = $self->{field_ops}->{$key};
+
+  if ($field) {
+    $field->add($value)
+  } else {
+    my $vec = KorAP::VirtualCorpus::DocVec
+      ->new($key)
+      ->value($value);
+    $self->union($vec);
+    $self->{field_ops}->{$key} = $vec;
+  };
 };
 
 # Define an operand to be "and"ed
@@ -153,6 +164,12 @@
   $self->joint($doc);
 };
 
+sub DESTROY {
+  my $self = shift;
+  foreach (keys %{$self->{field_ops}}) {
+    delete $self->{field_ops}->{$_};
+  };
+};
 
 1;