Coverage report: /development/source/library/org/datagraph/spocq-shard/src/store/field.lisp
| Kind | Covered | All | % |
| expression | 216 | 405 | 53.3 |
| branch | 18 | 34 | 52.9 |
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 "fields"
6
"data manipulation for solution fields")
10
(defun term-number-statements (repository-handle quad-or-triple-data &key (skolemize (skolemize-insertions-p)) (context nil))
11
"Project a field of symbolic terms into one which is expressed in term numbers.
12
Handle special cases which cannot appear in the store:
13
- preclude null terms,
14
- map wildcard graph terms to their true term numbers
15
- permit statements as either tagged
27
(labels ((map-node (node)
28
(rest (or (assoc node node-map)
29
(first (push (cons node (cons-global-blank-node))
33
((nil :undef) (error "term-number-statements: invalid term: ~s." term))
34
(|urn:dydra|:|all| *true-all-context-term-number*)
35
(|urn:dydra|:|default| *true-default-context-term-number*)
36
(|urn:dydra|:|named| *true-named-context-term-number*)
37
(t (cond ((undistinguished-variable-p term)
38
(repository-object-term-number repository-handle (map-node term)))
39
((spocq:blank-node-p term)
41
(repository-object-term-number repository-handle (map-node term))
42
(repository-object-term-number repository-handle term)))
44
(repository-object-term-number repository-handle term))
46
(error "Invalid term: ~s." term)))))))
47
(let ((default-graph-id (when context (map-term context) #xffffffff)))
48
(flet ((intern-triples (triples) ;; as quads _or_ triples
50
(let ((field (make-page (length triples) 4)))
51
(loop for statement in triples
52
for (s p o) = (triple-terms statement)
54
do (setf (aref field index 0) (map-term s)
55
(aref field index 1) (map-term p)
56
(aref field index 2) (map-term o)
57
(aref field index 2) default-graph-id))
59
(let ((field (make-page (length triples) 3)))
60
(loop for statement in triples
61
for (s p o) = (triple-terms statement)
63
do (setf (aref field index 0) (map-term s)
64
(aref field index 1) (map-term p)
65
(aref field index 2) (map-term o)))
68
(let ((field (make-page (length cspos) 4)))
69
(loop for statement in cspos
70
for (c s p o) = (quad-terms statement)
72
;;!!! rdf 1.1 intends to allow blank nodes for graph terms
73
;;!!! a. optionally skolemize
74
;;!!! b. exclude other than iri and blank node
75
do (progn (setf (aref field index 0) (map-term s)
76
(aref field index 1) (map-term p)
77
(aref field index 2) (map-term o)
78
;; don't map, as no blank node allowed, but allow for truncated quad
79
(aref field index 3) (repository-context-term-number repository-handle c))))
82
(let ((field (make-page (length quads) 4)))
83
(loop for statement in quads
84
for (s p o c) = (quad-terms statement)
86
do (progn (setf (aref field index 0) (map-term s)
87
(aref field index 1) (map-term p)
88
(aref field index 2) (map-term o)
89
;; don't map, as no blank node allowed, but allow for truncated quad
90
(aref field index 3) (repository-context-term-number repository-handle c))))
93
(destructuring-bind (graph triples) (rest form)
94
(let ((field (make-page (length triples) 4))
95
;; no blank node allowed
96
(graph-id (repository-object-term-number repository-handle graph)))
97
(loop for statement in triples
98
for (s p o) = (triple-terms statement)
100
;; place in the same order an sexp-quad
101
do (setf (aref field index 0) (map-term s)
102
(aref field index 1) (map-term p)
103
(aref field index 2) (map-term o)
104
(aref field index 3) graph-id))
106
(if (graph-form-p quad-or-triple-data)
107
(push quad-or-triple-data graphs)
108
(dolist (expression quad-or-triple-data)
109
(cond ((graph-form-p expression)
110
(push expression graphs))
111
((triple-form-p expression)
112
(push expression triples))
113
((quad-form-p expression)
114
(push expression quads))
116
(push expression cspos))
118
(error "Invalid statement: ~s." expression)))))
119
(let ((interned (append (when triples (list (intern-triples (reverse triples))))
120
(when quads (list (intern-quads (reverse quads))))
121
(when cspos (list (intern-cspos (reverse cspos))))
122
(mapcar #'intern-graph (reverse graphs)))))
123
(values (if (rest interned)
124
(coerce interned 'vector)
128
(defmethod intern-quad-or-triple-data ((repository rdfcache-repository) quad-or-triple-data &rest args)
129
(declare (dynamic-extent args))
130
(apply #'term-number-statements repository quad-or-triple-data args))
132
(defmethod repository-intern-statements ((repository rdfcache-repository) quad-or-triple-data &rest args)
133
(declare (dynamic-extent args))
134
(apply #'term-number-statements repository quad-or-triple-data args))
136
(defmethod repository-intern-statements ((transaction rdfcache-transaction) quad-or-triple-data &rest args)
137
(declare (dynamic-extent args))
138
(apply #'term-number-statements transaction quad-or-triple-data args))
140
(defun term-number-field (solution-data &key (skolemize (skolemize-insertions-p))
141
(field-length (length solution-data))
142
(field-width (length (first solution-data)))
143
(field (make-page field-length field-width))
146
;; if no transaction is present, just the persistent terms will bind
147
(context-id (context-term-number context)))
148
(labels ((map-node (node)
149
(rest (or (assoc node node-map)
150
(first (push (cons node (cons-global-blank-node))
153
(cond ((member term '(nil :undef))
155
((undistinguished-variable-p term)
156
(object-term-number (map-node term)))
157
((spocq:blank-node-p term)
159
(object-term-number (map-node term))
160
(object-term-number term)))
162
(object-term-number term)))))
164
(loop for solution in solution-data
165
for solution-index from 0
166
do (loop for term in solution
167
for term-index from 0 below field-width
168
do (setf (aref field solution-index term-index)
170
finally (case term-index
171
(3 ) ;; already a quad
172
(2 ;; augment triple with default graph id
173
(when (= field-width 4)
174
(setf (aref field solution-index term-index) context-id))))))
177
(defgeneric term-value-field (solution-data)
178
(:documentation "Transform a term-number matrix/array into the object-solution field,
179
that is a list of solutions")
180
(:method ((solution-data array))
181
(let* ((field-length (array-dimension solution-data 0))
182
(field-width (array-dimension solution-data 1)))
183
(loop for solution-index from 0 below field-length
184
collect (loop for term-index from 0 below field-width
185
collect (term-number-object (aref solution-data solution-index term-index))))))
186
(:method ((datum integer))
187
(term-number-object datum))
189
(:method ((datum t)) datum)
192
(:method ((matrix sb-sys:system-area-pointer))
193
(let ((numeric-field (rdfcache:matrix-to-list matrix)))
194
(term-value-field (make-array (list (length numeric-field) (length (first numeric-field)))
195
:initial-contents numeric-field))))
197
(:method ((datum matrix-field))
198
(let ((solutions (solution-field-solutions datum)))
199
(unless (cffi:null-pointer-p solutions)
200
(let ((numeric-field (subseq (rdfcache:matrix-to-list solutions)
201
0 (solution-field-row-count datum))))
202
(term-value-field (make-array (list (length numeric-field) (length (first numeric-field)))
203
:initial-contents numeric-field))))))
205
(:method ((generator solution-generator))
206
(let ((channel (abstract-field-generator-channel generator))
207
(dimensions (abstract-field-generator-dimensions generator))
209
(do-pages (page channel)
210
(push (term-value-field page) results))
211
(values (reduce #'nconc (nreverse results) :from-end t)
216
(defun transaction-intern-shuffeled-field (transaction solution-data from-dimensions to-dimensions &key (skolemize (skolemize-insertions-p))
217
(from-field-width (length (first solution-data)))
218
(to-field-width (length to-dimensions))
219
(field (make-page (length solution-data) to-field-width))
221
(assert (or partial (null (set-exclusive-or from-dimensions to-dimensions))) ()
222
"invalid shuffle dimensions ~a -> ~a" from-dimensions to-dimensions)
224
;; if no transaction is present, just the persistent terms will bind
225
(x-record (when transaction (transaction-record transaction))))
226
(labels ((map-node (node)
227
(rest (or (assoc node node-map)
228
(first (push (cons node (cons-global-blank-node :transaction x-record))
232
((nil :undef) (error "transaction-intern-shuffeled-field: invalid term: ~s." term))
233
(|urn:dydra|:|all| *true-all-context-term-number*)
234
(|urn:dydra|:|default| *true-default-context-term-number*)
235
(|urn:dydra|:|named| *true-named-context-term-number*)
237
(cond ((undistinguished-variable-p term)
238
(rdfcache-object-term-number x-record (map-node term)))
239
((spocq:blank-node-p term)
241
(rdfcache-object-term-number x-record (map-node term))
242
(rdfcache-object-term-number x-record term)))
244
(rdfcache-object-term-number x-record term)))))))
245
(loop with map = (loop for from in from-dimensions
246
collect (position from to-dimensions))
247
for solution in solution-data
248
for solution-index from 0
249
do (progn (assert (= (length solution) from-field-width) ()
250
"Inconsistent solution (@~d not x ~d): ~s."
251
solution-index from-field-width solution)
252
(loop for term in solution
253
for term-index in map
255
do (setf (aref field solution-index term-index)