Coverage report: /development/source/library/org/datagraph/spocq-shard/src/algebra/matrix-operators/extend.lisp
| Kind | Covered | All | % |
| expression | 0 | 156 | 0.0 |
| branch | 0 | 8 | 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; -*-
3
(in-package :org.datagraph.spocq.implementation)
5
(:documentation "sparql slice operation for matrix fields")
7
;;; (load (compile-file "/development/source/library/org/datagraph/spocq/src/algebra/matrix-operators/slice.lisp"))
9
(defmethod spocq.e:extend ((source-field matrix-field) bindings &rest arguments &key start end)
10
(declare (dynamic-extent arguments))
11
(let* ((base-dimensions (matrix-field-dimensions source-field))
12
(length (- (or end (field-length source-field)) (or start 0)))
13
(result-dimensions (loop for binding in bindings
14
collect (if (consp binding) (first binding) binding)))
15
(width (length result-dimensions))
16
(%data (rdfcache:make-matrix length width))
17
(result-field (clone-matrix-field source-field :data %data
18
:dimensions result-dimensions
19
:sort-dimensions (loop for dimension in (matrix-field-sort-dimensions source-field)
20
when (find dimension result-dimensions)
22
(operator (apply #'matrix-extend-operator result-dimensions base-dimensions
23
(loop for binding in bindings
27
(apply operator result-field source-field
32
(defmethod process-extend ((destination matrix-page-channel)
33
(source matrix-page-channel)
34
result-dimensions base-dimensions bindings
37
(end (when count (+ count (or start 0)))))
38
(declare (ignore start end))
39
(let ((operator (matrix-extend-operator result-dimensions base-dimensions bindings)))
40
(funcall operator destination source
41
:start start :end end))
42
(values (channel-solution-count destination)
43
(channel-solution-count source)))
46
;;;!!! still need to abstract the extend operator
47
;;; first cache any computed values - if there is an error, skip
48
;;; then perform a term-number projection, computed from the result side to move just the identity values
49
;;; then move the computed values
51
(defun matrix-extend-operator (result-dimensions source-dimensions bindings &rest args)
52
(declare (dynamic-extent args))
54
(let* ((bindings-dimensions (bindings-variables bindings))
55
(rebound-variables (intersection bindings-dimensions source-dimensions)))
56
(when *strict-extend-bindings*
57
;; See [http://www.w3.org/TR/sparql11-query/#sparqlGrammar] wrt restrictions.
58
(assert (null rebound-variables) ()
59
"The variables are already bound: ~a" rebound-variables))
60
(let* ((projection (loop for source-dimension in source-dimensions
61
collect (when source-dimension (position source-dimension result-dimensions))))
62
(all-dimensions (union-dimensions (union-dimensions result-dimensions source-dimensions) bindings-dimensions))
63
(dimension-map (loop for count from 0
64
for dimension in all-dimensions
65
collect (cons dimension (cons-symbol *variable-package* "v" (princ-to-string count)))))
66
(generic-result-dimensions (sublis dimension-map result-dimensions))
67
(generic-source-dimensions (sublis dimension-map source-dimensions))
68
(generic-bindings (sublis dimension-map bindings)))
69
(values (ensure-matrix-operator 'extend :projection projection
70
:source-dimensions generic-source-dimensions
71
:result-dimensions generic-result-dimensions
72
:bindings generic-bindings
73
:slice (not (null args)))
77
(defmethod compute-matrix-operator-lambda ((operator (eql 'extend))
78
&key projection source-dimensions result-dimensions bindings slice)
79
(let* ((source-column-count (length projection))
80
(result-column-count (length result-dimensions))
81
(referenced-dimensions (expression-variables (mapcar #'rest bindings))))
82
`(lambda (result-field source-field ,@(when slice '(&key (start 0) end)))
83
,(format nil "extend operator for projection: ~s; extension: ~s." projection bindings)
84
(declare (type matrix-field result-field source-field)
85
(optimize ,@*field-optimization*)
86
,@(when slice '((type fixnum start))))
88
(unless (= (channel-page-width result-field) ,result-column-count) ()
89
(matrix-dimension-error :matrix result-field :expected-dimensions '(* ,result-column-count)))
90
(unless (= (channel-page-width source-field) ,source-column-count) ()
91
(matrix-dimension-error :matrix source-field :expected-dimensions '(* ,source-column-count)))
92
(incf-stat *algebra-operations*)
94
(let ((%source-data (cffi::null-pointer))
95
(%result-data (cffi::null-pointer))
98
(declare (foreign-type (foreign-array ,+matrix-element-type+ (* ,source-column-count)) %source-data)
99
(foreign-type (foreign-array ,+matrix-element-type+ (* ,result-column-count)) %result-data)
100
(type sb-sys:system-area-pointer %source-data %result-data)
101
(type fixnum source-row result-row)
103
(handler-bind ((error (lambda (c)
104
(log-trace "extend raised condition: ~a" c)
106
(loop ,@(when slice '(with result-count fixnum = 0 until (and end (>= result-count (the fixnum end)))))
107
until (cffi:null-pointer-p (setf (values %source-data source-row) (next-field-row source-field)))
108
,@(when slice '(when (> (incf result-count) start)))
109
do (let ,(loop for variable in referenced-dimensions
110
for position = (position variable source-dimensions)
111
collect (list variable `(foreign-array-named-object-ref ,variable %source-data source-row ,position)))
113
(let* ,(loop for (variable expression) in bindings
114
collect `(,variable (locally (declare (optimize (speed 0) (safety 3))) ,expression)))
115
;; when the extension computation succeeds
116
(setf (values %result-data result-row) (new-field-row result-field))
117
(trace-matrix "~&extend.next-result ~@{~a ~}" :source source-row :result result-row
118
,@(when slice '(:result-count result-count)))
119
,@(loop for variable in source-dimensions
120
for source-position from 0
121
for result-position = (position variable result-dimensions)
123
collect `(setf (foreign-array-ref %result-data result-row ,result-position)
124
(foreign-array-ref %source-data source-row ,source-position)))
125
,@(loop for (variable nil) in bindings
126
for result-position = (position variable result-dimensions)
127
collect `(setf (foreign-array-named-object-ref ,variable %result-data result-row ,result-position) ,variable)))))))
128
(complete-field result-field)
132
;;; (spocq-compile (compute-matrix-operator-lambda 'extend :projection '(1 nil 3 2) :result-dimensions '(?::a ?::d ?::q ?::s) :source-dimensions '(?::a ?::s ?::d) :bindings '((?::q (spocq.a:+ ?::a ?::s))) :slice t))