[Groonga-commit] groonga/grnxx at 6b30e35 [master] Add new arguments output_offset and output_limit to Expression::filter().

Zurück zum Archiv-Index

susumu.yata null+****@clear*****
Wed Aug 20 16:02:06 JST 2014


susumu.yata	2014-08-20 16:02:06 +0900 (Wed, 20 Aug 2014)

  New Revision: 6b30e35406cd61d6564f9102d29d675fb5cb29da
  https://github.com/groonga/grnxx/commit/6b30e35406cd61d6564f9102d29d675fb5cb29da

  Message:
    Add new arguments output_offset and output_limit to Expression::filter().

  Modified files:
    include/grnxx/expression.hpp
    lib/grnxx/expression.cpp

  Modified: include/grnxx/expression.hpp (+22 -2)
===================================================================
--- include/grnxx/expression.hpp    2014-08-20 11:21:55 +0900 (d4d85a4)
+++ include/grnxx/expression.hpp    2014-08-20 16:02:06 +0900 (79c497a)
@@ -80,16 +80,36 @@ class Expression {
     return block_size_;
   }
 
+  // TODO: The following interface is not yet fixed.
+
+//  // Filter out false records.
+//  //
+//  // Evaluates the expression for "*records" and removes records whose
+//  // evaluation results are false.
+//  // Note that the first "offset" records are left without evaluation.
+//  //
+//  // On success, returns true.
+//  // On failure, returns false and stores error information into "*error" if
+//  // "error" != nullptr.
+//  bool filter(Error *error, Array<Record> *records, Int offset = 0);
+
   // Filter out false records.
   //
   // Evaluates the expression for "*records" and removes records whose
   // evaluation results are false.
-  // Note that the first "offset" records are left without evaluation.
+  //
+  // Note that the first "input_offset" records in "*records" are left as is
+  // without evaluation.
+  // Also note that the first "output_offset" true records are removed and
+  // the number of output records is at most "output_limit".
   //
   // On success, returns true.
   // On failure, returns false and stores error information into "*error" if
   // "error" != nullptr.
-  bool filter(Error *error, Array<Record> *records, Int offset = 0);
+  bool filter(Error *error, Array<Record> *records,
+              Int input_offset = 0,
+              Int output_offset = 0,
+              Int output_limit = numeric_limits<Int>::max());
 
   // Extract true records.
   //

  Modified: lib/grnxx/expression.cpp (+47 -5)
===================================================================
--- lib/grnxx/expression.cpp    2014-08-20 11:21:55 +0900 (ae619d8)
+++ lib/grnxx/expression.cpp    2014-08-20 16:02:06 +0900 (bbcbd5f)
@@ -2194,12 +2194,54 @@ DataType Expression::data_type() const {
   return root_->data_type();
 }
 
-bool Expression::filter(Error *error, Array<Record> *records, Int offset) {
-  ArrayRef<Record> output_records = records->ref();
-  if (!filter(error, *records, &output_records)) {
-    return false;
+//bool Expression::filter(Error *error, Array<Record> *records, Int offset) {
+//  ArrayRef<Record> output_records = records->ref();
+//  if (!filter(error, *records, &output_records)) {
+//    return false;
+//  }
+//  return records->resize(error, output_records.size());
+//}
+
+bool Expression::filter(Error *error,
+                        Array<Record> *records,
+                        Int input_offset,
+                        Int output_offset,
+                        Int output_limit) {
+  ArrayCRef<Record> input = records->ref(input_offset);
+  ArrayRef<Record> output = records->ref(input_offset);
+  Int count = 0;
+  while ((input.size() > 0) && (output_limit > 0)) {
+    Int next_size = (input.size() < block_size_) ? input.size() : block_size_;
+    ArrayCRef<Record> next_input = input.ref(0, next_size);
+    ArrayRef<Record> next_output = output.ref(0, next_size);
+    if (!root_->filter(error, next_input, &next_output)) {
+      return false;
+    }
+    input = input.ref(next_size);
+
+    if (output_offset > 0) {
+      if (output_offset >= next_output.size()) {
+        output_offset -= next_output.size();
+        next_output = next_output.ref(0, 0);
+      } else {
+        for (Int i = output_offset; i < next_output.size(); ++i) {
+          next_output.set(i - output_offset, next_output[i]);
+        }
+        next_output = next_output.ref(0, next_output.size() - output_offset);
+        output_offset = 0;
+      }
+    }
+    if (next_output.size() > output_limit) {
+      next_output = next_output.ref(0, output_limit);
+    }
+    output_limit -= next_output.size();
+
+    output = output.ref(next_output.size());
+    count += next_output.size();
   }
-  return records->resize(error, output_records.size());
+  records->resize(nullptr, input_offset + count);
+  return true;
+
 }
 
 bool Expression::filter(Error *error,
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Zurück zum Archiv-Index