mas01cr@511
|
1 (in-package "SB-ADB")
|
mas01cr@511
|
2
|
mas01cr@511
|
3 (defclass adb ()
|
mas01cr@511
|
4 ((alien :initarg alien)))
|
mas01cr@511
|
5 (defmethod initialize-instance :after ((o adb) &key)
|
mas01cr@511
|
6 (when (and (slot-boundp o 'alien)
|
mas01cr@511
|
7 (not (null-alien (slot-value o 'alien))))
|
mas01cr@511
|
8 (let ((alien (slot-value o 'alien)))
|
mas01cr@511
|
9 (sb-ext:finalize o (lambda () (%close alien))))))
|
mas01cr@511
|
10
|
mas01cr@511
|
11 ;;; FIXME: deal with interrupt-safety / leak issues
|
mas01cr@511
|
12
|
mas01cr@511
|
13 ;;; FIXME: if-does-not-exist.
|
mas01cr@511
|
14 (defun open (path &key (direction :input) (if-exists :error) (adb-class 'adb))
|
mas01cr@511
|
15 (flet ((direction-flag (direction)
|
mas01cr@511
|
16 (ecase direction
|
mas01cr@511
|
17 ((:input :probe) sb-posix:o-rdonly)
|
mas01cr@511
|
18 ((:output :io) sb-posix:o-rdwr))))
|
mas01cr@511
|
19 (let* ((truepath (probe-file path))
|
mas01cr@511
|
20 (alien (cond
|
mas01cr@511
|
21 (truepath
|
mas01cr@511
|
22 (ecase direction
|
mas01cr@511
|
23 ((:input :probe)
|
mas01cr@511
|
24 (%%open path (direction-flag direction)))
|
mas01cr@511
|
25 ((:output :io)
|
mas01cr@511
|
26 (case if-exists
|
mas01cr@511
|
27 (:error (error "database already exists: ~S" path))
|
mas01cr@511
|
28 (:append (%open path (direction-flag direction)))
|
mas01cr@511
|
29 ;; FIXME: not the best implementation of
|
mas01cr@511
|
30 ;; :SUPERSEDE semantics ever.
|
mas01cr@511
|
31 (:supersede (delete-file path) (%create path 0 0 0))))))
|
mas01cr@511
|
32 ((eql direction :input)
|
mas01cr@511
|
33 (error "database does not exist: ~S" path))
|
mas01cr@511
|
34 (t (%create path 0 0 0)))))
|
mas01cr@511
|
35 (cond
|
mas01cr@511
|
36 ((null-alien alien)
|
mas01cr@511
|
37 (case direction
|
mas01cr@511
|
38 (:probe nil)
|
mas01cr@511
|
39 (t (error "opening database failed: ~S" path))))
|
mas01cr@511
|
40 (t (make-instance adb-class 'alien alien))))))
|
mas01cr@511
|
41 (defmethod close ((o adb))
|
mas01cr@511
|
42 (when (and (slot-boundp o 'alien)
|
mas01cr@511
|
43 (not (null-alien (slot-value o 'alien))))
|
mas01cr@511
|
44 (%close (slot-value o 'alien))
|
mas01cr@511
|
45 (sb-ext:cancel-finalization o)
|
mas01cr@511
|
46 (slot-makunbound o 'alien)))
|
mas01cr@511
|
47 (defmacro with-adb ((adb path &rest open-args &key direction adb-class if-exists)
|
mas01cr@511
|
48 &body body)
|
mas01cr@511
|
49 (declare (ignore direction adb-class if-exists))
|
mas01cr@511
|
50 `(let ((,adb (open ,path ,@open-args)))
|
mas01cr@511
|
51 (unwind-protect
|
mas01cr@511
|
52 (locally ,@body)
|
mas01cr@511
|
53 (close ,adb))))
|
mas01cr@511
|
54
|
mas01cr@511
|
55 (defgeneric l2norm (db))
|
mas01cr@511
|
56 (defmethod l2norm ((db adb))
|
mas01cr@511
|
57 (%l2norm (slot-value db 'alien)))
|
mas01cr@511
|
58
|
mas01cr@511
|
59 (defstruct (datum
|
mas01cr@511
|
60 (:constructor %make-datum)
|
mas01cr@511
|
61 (:constructor
|
mas01cr@511
|
62 make-datum
|
mas01cr@511
|
63 (key %data &key times power
|
mas01cr@511
|
64 &aux (data
|
mas01cr@511
|
65 (make-array (list (length %data) (length (elt %data 0)))
|
mas01cr@511
|
66 :element-type 'double-float
|
mas01cr@511
|
67 :initial-contents %data)))))
|
mas01cr@511
|
68 (key (error "missing argument") :type string)
|
mas01cr@511
|
69 (data (error "missing argument") :type (simple-array double-float (* *)))
|
mas01cr@511
|
70 (times nil :type (or null (simple-array double-float)))
|
mas01cr@511
|
71 (power nil :type (or null (simple-array double-float))))
|
mas01cr@511
|
72
|
mas01cr@511
|
73 (defgeneric insert (datum db))
|
mas01cr@511
|
74
|
mas01cr@511
|
75 (defmethod insert ((datum datum) (db adb))
|
mas01cr@511
|
76 (let* ((data (datum-data datum))
|
mas01cr@511
|
77 (nvectors (array-dimension data 0))
|
mas01cr@511
|
78 (dim (array-dimension data 1)))
|
mas01cr@511
|
79 (when (datum-times datum)
|
mas01cr@511
|
80 (unless (= (array-total-size (datum-times datum)) (* 2 nvectors))
|
mas01cr@511
|
81 (error "dimension mismatch for times: ~S" datum)))
|
mas01cr@511
|
82 (when (datum-power datum)
|
mas01cr@511
|
83 (unless (= (array-total-size (datum-power datum)) nvectors)
|
mas01cr@511
|
84 (error "dimension mismatch for power: ~S" datum)))
|
mas01cr@511
|
85 (with-alien ((d adb-datum-t))
|
mas01cr@511
|
86 (sb-sys:with-pinned-objects ((datum-data datum)
|
mas01cr@511
|
87 (datum-times datum)
|
mas01cr@511
|
88 (datum-power datum))
|
mas01cr@511
|
89 (setf (slot d 'dim) dim)
|
mas01cr@511
|
90 (setf (slot d 'nvectors) nvectors)
|
mas01cr@511
|
91 (setf (slot d 'key) (datum-key datum))
|
mas01cr@511
|
92 (setf (slot d 'data)
|
mas01cr@511
|
93 (sb-sys:vector-sap (sb-ext:array-storage-vector (datum-data datum))))
|
mas01cr@511
|
94 (if (datum-times datum)
|
mas01cr@511
|
95 (setf (slot d 'times) (sb-sys:vector-sap (sb-ext:array-storage-vector (datum-times datum))))
|
mas01cr@511
|
96 (setf (slot d 'times) nil))
|
mas01cr@511
|
97 (if (datum-power datum)
|
mas01cr@635
|
98 (setf (slot d 'power) (sb-sys:vector-sap (sb-ext:array-storage-vector (datum-power datum))))
|
mas01cr@511
|
99 (setf (slot d 'power) nil))
|
mas01cr@511
|
100 (sb-int:with-float-traps-masked (:invalid)
|
mas01cr@511
|
101 (%insert-datum (slot-value db 'alien) (addr d)))))))
|
mas01cr@580
|
102
|
mas01cr@580
|
103 (defgeneric retrieve (key db))
|
mas01cr@580
|
104
|
mas01cr@580
|
105 (defmethod retrieve ((key string) (db adb))
|
mas01cr@580
|
106 ;; KLUDGE: this does multiple copies of the floating point data:
|
mas01cr@580
|
107 ;; once within audiodb_retrieve_datum(), and once from the alien to
|
mas01cr@580
|
108 ;; the lisp arrays. Oh well.
|
mas01cr@580
|
109 (with-alien ((d adb-datum-t))
|
mas01cr@580
|
110 (setf (slot d 'times) nil
|
mas01cr@580
|
111 (slot d 'power) nil)
|
mas01cr@580
|
112 (%retrieve-datum (slot-value db 'alien) key (addr d))
|
mas01cr@580
|
113 (let* ((dim (slot d 'dim))
|
mas01cr@580
|
114 (nvectors (slot d 'nvectors))
|
mas01cr@580
|
115 (data (make-array (list nvectors dim) :element-type 'double-float))
|
mas01cr@580
|
116 (vector (sb-ext:array-storage-vector data))
|
mas01cr@580
|
117 ;; FIXME: this shares KEY
|
mas01cr@580
|
118 (datum (%make-datum :key key :data data)))
|
mas01cr@580
|
119 (sb-kernel:system-area-ub64-copy (alien-sap (slot d 'data)) 0
|
mas01cr@580
|
120 (sb-sys:vector-sap vector) 0
|
mas01cr@580
|
121 (* dim nvectors))
|
mas01cr@580
|
122 (unless (null-alien (slot d 'times))
|
mas01cr@580
|
123 (let ((times (make-array nvectors :element-type 'double-float)))
|
mas01cr@580
|
124 (sb-kernel:system-area-ub64-copy (alien-sap (slot d 'times)) 0
|
mas01cr@580
|
125 (sb-sys:vector-sap times) 0
|
mas01cr@580
|
126 nvectors)
|
mas01cr@580
|
127 (setf (datum-times datum) times)))
|
mas01cr@580
|
128 (unless (null-alien (slot d 'power))
|
mas01cr@580
|
129 (let ((power (make-array nvectors :element-type 'double-float)))
|
mas01cr@580
|
130 (sb-kernel:system-area-ub64-copy (alien-sap (slot d 'power)) 0
|
mas01cr@580
|
131 (sb-sys:vector-sap power) 0
|
mas01cr@580
|
132 nvectors)
|
mas01cr@580
|
133 (setf (datum-power datum) power)))
|
mas01cr@580
|
134 (%free-datum (slot-value db 'alien) (addr d))
|
mas01cr@580
|
135 datum)))
|
mas01cr@511
|
136
|
mas01cr@511
|
137 (defstruct result
|
mas01cr@511
|
138 (key "" :type string)
|
mas01cr@511
|
139 (distance 0d0 :type double-float)
|
mas01cr@511
|
140 (qpos 0 :type (and unsigned-byte fixnum))
|
mas01cr@511
|
141 (ipos 0 :type (and unsigned-byte fixnum)))
|
mas01cr@511
|
142
|
mas01cr@511
|
143 ;;; Hrm. To copy (from the malloc heap) or not to copy? Copying
|
mas01cr@511
|
144 ;;; would make things generally easier, I guess, and we have to hope
|
mas01cr@511
|
145 ;;; that the order of magnitude is not such that the copying causes
|
mas01cr@511
|
146 ;;; pain.
|
mas01cr@511
|
147 (defclass results (sequence standard-object)
|
mas01cr@511
|
148 ())
|
mas01cr@511
|
149 (defclass copied-query-results (results)
|
mas01cr@511
|
150 ((results :initarg results :accessor %copied-results)))
|
mas01cr@511
|
151 (defmethod print-object ((o copied-query-results) s)
|
mas01cr@511
|
152 (pprint-logical-block (s nil)
|
mas01cr@511
|
153 (print-unreadable-object (o s :type t)
|
mas01cr@511
|
154 (format s "(~D results):~2I~@:_" (length o))
|
mas01cr@511
|
155 (sequence:dosequence (r o)
|
mas01cr@511
|
156 (pprint-pop)
|
mas01cr@511
|
157 (format s "~A ~6,3e ~D ~D~@:_"
|
mas01cr@511
|
158 (result-key r) (result-distance r)
|
mas01cr@511
|
159 (result-qpos r) (result-ipos r))))))
|
mas01cr@511
|
160
|
mas01cr@511
|
161 (defmethod sequence:length ((o copied-query-results))
|
mas01cr@511
|
162 (length (%copied-results o)))
|
mas01cr@511
|
163 (defmethod sequence:elt ((o copied-query-results) index)
|
mas01cr@511
|
164 (elt (%copied-results o) index))
|
mas01cr@511
|
165 (defmethod (setf sequence:elt) (new-value (o copied-query-results) index)
|
mas01cr@511
|
166 (setf (elt (%copied-results o) index) new-value))
|
mas01cr@511
|
167 (defmethod sequence:make-sequence-like
|
mas01cr@511
|
168 ((o copied-query-results) length &rest args
|
mas01cr@511
|
169 &key initial-element initial-contents)
|
mas01cr@511
|
170 (declare (ignore initial-element initial-contents))
|
mas01cr@511
|
171 (let ((vector (apply #'make-array length args)))
|
mas01cr@511
|
172 (make-instance 'copied-query-results 'results vector)))
|
mas01cr@511
|
173 (defmethod sequence:adjust-sequence
|
mas01cr@511
|
174 ((o copied-query-results) length &rest args
|
mas01cr@511
|
175 &key initial-element initial-contents)
|
mas01cr@511
|
176 (declare (ignore initial-element initial-contents))
|
mas01cr@511
|
177 (let ((results (%copied-results o)))
|
mas01cr@511
|
178 (apply #'sequence:adjust-sequence results length args))
|
mas01cr@511
|
179 o)
|
mas01cr@511
|
180
|
mas01cr@511
|
181 (defclass proxied-query-results (results)
|
mas01cr@511
|
182 ((adb :initarg adb)
|
mas01cr@511
|
183 (spec :initarg spec)
|
mas01cr@511
|
184 (results :initarg results)))
|
mas01cr@511
|
185 (defmethod initialize-instance :after ((o proxied-query-results) &key)
|
mas01cr@511
|
186 (when (and (slot-boundp o 'results)
|
mas01cr@511
|
187 (not (null-alien o))
|
mas01cr@511
|
188 (slot-boundp o 'spec))
|
mas01cr@511
|
189 (with-slots (results spec adb) o
|
mas01cr@511
|
190 (flet ((results-finalizer ()
|
mas01cr@511
|
191 (with-slots (alien) adb
|
mas01cr@511
|
192 (%free-query-results alien spec results))))
|
mas01cr@511
|
193 (sb-ext:finalize o #'results-finalizer)))))
|
mas01cr@511
|
194
|
mas01cr@511
|
195 (defgeneric query (datum db &key))
|
mas01cr@511
|
196
|
mas01cr@511
|
197 ;;; FIXME: I don't like this way of generalizing the boilerplate;
|
mas01cr@511
|
198 ;;; isn't there a nice functional way of doing this?
|
mas01cr@511
|
199 (macrolet
|
mas01cr@511
|
200 ((def (name datum-class &body qdatum-forms)
|
mas01cr@511
|
201 `(defmethod ,name ((datum ,datum-class) (db adb) &key
|
mas01cr@511
|
202 (sequence-length 1) (sequence-start 0)
|
mas01cr@511
|
203 exhaustivep accumulation distance
|
mas01cr@511
|
204 ;; FIXME: dubious historical defaults
|
mas01cr@511
|
205 (npoints 10) (ntracks 10)
|
mas01cr@511
|
206
|
mas01cr@511
|
207 (radius nil radiusp)
|
mas01cr@511
|
208 (include-keys nil include-keys-p)
|
mas01cr@511
|
209 (exclude-keys nil exclude-keys-p))
|
mas01cr@511
|
210 (unless (slot-boundp db 'alien)
|
mas01cr@511
|
211 (error "database ~S is closed" db))
|
mas01cr@511
|
212 (with-alien ((qid adb-query-id-t)
|
mas01cr@511
|
213 (qparams adb-query-parameters-t)
|
mas01cr@511
|
214 (qrefine adb-query-refine-t)
|
mas01cr@511
|
215 (qdatum adb-datum-t))
|
mas01cr@511
|
216 ,@qdatum-forms
|
mas01cr@511
|
217 (setf (slot qid 'datum) (addr qdatum))
|
mas01cr@511
|
218 (setf (slot qid 'sequence-length) sequence-length)
|
mas01cr@511
|
219 (setf (slot qid 'sequence-start) sequence-start)
|
mas01cr@511
|
220 (setf (slot qid 'flags) (if exhaustivep 1 0))
|
mas01cr@511
|
221
|
mas01cr@511
|
222 (setf (slot qparams 'accumulation)
|
mas01cr@511
|
223 (ecase accumulation
|
mas01cr@511
|
224 (:db 1)
|
mas01cr@511
|
225 (:per-track 2)
|
mas01cr@511
|
226 (:one-to-one 3)))
|
mas01cr@511
|
227 (setf (slot qparams 'distance)
|
mas01cr@511
|
228 (ecase distance
|
mas01cr@511
|
229 (:dot-product 1)
|
mas01cr@511
|
230 (:euclidean-normed 2)
|
mas01cr@511
|
231 (:euclidean 3)))
|
mas01cr@511
|
232 (setf (slot qparams 'npoints) (or npoints 0))
|
mas01cr@511
|
233 (setf (slot qparams 'ntracks) (or ntracks 0))
|
mas01cr@511
|
234
|
mas01cr@511
|
235 (let ((refine-flags 0))
|
mas01cr@511
|
236 (when radiusp
|
mas01cr@511
|
237 (setf refine-flags (logior refine-flags 4))
|
mas01cr@511
|
238 (setf (slot qrefine 'radius) (float radius 0d0)))
|
mas01cr@511
|
239 ;; FIXME: the freeing of the KEYS slot in these
|
mas01cr@511
|
240 ;; include/exclude keylists isn't interrupt-safe.
|
mas01cr@511
|
241 ;;
|
mas01cr@511
|
242 ;; FIXME: think quite hard about the behaviour of this
|
mas01cr@511
|
243 ;; when LENGTH is 0.
|
mas01cr@511
|
244 (when include-keys-p
|
mas01cr@511
|
245 (setf refine-flags (logior refine-flags 1))
|
mas01cr@511
|
246 (let ((length (length include-keys)))
|
mas01cr@511
|
247 (setf (slot (slot qrefine 'include) 'nkeys) length)
|
mas01cr@511
|
248 (let ((keys (make-alien c-string length)))
|
mas01cr@511
|
249 (setf (slot (slot qrefine 'include) 'keys) keys)
|
mas01cr@511
|
250 (loop for key being the elements of include-keys
|
mas01cr@511
|
251 for i upfrom 0
|
mas01cr@511
|
252 do (setf (deref keys i) key)))))
|
mas01cr@511
|
253 (when exclude-keys-p
|
mas01cr@511
|
254 (setf refine-flags (logior refine-flags 2))
|
mas01cr@511
|
255 (let ((length (length exclude-keys)))
|
mas01cr@511
|
256 (setf (slot (slot qrefine 'exclude) 'nkeys) length)
|
mas01cr@511
|
257 (let ((keys (make-alien c-string length)))
|
mas01cr@511
|
258 (setf (slot (slot qrefine 'exclude) 'keys) keys)
|
mas01cr@511
|
259 (loop for key being the elements of exclude-keys
|
mas01cr@511
|
260 for i upfrom 0
|
mas01cr@511
|
261 do (setf (deref keys i) key)))))
|
mas01cr@511
|
262 (setf (slot qrefine 'flags) refine-flags))
|
mas01cr@511
|
263 (setf (slot qrefine 'hopsize) 1)
|
mas01cr@511
|
264
|
mas01cr@511
|
265 ;; FIXME: hm, this possibly suggests that there's something
|
mas01cr@511
|
266 ;; a bit wrong with the C audioDB interface. The API
|
mas01cr@511
|
267 ;; currently exposed effectively requires either that all
|
mas01cr@511
|
268 ;; the processing of query results happens in the same
|
mas01cr@511
|
269 ;; dynamic extent as the call to audiodb_query_spec(), or
|
mas01cr@511
|
270 ;; that the adb_query_spec_t object is allocated on the
|
mas01cr@511
|
271 ;; heap. We need to think harder about whether the spec
|
mas01cr@511
|
272 ;; argument is really required (I think it probably isn't).
|
mas01cr@511
|
273 ;;
|
mas01cr@511
|
274 ;; meanwhile, here we're using it with dynamic extent anyway, so
|
mas01cr@511
|
275 ;; we could put it right back on the stack.
|
mas01cr@511
|
276 (let ((qspec (make-alien adb-query-spec-t)))
|
mas01cr@511
|
277 (unwind-protect
|
mas01cr@511
|
278 (progn
|
mas01cr@511
|
279 (setf (slot qspec 'qid) qid)
|
mas01cr@511
|
280 (setf (slot qspec 'params) qparams)
|
mas01cr@511
|
281 (setf (slot qspec 'refine) qrefine)
|
mas01cr@511
|
282
|
mas01cr@511
|
283 (let ((results
|
mas01cr@511
|
284 (sb-int:with-float-traps-masked (:invalid)
|
mas01cr@511
|
285 (%query (slot-value db 'alien) qspec))))
|
mas01cr@511
|
286 (flet ((collect-copied-results ()
|
mas01cr@511
|
287 (let ((nresults (slot results 'nresults))
|
mas01cr@511
|
288 (cresults (slot results 'results)))
|
mas01cr@511
|
289 (coerce
|
mas01cr@511
|
290 (loop for i below nresults
|
mas01cr@511
|
291 for r = (deref cresults i)
|
mas01cr@511
|
292 collect (make-result
|
mas01cr@511
|
293 :key (slot r 'key)
|
mas01cr@511
|
294 :distance (slot r 'dist)
|
mas01cr@511
|
295 :qpos (slot r 'qpos)
|
mas01cr@511
|
296 :ipos (slot r 'ipos)))
|
mas01cr@511
|
297 'vector))))
|
mas01cr@511
|
298 (unwind-protect
|
mas01cr@511
|
299 (make-instance 'copied-query-results
|
mas01cr@511
|
300 'results (collect-copied-results))
|
mas01cr@511
|
301 (%free-query-results (slot-value db 'alien) qspec results)))))
|
mas01cr@511
|
302 (when (logbitp 0 (slot (slot qspec 'refine) 'flags))
|
mas01cr@511
|
303 (free-alien (slot (slot (slot qspec 'refine) 'include) 'keys)))
|
mas01cr@511
|
304 (when (logbitp 1 (slot (slot qspec 'refine) 'flags))
|
mas01cr@511
|
305 (free-alien (slot (slot (slot qspec 'refine) 'exclude) 'keys)))
|
mas01cr@511
|
306 (free-alien qspec)))))))
|
mas01cr@511
|
307 (def query string (setf (slot qdatum 'key) datum))
|
mas01cr@511
|
308 (def query datum
|
mas01cr@511
|
309 (setf (slot qdatum 'key) (datum-key datum))
|
mas01cr@511
|
310 (setf (slot qdatum 'dim) (array-dimension (datum-data datum) 1))
|
mas01cr@511
|
311 (setf (slot qdatum 'nvectors) (array-dimension (datum-data datum) 0))
|
mas01cr@511
|
312 (setf (slot qdatum 'data) (sb-sys:vector-sap (sb-ext:array-storage-vector (datum-data datum))))
|
mas01cr@511
|
313 (if (datum-times datum)
|
mas01cr@511
|
314 (setf (slot qdatum 'times) (sb-sys:vector-sap (sb-ext:array-storage-vector (datum-times datum))))
|
mas01cr@511
|
315 (setf (slot qdatum 'times) nil))
|
mas01cr@511
|
316 (if (datum-power datum)
|
mas01cr@511
|
317 (setf (slot qdatum 'power) (sb-sys:vector-sap (sb-ext:array-storage-vector (datum-times datum))))
|
mas01cr@511
|
318 (setf (slot qdatum 'power) nil))))
|
mas01cr@511
|
319
|
mas01cr@511
|
320 #+test
|
mas01cr@511
|
321 (sb-adb:with-adb (db "/home/csr21/tmp/omras2-workshop/9.adb")
|
mas01cr@511
|
322 (sb-adb:query "KSA_CHARM_337" db :exhaustivep t :sequence-length 30
|
mas01cr@511
|
323 :accumulation :per-track :distance :euclidean :npoints 1 :ntracks 20))
|
mas01cr@511
|
324
|
mas01cr@511
|
325 #+test
|
mas01cr@511
|
326 (sb-adb:with-adb (db "/home/csr21/tmp/omras2-workshop/9.adb")
|
mas01cr@511
|
327 (sb-adb:query "KSA_CHARM_337" db :sequence-start 20 :sequence-length 20
|
mas01cr@511
|
328 :accumulation :per-track :distance :euclidean-normed
|
mas01cr@511
|
329 :npoints 10 :ntracks 1))
|
mas01cr@511
|
330
|
mas01cr@511
|
331 #+test
|
mas01cr@511
|
332 (sb-adb:with-adb (db "/home/csr21/tmp/omras2-workshop/9.adb")
|
mas01cr@511
|
333 (sb-adb:query "KSA_CHARM_337" db
|
mas01cr@511
|
334 :exhaustivep t :sequence-length 30
|
mas01cr@511
|
335 :accumulation :per-track :distance :euclidean-normed
|
mas01cr@511
|
336 :npoints 2 :ntracks 10))
|
mas01cr@511
|
337
|
mas01cr@511
|
338 ;;; only hacks and tests below
|
mas01cr@511
|
339 #|
|
mas01cr@511
|
340 (defun foo ()
|
mas01cr@511
|
341 (let ((db (%open "/home/csr21/tmp/omras2-workshop/9.adb" sb-posix:o-rdonly)))
|
mas01cr@511
|
342 (unless (null-alien db)
|
mas01cr@511
|
343 (unwind-protect
|
mas01cr@511
|
344 (with-alien ((status adb-status-t))
|
mas01cr@511
|
345 (%status db (addr status))
|
mas01cr@511
|
346 (print (list (slot status 'dim) (slot status 'nfiles))))
|
mas01cr@511
|
347 (%close db)))))
|
mas01cr@511
|
348
|
mas01cr@511
|
349 (defun set-up-spec (spec qid qparams qrefine)
|
mas01cr@511
|
350 (declare (type (alien adb-query-parameters-t) qparams)
|
mas01cr@511
|
351 (type (alien adb-query-refine-t) qrefine)
|
mas01cr@511
|
352 (type (alien adb-query-id-t) qid)
|
mas01cr@511
|
353 (type (alien adb-query-spec-t) spec))
|
mas01cr@511
|
354 (setf (slot spec 'refine) qrefine)
|
mas01cr@511
|
355 nil)
|
mas01cr@511
|
356
|
mas01cr@511
|
357 (defun bar ()
|
mas01cr@511
|
358 (let ((db (%open "/home/csr21/tmp/omras2-workshop/9.adb" sb-posix:o-rdonly)))
|
mas01cr@511
|
359 (unless (null-alien db)
|
mas01cr@511
|
360 (unwind-protect
|
mas01cr@511
|
361 (with-alien ((qid adb-query-id-t)
|
mas01cr@511
|
362 (qparams adb-query-parameters-t)
|
mas01cr@511
|
363 (qrefine adb-query-refine-t)
|
mas01cr@511
|
364 (qspec adb-query-spec-t)
|
mas01cr@511
|
365 (datum adb-datum-t))
|
mas01cr@511
|
366 (setf (slot datum 'key) "KSA_CHARM_337")
|
mas01cr@511
|
367 (setf (slot datum 'data) (sap-alien (sb-sys:int-sap 0) (* double)))
|
mas01cr@511
|
368
|
mas01cr@511
|
369 (setf (slot qid 'datum) (addr datum))
|
mas01cr@511
|
370 (setf (slot qid 'sequence-length) 30)
|
mas01cr@511
|
371 (setf (slot qid 'flags) 1) ; ADB_QID_FLAG_EXHAUSTIVE
|
mas01cr@511
|
372
|
mas01cr@511
|
373 (setf (slot qparams 'accumulation) 2) ; ADB_ACCUMULATION_PER_TRACK
|
mas01cr@511
|
374 (setf (slot qparams 'distance) 2) ; ADB_DISTANCE_EUCLIDEAN_NORMED
|
mas01cr@511
|
375 (setf (slot qparams 'npoints) 1)
|
mas01cr@511
|
376 (setf (slot qparams 'ntracks) 20)
|
mas01cr@511
|
377
|
mas01cr@511
|
378 (setf (slot qrefine 'flags) 0)
|
mas01cr@511
|
379 (setf (slot qrefine 'hopsize) 1)
|
mas01cr@511
|
380
|
mas01cr@511
|
381 (setf (slot qspec 'qid) qid)
|
mas01cr@511
|
382 (setf (slot qspec 'params) qparams)
|
mas01cr@511
|
383 (setf (slot qspec 'refine) qrefine)
|
mas01cr@511
|
384 (let ((results (%query db (addr qspec))))
|
mas01cr@511
|
385 (unless (null-alien results)
|
mas01cr@511
|
386 (unwind-protect
|
mas01cr@511
|
387 (flet ((print-result (n)
|
mas01cr@511
|
388 (let ((result (deref (slot results 'results) n)))
|
mas01cr@511
|
389 (format t "~&~A ~F ~D ~D~%"
|
mas01cr@511
|
390 (slot result 'key) (slot result 'dist)
|
mas01cr@511
|
391 (slot result 'qpos) (slot result 'ipos)))))
|
mas01cr@511
|
392 (dotimes (i (slot results 'nresults))
|
mas01cr@511
|
393 (print-result i)))
|
mas01cr@511
|
394 (%free-query-results db (addr qspec) results)))))
|
mas01cr@511
|
395 (%close db)))))
|
mas01cr@511
|
396 |#
|