-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathndbapi-simple-scan.lisp
More file actions
150 lines (136 loc) · 8.93 KB
/
ndbapi-simple-scan.lisp
File metadata and controls
150 lines (136 loc) · 8.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
;;; Copyright (c) 2022 Max-Gerd Retzlaff <mgr@matroid.org>, Datagraph GmbH.
;;; Distributed under the terms of the GNU General Public License, Version 2.0,
;;; see file LICENSE in the top level directory of this repository.
(in-package :ndb.simple-scan)
;; translation of the example ndbapi_simple_scan that I created
;; on the basis of my ndbapi_simple_scan example (in c++)
#+(or)
(asdf:oos 'asdf:load-op :ndbapi)
#|
create table as:
create table test
(g int unsigned not null, s int unsigned not null,
p int unsigned not null, o int unsigned not null,
index gspo (g,s,p,o), index gpos (g,p,o,s), index gosp (g,o,s,p),
index spog (s,p,o,g), index posg (p,o,s,g), index ospg (o,s,p,g),
unique (g,s,p,o));
load data with:
load data infile '/path/to/data.tsv' into table test;
|#
(defun simple-scan (&key connection-string database-name table-name index-name
bound-specs ;; list of specs: (&key low high (low-inclusive t) (high-inclusive t))
just-count
force-retrieval
decode-visibility)
(ndbapi:ensure-ndb-api-initialisation)
(ndbapi:with-ndb-cluster-connection (ndbapi:*connection* (connection-string)
:name "ndbapi-scan-count")
(ndbapi:with-ndb (ndb (ndbapi:*connection* database-name))
(cffi:with-foreign-object (result-mask :unsigned-char)
(setf (cffi:mem-ref result-mask :unsigned-char) #b00000000)
(ndbapi:with-ndb-transaction (transaction ndb)
(let* ((dict (ndbapi:ndb-get-dictionary ndb))
(table (ndbapi:dictionary-get-table dict table-name))
(index (ndbapi:dictionary-get-index dict
index-name
(ndbapi:table-get-name table)))
(index-default-record (ndbapi:index-get-default-record index))
(table-default-record (ndbapi:table-get-default-record table))
(scan-flags (remove nil (list (unless just-count
:+SF-ORDER-BY+)
:+SF-MULTI-RANGE+))))
(ndbapi:with-foreign-struct (scan-options (list :options-present :+SO-SCANFLAGS+
:scan-flags scan-flags)
'(:struct ndbapi:scan-options))
;;(break "~a" (cffi:convert-from-foreign scan-options '(:struct ndbapi:scan-options)))
(ndbapi:with-ndb-transaction-scan-index (scan (transaction
index-default-record
table-default-record
:+lm-committed-read+
(if (and just-count
(not force-retrieval))
result-mask
(cffi:null-pointer))
(cffi:null-pointer)
scan-options
(cffi:foreign-type-size
'(:struct ndbapi:scan-options)))
(t))
;; set bounds for scan
(let ((bounds-count (length bound-specs)))
(cffi:with-foreign-objects ((low-quads '(:struct ndb.quads:quad) bounds-count)
(high-quads '(:struct ndb.quads:quad) bounds-count)
(bounds '(:struct ndbapi:index-bound) bounds-count))
(loop for bound-spec in bound-specs
for i from 0
do (destructuring-bind (&key low high (low-inclusive t) (high-inclusive t))
bound-spec
(setf (cffi:mem-aref low-quads '(:struct ndb.quads:quad) i) (ndb.quads:list-to-quad low)
(cffi:mem-aref high-quads '(:struct ndb.quads:quad) i) (ndb.quads:list-to-quad high)
(cffi:mem-aref bounds '(:struct ndbapi:index-bound) i)
(list :low-key (cffi:mem-aptr low-quads '(:struct ndb.quads:quad) i)
:low-key-count (length low)
:low-inclusive low-inclusive
:high-key (cffi:mem-aptr high-quads '(:struct ndb.quads:quad) i)
:high-key-count (length high)
:high-inclusive high-inclusive
:range-no i))
(let ((bound (cffi:mem-aptr bounds '(:struct ndbapi:index-bound) i)))
(ndbapi:ndb-index-scan-operation-set-bound scan index-default-record bound))))
;; execute transaction
(ndbapi:ndb-transaction-execute transaction :+NO-COMMIT+)))
;; explicitly check for errors
;; as there might still be errors even though the execute call itself was successful
;; Update: this is done by ndbapi:ndb-transaction-execute already now (20221213 mgr).
;; (ndbapi:explicitly-check-for-transaction-error transaction)
;; do scan and print
(unless just-count
(format t "~&table: ~a" table-name)
(format t "~&columns: ~{~12@a~^, ~}" (list :graph :subject :predicate :object)))
(let ((total-row-count 0))
(cffi:with-foreign-object (row-data :pointer)
(loop for rc = (ndbapi:ndb-scan-operation-next-result scan row-data t nil)
for j from 0
while (zerop rc)
do (unless just-count
(format t "~&row ~5d: ~{~12d~^, ~}" j
(ndb.quads:quad-to-list
(ndb.quads:convert-foreign-quad (cffi:mem-aref row-data :pointer))
:decode-visibility decode-visibility)))
(when force-retrieval
(assert (plusp (cffi:foreign-slot-value (cffi:mem-aref row-data :pointer)
'(:struct ndb.quads:quad-vis) :vis-size))))
(incf total-row-count)
finally (assert (= rc 1)
()
"scan-operation-next-result() failed: ~a"
(ndbapi:get-ndb-error transaction #'ndbapi:ndb-transaction-get-ndb-error))))
total-row-count)))))))))
#+(or)
(ndb.simple-scan:simple-scan :connection-string "localhost:1186,localhost:1187"
:database-name "mgr"
:table-name "test"
:index-name "gspo")
#+(or)
(ndb.simple-scan:simple-scan :connection-string "localhost:1186,localhost:1187"
:database-name "mgr"
:table-name "test"
:index-name "ospg"
:bound-specs '((:low (1106 1105 638 1105) :low-inclusive t
:high (1109 1106 1108 1105) :high-inclusive t)))
#+(or)
(ndb.simple-scan:simple-scan :connection-string "localhost:1186,localhost:1187"
:database-name "mgr"
:table-name "test"
:index-name "gpos"
:bound-specs '((:low (1105 2000000) :low-inclusive t
:high (1105 2200000) :high-inclusive t)))
#+(or)
(ndb.simple-scan:simple-scan :connection-string "localhost:1186,localhost:1187"
:database-name "mgr"
:table-name "test"
:index-name "ospg"
:bound-specs '((:low (1106 1105 638 1105) :low-inclusive t
:high (1109 1106 1108 1105 ) :high-inclusive t)
(:low (600000) :low-inclusive nil
:high (662743) :high-inclusive t)))