Coverage report: /development/source/library/org/datagraph/spocq-shard/src/store/rlmdb/repository-streaming-filtered.lisp

KindCoveredAll%
expression0192 0.0
branch016 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.rdf.lmdb.implementation)
4
 
5
 (:documentation "LMDB repository multi-revision streaming w/filter
6
  LMDB-based bgp processing relies on this as the quad source when the bgp includes
7
  filter expressions for temporal attributes.")
8
 
9
   
10
 
11
 (defgeneric rlmdb:map-repository-statements-filtered (operator index-db quad-pattern filter)
12
   (:documentation
13
    "For the case where a temporal expression is supplied as a filter predicate,
14
     delegate to an index as for the simple bounded case and then map the given
15
     operator across those statements which match the quad pattern and for which
16
     the respective presence map satisfies the predicate
17
 
18
     operator : (function (%quad . list) t)
19
     index-db : (delegate rlmdb:index-database)
20
     quad-pattern : (or spocq:quad (simple-vector 4))
21
     filter : (function (simple-vector function) boolean)
22
            ; invokes the function upon success with the arguments to be supplied to the mapped operator
23
     values : integer")
24
 
25
   (:method (operator (id string) quad-pattern filter)
26
     (rlmdb:map-repository-statements-filtered operator (spocq.i:repository id) quad-pattern filter))
27
 
28
   (:method (operator (repository spocq.i:lmdb-repository) quad-pattern filter)
29
     (rlmdb:map-repository-statements-filtered operator (spocq.i:repository-lmdb-repository repository)
30
                                      quad-pattern
31
                                      filter))
32
 
33
   (:method (operator (revision spocq.i::lmdb-revision) (quad-pattern t) filter)
34
     (rlmdb:map-repository-statements-filtered operator (spocq.i:repository-lmdb-repository revision)
35
                                      quad-pattern
36
                                      filter))
37
 
38
   (:method (operator (transaction spocq.i:lmdb-transaction) (quad-pattern t) filter)
39
     (rlmdb:map-repository-statements-filtered operator (spocq.i::transaction-revision transaction)
40
                                      quad-pattern
41
                                      filter))
42
 
43
   (:method (operator (repository rlmdb:repository) quad-pattern filter)
44
     (lmdb:with-transaction ((transaction  (lmdb:make-transaction repository :flags liblmdb:+rdonly+))
45
                             :initial-disposition :begin :normal-disposition :abort)
46
       ;; no graph database support
47
       (let ((index-database (repository-quad-pattern-index repository quad-pattern)))
48
         (rlmdb:map-repository-statements-filtered operator index-database quad-pattern filter)))))
49
 
50
 
51
 (defmethod rlmdb:map-repository-statements-filtered (operator (index rlmdb:index-database) (quad-pattern t) filter)
52
   (lmdb:with-database (index)
53
     (let* ((cur (lmdb:make-cursor index :transaction lmdb:*transaction*))
54
            (named-only (case (graph quad-pattern)
55
                          ((-2 |urn:dydra|:|named|) t)
56
                          (t nil)))
57
            (quad-map (quad-pattern-key-map quad-pattern))
58
            ;; find the position which maps tot he graph term
59
            (quad-graph-index (position 0 quad-map :test #'=))
60
            (wild-pattern-p (wild-quad-pattern-p quad-pattern))
61
            ;;(interval-vector (make-array 16 :adjustable t :fill-pointer 0))
62
            (match-count 0)
63
            (scan-count 0)
64
            (version-map (spocq.i::make-foreign-ordinal-map :vector (cffi:null-pointer))))
65
       (cffi:with-foreign-objects ((%quad-pattern '(:struct rdfcache::quad))
66
                                   (%key-quad '(:struct rdfcache::quad))
67
                                   (%result-quad '(:struct rdfcache::quad)))
68
         (lmdb::with-empty-value (raw-key)
69
           (lmdb::with-empty-value (raw-value)
70
             (flet ((map-for-graph (quad-pattern)
71
                      ;;(print :let)
72
                      (incf spocq.i::*match-requests*)
73
                      (quad-to-quad-record quad-pattern %quad-pattern)
74
                      (copy-quad-record %quad-pattern %key-quad)
75
                      ;;(print :initial)
76
                      ;;(%print-quad %quad-pattern *trace-output*)
77
                      ;;(%print-quad %key-quad *trace-output*)
78
                      (lmdb:with-cursor (cur)
79
                        (let ((%cursor (lmdb::handle cur))
80
                              (visibility-unit (cffi:foreign-type-size :uint32)))
81
                        (labels ((get-quad (get-op)
82
                                   ;(lmdb::with-empty-value (raw-key)
83
                                   ;(lmdb::with-empty-value (raw-value)
84
                                   (ecase get-op
85
                                     (:+set-range+
86
                                      (setf (cffi:foreign-slot-value raw-key '(:struct liblmdb:val) 'liblmdb:mv-size) (cffi:make-pointer 16)
87
                                            (cffi:foreign-slot-value raw-key '(:struct liblmdb:val) 'liblmdb:mv-data) %key-quad)
88
                                      ;; (%print-quad %key-quad *trace-output*)
89
                                      )
90
                                     (:+next+ ))
91
                                   ;;(print :key-quad *trace-output*)
92
                                   ;;(%print-quad %key-quad *trace-output*)
93
                                   (let ((return-code (liblmdb:cursor-get %cursor
94
                                                                          raw-key
95
                                                                          raw-value
96
                                                                          get-op)))
97
                                     ;; (print (list quad-pattern return-code))
98
                                     (alexandria:switch (return-code)
99
                                                        (0
100
                                                         (incf scan-count)
101
                                                         (call-with-quad-entry raw-key raw-value))
102
                                                        (liblmdb:+notfound+
103
                                                         nil)
104
                                                        (t
105
                                                         (lmdb::unknown-error return-code)))))
106
                                 (call-with-quad-entry (k v)
107
                                   ;;(print :call-with-quad-entry)
108
                                   (assert (= 16 (%mdb-val-size k))
109
                                           ()
110
                                           "key size is invalid: ~s" (%mdb-val-size k))
111
                                   (let* ((%index-quad (%mdb-val-data k))
112
                                          (visibility-bytes (%mdb-val-size v))
113
                                          (visibility-count (if (plusp visibility-bytes) (/ visibility-bytes visibility-unit) 0)))
114
                                     ;; continue until either no longer matched or the operator returns nil
115
                                     ;; (print (list :no named-only :qm quad-map :qgi quad-graph-index :g (cffi:mem-aref %index-quad 'term-id quad-graph-index)))
116
                                     ;; (%print-quad %index-quad *trace-output*)
117
                                     (cond ((and named-only (= (cffi:mem-aref %index-quad 'term-id quad-graph-index) #xffffffff))
118
                                            ;; skip
119
                                            t)
120
                                           ((or wild-pattern-p (%quad-match-p %quad-pattern %index-quad)) ;; iff still in range
121
                                            (if (zerop visibility-count) ; not revisioned, should not be here
122
                                                (if (map-repository-statements-filtered-callback operator
123
                                                                                                 (term-number-key-to-term-number-quad %index-quad %result-quad quad-map)
124
                                                                                                 nil nil)
125
                                                    (incf match-count)
126
                                                    (return-from call-with-quad-entry nil))
127
                                                (flet ((continue-with-success (first last)
128
                                                         ;; success values augment the quad to be bound in the bgp
129
                                                         ;; continuation control is left to continue
130
                                                         (unless (map-repository-statements-filtered-callback operator
131
                                                                                                              (term-number-key-to-term-number-quad %index-quad %result-quad quad-map)
132
                                                                                                              first last)
133
                                                           ;; terminate iff caller indicates to stop
134
                                                           (return-from call-with-quad-entry nil))))
135
                                                  (declare (dynamic-extent #'continue-with-success))
136
                                                  #+(or)
137
                                                  (setf interval-vector (decode-visibility-record interval-vector
138
                                                                                                  (%mdb-val-data v)
139
                                                                                                  visibility-count))
140
                                                  (setf (spocq.i::foreign-ordinal-map-vector version-map) (%mdb-val-data v)
141
                                                        (spocq.i::foreign-ordinal-map-length version-map) visibility-count)
142
                                                  (when (filter-matched-statements filter #'continue-with-success version-map)
143
                                                    (incf match-count))
144
                                                  ;; if within match set always return t unless callback terminates prematurely
145
                                                  t)))
146
                                           ;; otherwise end
147
                                           (t nil)))))
148
                      (loop for op = :+set-range+ then :+next+
149
                        while (get-quad op)))))))
150
               (typecase (graph quad-pattern)
151
                 (cons (loop with single-graph-quad-pattern = (copy-quad-pattern quad-pattern)
152
                         for graph in (graph quad-pattern)
153
                         do (progn (setf (graph single-graph-quad-pattern) graph)
154
                              (map-for-graph single-graph-quad-pattern))))
155
                 (t (when named-only
156
                      (setf (graph quad-pattern) 0))
157
                    (map-for-graph quad-pattern)))))))
158
       ;;; should hapen in bgp processor (incf spocq.i::*match-responses* match-count)
159
       (values scan-count match-count))))
160
 
161
 
162
 (defun rlmdb.i::map-repository-statements-filtered-callback (operator quad first last)
163
   #+(or)
164
   (when cl-user::*map-repository-statements-callback.verbose*
165
     (let ((quad-string (with-output-to-string (stream) (spocq.i::%print-quad quad stream))))
166
       (format *trace-output* "mrs: ~a" quad-string)
167
       ;(spocq.i::log-warn "mrs: ~a" quad-string)
168
       ))
169
   ;; (incf spocq.i::*match-responses*)
170
   (funcall operator quad first last))
171
 
172
 
173
 (defun rlmdb.i::filter-matched-statements (filter continue map)
174
   ;(print (list :c continue :m map)) (finish-output )
175
   ;(break)
176
   (funcall filter continue map))
177