Skip to content

Commit 447699f

Browse files
committed
use sqlite3 indexing for faster lookups attributes/references
1 parent ba6898b commit 447699f

File tree

1 file changed

+20
-13
lines changed

1 file changed

+20
-13
lines changed

opcua/server/address_space_sqlite.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class AddressSpaceSQLite(AddressSpace):
8686
Intended for slow devices, such as Raspberry Pi, to greatly improve start up time
8787
"""
8888
PY2 = sys.version_info < (3, 0)
89+
NODEID_COL_NAME = 'NodeId'
8990
ATTR_TABLE_NAME = 'Attributes'
9091
REFS_TABLE_NAME = 'References'
9192
CUR_TIME_NODEID = NumericNodeId(ua.ObjectIds.Server_ServerStatus_CurrentTime, 0)
@@ -296,9 +297,10 @@ def CB(row):
296297
# Read and write from attribute table
297298
@staticmethod
298299
def _create_attr_table(backend, table=ATTR_TABLE_NAME, drop=False):
299-
ATTR_TABLE_COLS = [
300+
nid = AddressSpaceSQLite.NODEID_COL_NAME
301+
ATTR_COLS = [
300302
'_Id BLOB PRIMARY KEY NOT NULL', # 0
301-
'NodeId BLOB', # 1
303+
'{:s} BLOB'.format(nid), # 1
302304
'AttributeId INTEGER', # 2
303305
'ServerTimestamp TIMESTAMP', # 3
304306
'ServerPicoseconds INTEGER', # 4
@@ -308,11 +310,19 @@ def _create_attr_table(backend, table=ATTR_TABLE_NAME, drop=False):
308310
'Variant BLOB', # 8
309311
'Description STRING', # 9
310312
]
313+
AddressSpaceSQLite._create_indexed_table(backend, table, ATTR_COLS, drop)
314+
315+
@staticmethod
316+
def _create_indexed_table(backend, table, cols, drop):
317+
nid = AddressSpaceSQLite.NODEID_COL_NAME
318+
cmds = []
311319
if drop is True:
312-
dropCmd = 'DROP TABLE IF EXISTS "{tn}"'.format(tn=table)
313-
backend.execute_write(dropCmd, commit=True)
314-
cmd = 'CREATE TABLE IF NOT EXISTS "{tn}" ({c})'.format(tn=table, c=', '.join(ATTR_TABLE_COLS))
315-
backend.execute_write(cmd, commit=True)
320+
cmds.append('DROP INDEX IF EXISTS "idx_{tn}"'.format(tn=table))
321+
cmds.append('DROP TABLE IF EXISTS "{tn}"'.format(tn=table))
322+
cmds.append('CREATE TABLE IF NOT EXISTS "{tn}" ({c})'.format(tn=table, c=', '.join(cols)))
323+
cmds.append('CREATE INDEX IF NOT EXISTS "idx_{tn}" ON "{tn}" ({nid})'.format(tn=table, nid=nid))
324+
for cmd in cmds:
325+
backend.execute_write(cmd, commit=True)
316326

317327
def _insert_attribute_threadsafe(self, nodeid, attrId, attr, table=ATTR_TABLE_NAME, commit=True):
318328
with self._lock:
@@ -384,9 +394,10 @@ def _read_attribute_row(row):
384394
# Read and write from references table
385395
@staticmethod
386396
def _create_refs_table(backend, table=REFS_TABLE_NAME, drop=False):
387-
REFS_TABLE_COLS = [
397+
nid = AddressSpaceSQLite.NODEID_COL_NAME
398+
REFS_COLS = [
388399
'_Id BLOB PRIMARY KEY NOT NULL', # 0
389-
'NodeId BLOB', # 1 = the nodeid of this ReferenceDescription
400+
'{:s} BLOB'.format(nid), # 1 = the nodeid of this ReferenceDescription
390401
'ReferenceTypeId BLOB', # 2
391402
'IsForward INTEGER', # 3
392403
'ReferredNodeId BLOB', # 4 = referred nodeid of ReferenceDescription
@@ -399,11 +410,7 @@ def _create_refs_table(backend, table=REFS_TABLE_NAME, drop=False):
399410
'TypeDefinition BLOB', # 11
400411
'Description STRING' # 12
401412
]
402-
if drop is True:
403-
dropCmd = 'DROP TABLE IF EXISTS "{tn}"'.format(tn=table)
404-
backend.execute_write(dropCmd, commit=True)
405-
cmd = 'CREATE TABLE IF NOT EXISTS "{tn}" ({c})'.format(tn=table, c=', '.join(REFS_TABLE_COLS))
406-
backend.execute_write(cmd, commit=True)
413+
AddressSpaceSQLite._create_indexed_table(backend, table, REFS_COLS, drop)
407414

408415
def _insert_reference_threadsafe(self, nodeid, ref, table=REFS_TABLE_NAME, commit=True):
409416
with self._lock:

0 commit comments

Comments
 (0)