-
Notifications
You must be signed in to change notification settings - Fork 15
/
virtuoso.py
140 lines (123 loc) · 4.51 KB
/
virtuoso.py
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
#!/usr/bin/env python3
# This script provides a convenient wrapper for the Virtuoso SPARQL server.
# Adapted from Sempre (https://github.com/percyliang/sempre)
import os
import sys
import subprocess
import argparse
virtuosoPath = "/home/dki_lab/tools/virtuoso/virtuoso-opensource"
if not os.path.exists(virtuosoPath):
print(f"{virtuosoPath} does not exist")
sys.exit(1)
# Virtuoso has two services: the server (isql) and SPARQL endpoint
def isqlPort(port): return 10000 + port
def httpPort(port): return port
def run(command):
print(f"RUNNING: {command}")
res = subprocess.run(command, shell=True, stdout=subprocess.PIPE)
return res.stdout
def start(dbPath, port):
if not os.path.exists(dbPath):
os.mkdir(dbPath)
# Recommended: 70% of RAM, each buffer is 8K
# Use a fraction of the free RAM. The result may vary across runs.
# memFree = parseInt(`cat /proc/meminfo | grep MemFree | awk '{print $2}'`) # KB
# Use a fraction of the total RAM. The result is the same across runs.
memFree = int(run("cat /proc/meminfo | grep MemTotal | awk '{print $2}'")) # KB
numberOfBuffers = memFree * 0.15 / 8
maxDirtyBuffers = numberOfBuffers / 2
print(f"{memFree} KB free, using {numberOfBuffers} buffers, {maxDirtyBuffers} dirty buffers")
# Configuration options:
# http://docs.openlinksw.com/virtuoso/dbadm.html
# http://virtuoso.openlinksw.com/dataspace/doc/dav/wiki/Main/VirtConfigScale
config = (
f"[Database]\n"
f"DatabaseFile = {dbPath}/virtuoso.db\n"
f"ErrorLogFile = {dbPath}/virtuoso.log\n"
f"LockFile = {dbPath}/virtuoso.lck\n"
f"TransactionFile = {dbPath}/virtuoso.trx\n"
f"xa_persistent_file = {dbPath}/virtuoso.pxa\n"
f"ErrorLogLevel = 7\n"
f"FileExtend = 200\n"
f"MaxCheckpointRemap = 2000\n"
f"Striping = 0\n"
f"TempStorage = TempDatabase\n"
f"\n"
f"[TempDatabase]\n"
f"DatabaseFile = {dbPath}/virtuoso-temp.db\n"
f"TransactionFile = {dbPath}/virtuoso-temp.trx\n"
f"MaxCheckpointRemap = 2000\n"
f"Striping = 0\n"
f"\n"
f"[Parameters]\n"
f"ServerPort = {isqlPort(port)}\n"
f"LiteMode = 0\n"
f"DisableUnixSocket = 1\n"
f"DisableTcpSocket = 0\n"
f"ServerThreads = 100 ; increased from 20\n"
f"CheckpointInterval = 60\n"
f"O_DIRECT = 1 ; increased from 0\n"
f"CaseMode = 2\n"
f"MaxStaticCursorRows = 100000\n"
f"CheckpointAuditTrail = 0\n"
f"AllowOSCalls = 0\n"
f"SchedulerInterval = 10\n"
f"DirsAllowed = .\n"
f"ThreadCleanupInterval = 0\n"
f"ThreadThreshold = 10\n"
f"ResourcesCleanupInterval = 0\n"
f"FreeTextBatchSize = 100000\n"
# f"SingleCPU = 0\n"
f"PrefixResultNames = 0\n"
f"RdfFreeTextRulesSize = 100\n"
f"IndexTreeMaps = 256\n"
f"MaxMemPoolSize = 200000000\n"
f"PrefixResultNames = 0\n"
f"MacSpotlight = 0\n"
f"IndexTreeMaps = 64\n"
f"NumberOfBuffers = {numberOfBuffers}\n"
f"MaxDirtyBuffers = {maxDirtyBuffers}\n"
f"\n"
f"[SPARQL]\n"
f"ResultSetMaxRows = 50000\n"
f"MaxQueryCostEstimationTime = 600 ; in seconds (increased)\n"
f"MaxQueryExecutionTime = 180; in seconds (increased)\n"
f"\n"
f"[HTTPServer]\n"
f"ServerPort = {httpPort(port)}\n"
f"Charset = UTF-8\n"
f"ServerThreads = 15 ; increased from unknown\n"
)
configPath = f"{dbPath}/virtuoso.ini"
print(config)
print()
print(configPath)
print(f"==== Starting Virtuoso server for {dbPath} on port {port}...")
with open(configPath, 'w') as f:
f.write(config)
run(f"{virtuosoPath}/bin/virtuoso-t +configfile {configPath} +wait")
def stop(port):
run(f"echo 'shutdown;' | {virtuosoPath}/bin/isql localhost:{isqlPort(port)}")
def status(port):
run(f"echo 'status();' | {virtuosoPath}/bin/isql localhost:{isqlPort(port)}")
############################################################
# Main
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="manage Virtuoso services")
parser.add_argument("action", type=str, help="start or stop")
parser.add_argument("port", type=int, help="port for the SPARQL HTTP endpoint")
parser.add_argument("-d", "--db-path", type=str, help="path to the db directory")
args = parser.parse_args()
if args.action == "start":
if not args.db_path:
print("please specify path to the db directory with -d")
sys.exit()
if not os.path.isdir(args.db_path):
print("the path specified does not exist")
sys.exit()
start(args.db_path, args.port)
elif args.action == "stop":
stop(args.port)
else:
print(f"invalid action: ${args.action}")
sys.exit()