Coverage report: /development/source/library/org/datagraph/spocq-shard/src/algebra/matrix-operators/filter.lisp

KindCoveredAll%
expression079 0.0
branch02 0.0
Key
Not instrumented
Conditionalized out
Executed
Not executed
 
Both branches taken
One branch taken
Neither branch taken
1
 ;;; -*- Mode: lisp; Syntax: ansi-common-lisp; Base: 10; Package: org.datagraph.spocq.implementation; -*-
2
 
3
 (in-package :org.datagraph.spocq.implementation)
4
 
5
 (:documentation "sparql filter operation for matrix fields")
6
 
7
 ;;; (load (compile-file "/development/source/library/org/datagraph/spocq/src/algebra/matrix-operators/filter.lisp"))
8
 
9
 
10
 (defmethod spocq.e:filter ((source-field matrix-field) test &rest arguments &key start end)
11
   "filter a field to a result given a source, a filter expression and slice (start, end) specifications."
12
   (declare (ignore start end)
13
            (dynamic-extent arguments))
14
   (let* ((base-dimensions (matrix-field-dimensions source-field))
15
          (length (- (or end (field-length source-field)) (or start 0)))
16
          (%data (rdfcache:make-matrix length (field-width source-field)))
17
          (result-field (clone-matrix-field source-field :data %data))
18
          (operator (apply #'matrix-filter-operator base-dimensions base-dimensions arguments))
19
          (predicate (matrix-unary-predicate-operator (solution-field-dimensions source-field) test)))
20
     (apply operator result-field source-field
21
            predicate
22
            arguments)    
23
     (values result-field
24
             (solution-field-length source-field)
25
             (solution-field-length result-field))))
26
 
27
 (defmethod process-filter ((result-field matrix-page-channel)
28
                            (source-field matrix-page-channel)
29
                            base-dimensions test
30
                            &rest arguments
31
                            &key start end)
32
   (let* ((base-dimensions (field-dimensions source-field))
33
          (operator (apply #'matrix-filter-operator base-dimensions base-dimensions arguments))
34
          (predicate (matrix-unary-predicate-operator base-dimensions test)))
35
     (apply operator result-field source-field
36
            predicate
37
            arguments)    
38
     (values (solution-field-length source-field)
39
             (solution-field-length result-field))))
40
 
41
 
42
 (defun matrix-filter-operator (result-dimensions source-dimensions &rest args)
43
   (declare (dynamic-extent args))
44
   (let ((projection (loop for source-dimension in source-dimensions
45
                           collect (position source-dimension result-dimensions))))
46
     (values (ensure-matrix-operator 'filter :projection projection
47
                                     :result-column-count (length result-dimensions)
48
                                     :slice (not (null args)))
49
             result-dimensions)))
50
 
51
 ;;; (spocq-compile (compute-matrix-operator-lambda 'predicate :dimensions '(?::var1 ?::var2) :test '(= ?::var1 ?::var2)))
52
 
53
 
54
 (defmethod compute-matrix-operator-lambda ((operator (eql 'filter)) &key projection result-column-count (slice nil))
55
   (let* ((source-column-count (length projection)))
56
     `(lambda (result-field source-field predicate ,@(when slice '(&key (start 0) end)))
57
        ,(format nil "filter operator for projection: ~s,~s." projection result-column-count)
58
        (declare (type matrix-field result-field source-field)
59
                 (optimize ,@*field-optimization*)
60
                 ,@(when slice '((type fixnum start))))
61
 
62
        (unless (= (length (solution-field-dimensions result-field)) ,result-column-count)
63
          (matrix-dimension-error :matrix result-field :expected-dimensions '(* ,result-column-count)))
64
        (unless (= (length (solution-field-dimensions source-field)) ,source-column-count)
65
          (matrix-dimension-error :matrix source-field :expected-dimensions '(* ,source-column-count)))
66
        (incf-stat *algebra-operations*)
67
 
68
        (let ((%source-data (cffi::null-pointer))
69
              (%result-data (cffi::null-pointer))
70
              (source-row 0)
71
              (result-row 0))
72
          (declare (foreign-type (foreign-array ,+matrix-element-type+ (* ,source-column-count)) %source-data)
73
                   (foreign-type (foreign-array ,+matrix-element-type+ (* ,result-column-count)) %result-data)
74
                   (type sb-sys:system-area-pointer %source-data %result-data)
75
                   (type fixnum source-row result-row)
76
                   )
77
          (handler-bind ((error (lambda (c)
78
                                  (declare (ignore c))
79
                                  (throw :skip nil))))
80
            (setf (values %source-data source-row) (first-field-row source-field))
81
            (loop ,@(when slice `(with result-count fixnum = 0 until (and end (>= result-count (the fixnum end)))))
82
                  until (cffi:null-pointer-p %source-data)
83
                  do (progn
84
                       (trace-matrix "~&filter.next ~@{~a ~}" :source source-row :result result-row)
85
                       (when (catch :skip (funcall predicate %source-data source-row))
86
                         (,@(if slice
87
                              '(when (> (incf result-count) start))
88
                              '(progn))
89
                          (setf (values %result-data result-row) (new-field-row result-field))
90
                          (trace-matrix "~&distinct.next-result ~@{~a ~}" :source source-row :result result-row
91
                                        ,@(when slice '(:result-count result-count)))
92
                          (project-foreign-solution (%result-data result-row) (%source-data source-row) ',projection)))
93
                       (setf (values %source-data source-row) (next-field-row source-field)))))
94
          result-field))))
95
 
96
 ;;; (spocq-compile (compute-matrix-operator-lambda 'filter :projection '(1 nil 3 2)))
97
 ;;; (spocq-compile (compute-matrix-operator-lambda 'filter :projection '(1 nil 3 2) :slice t))