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

KindCoveredAll%
expression0214 0.0
branch034 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 "This file defines the describe operator for the 'org.datagraph.spocq' RDF engine."
6
 
7
  (copyright
8
   "Copyright 2010 [james anderson](mailto:james.anderson@setf.de) All Rights Reserved.")
9
 
10
  (:long-description
11
   "The describe query form collects the bindings from the initial result field  as subjects for
12
  a new query, which combines a construct and a bgp to produce the graph for those subjects. To produce
13
  the indirect results, an internal query is constructed to request statements for the generated subjects.
14
 
15
  The response graph is one of the variations on the 'concise bounded descritpion'[1,2] form, whereby the
16
  type of the concrete for is specified by concrete form is specified by *describe-form* and the
17
  respective depth by *describe-subject-depth* and *describe-object-depth*.
18
  ---
19
  [1] : http://www.w3.org/Submission/CBD
20
  [2] : http://patterns.dataincubator.org/book/bounded-description.html
21
  "))
22
    
23
 
24
 
25
 ;;; !!! if the source field is larger than some threshold, and the repository is below some size
26
 ;;; ? use a ratio of the two ?
27
 ;;; then perform the describe as repeated joins with the complete repository ! describe across graphs? !
28
 ;;; where the field has only blank nodes subjects or blank node objects depending on which direction
29
 
30
 (defmethod spocq.e:describe ((source-field matrix-field) subjects)
31
   "Given RESULT-FIELD, a matrix-field or nil, SOURCE-FIELD, a matrix-field, SUBJECTS, a list of
32
     resource identifiers, :START,:END, a slice constraint, :FORM, a discription form, :OBJECT-DEPTH and
33
     :SUBJECT-DEPTH, the respective graph walk limits, generate the combined entity graphs from their
34
     immediate relations and any which are mediated by blank nodes subject to depth and navigation direction
35
     rules.
36
     VALUES : matrix-field : the result graphs
37
 
38
     The entity resources are specified either as explicit literals or designated as variables to be taken as
39
     the bindings in the source solution field.
40
 
41
     The following forms are defined
42
     - dydra:simple-concise-bounded-description
43
     - dydra:inverse-simple-concise-bounded-description
44
     - dydra:symmetric-simple-concise-bounded-description
45
     where the distinction is to as direction. The variations recurse through blank node links
46
     the the depth specified by *describe-subject-depth* and *describe-object-depth*"
47
 
48
   (let ((result-field (make-matrix-field :dimensions *construct-dimensions*)))
49
     (matrix-channel-describe result-field source-field subjects)
50
     result-field))
51
 
52
 
53
 (defmethod process-describe ((subject-source t) (object-source t) 
54
                              (result-field matrix-page-channel)
55
                              (source-field matrix-page-channel)
56
                              base-dimensions subjects)
57
   (matrix-channel-describe subject-source object-source
58
                            result-field source-field subjects))
59
 
60
 ;;; nb. sbcl 1.0.46 compiles a method body twice. the first time, it lacks the declarations.
61
 ;;; thus the autonomous function
62
 (defun matrix-channel-describe (subject-source object-source
63
                                 result-field source-field subjects &key
64
                                 ((:form describe-form) (describe-form))
65
                                 ((:object-depth describe-object-depth) (describe-object-depth))
66
                                 ((:subject-depth describe-subject-depth) (describe-subject-depth)))
67
   
68
   (incf-stat *algebra-operations*)
69
   (let* ((variables (remove-if-not #'variable-p subjects))
70
          (constants (remove-if #'variable-p subjects))
71
          (result-count 0)
72
          (context-term-id (object-term-number '|urn:dydra|:|all|))
73
          (wildcard-term-id (repository-wildcard-term *repository*))
74
          (describe-cache (make-hash-table :test 'equal))
75
          (rest-term-id (object-term-number |rdf|:|rest|))
76
          (%result-data (cffi:null-pointer))
77
          (result-row 0))
78
     (declare (foreign-type (foreign-array #.+matrix-element-type+ (* 3)) %result-data)
79
              (type fixnum result-row))
80
     ;;; special-case rdf list predicates.
81
     (labels ((describe-subject-term-id (term-id &optional (depth describe-subject-depth))
82
                (when (and (or (null depth) (plusp depth))
83
                           (not (eql term-id +null-term-id+))
84
                           (not (< term-id 0)))
85
                  (trace-data process-describe.subject term-id (term-number-object term-id) depth)
86
                  (flet ((do-terms (context subject predicate object)
87
                           (trace-data process-describe.subject.step context subject predicate object (list (term-number-object predicate) depth))
88
                           (when (and (collect-solution subject predicate object)
89
                                      (rdfcache:is-blank object))
90
                             (describe-subject-term-id object (when depth (if (= predicate rest-term-id) depth (1- depth)))))
91
                           t))
92
                    (declare (dynamic-extent #'do-terms))
93
                    (map-repository-statements #'do-terms subject-source term-id wildcard-term-id wildcard-term-id context-term-id))))
94
              (describe-object-term-id (term-id &optional (depth describe-object-depth))
95
                (when (and (or (null depth) (plusp depth))
96
                           (not (eql term-id +null-term-id+))
97
                           (not (< term-id 0)))
98
                  (trace-data process-describe.object term-id (term-number-object term-id) depth)
99
                  (flet ((do-terms (context subject predicate object)
100
                           (trace-data process-describe.obbject.step context subject predicate object (list (term-number-object predicate) depth))
101
                           (when (and (collect-solution subject predicate object)
102
                                      (rdfcache:is-blank subject))
103
                             (describe-object-term-id subject (when depth (if (= predicate rest-term-id) depth (1- depth)))))
104
                           t))
105
                    (declare (dynamic-extent #'do-terms))
106
                    (map-repository-statements #'do-terms object-source wildcard-term-id wildcard-term-id term-id context-term-id))))
107
              (collect-solution (subject predicate object)
108
                (unless (gethash (list subject predicate object) describe-cache)
109
                  (setf (gethash (list subject predicate object) describe-cache) t)
110
                  (setf (values %result-data result-row) (new-field-row result-field))
111
                  (setf (foreign-array-ref %result-data result-row 0) subject
112
                        (foreign-array-ref %result-data result-row 1) predicate
113
                        (foreign-array-ref %result-data result-row 2) object)))
114
              (describe-term (term-number)
115
                (ecase describe-form
116
                  (|urn:dydra|:|simple-concise-bounded-description|
117
                   (describe-subject-term-id term-number))
118
                  (|urn:dydra|:|simple-symmetric-concise-bounded-description|
119
                   (describe-subject-term-id term-number)
120
                   (describe-object-term-id term-number))
121
                  (|urn:dydra|:|simple-inverse-concise-bounded-description|
122
                   (describe-object-term-id term-number)))))
123
       
124
       (loop for constant in constants
125
             for constant-term-number = (object-term-number constant)
126
             do (describe-term constant-term-number))
127
       (let* ((source-dimensions (solution-field-dimensions source-field))
128
              (source-references (loop for dimension in source-dimensions
129
                                       for index from 0
130
                                       when (find dimension variables)
131
                                       collect index))
132
              (%source-data (cffi:null-pointer))
133
              (source-row 0)
134
              (source-row-width (* (length source-dimensions) +matrix-element-size+)))
135
         (loop until (cffi:null-pointer-p (setf (values %source-data source-row) (next-field-row source-field)))
136
               for source-row-offset = (* source-row source-row-width)
137
               do (loop for index in source-references
138
                        for term-number = (sb-sys:sap-ref-64 %source-data (+ source-row-offset (* index +matrix-element-size+)))
139
                        do (describe-term term-number)))
140
         (release-field-data source-field)
141
         (complete-field result-field)
142
         (solution-field-length source-field)
143
         (solution-field-length result-field)))))