Workflow: JSON parser acceleration

Sadly is even worse because of the ctypes-induced conversions.
This commit is contained in:
Geoffrey Frogeye 2019-12-09 10:42:37 +01:00
parent 55877be891
commit 66ac52c5db
Signed by: geoffrey
GPG key ID: D8A7ECA00A8CD3DD
2 changed files with 86 additions and 13 deletions

66
accel.c
View file

@ -1,6 +1,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
int ip4_flat(char* value, wchar_t* flat) char ip4_flat(char* value, wchar_t* flat)
{ {
unsigned char value_index = 0; unsigned char value_index = 0;
unsigned char octet_index = 0; unsigned char octet_index = 0;
@ -35,3 +36,66 @@ int ip4_flat(char* value, wchar_t* flat)
} while (1); // This ugly thing save one comparison } while (1); // This ugly thing save one comparison
return 1; return 1;
} }
#define MAX_OUTPUT 255
char feed_dns_parse_json(char* line, char* name, char* value)
{
unsigned short line_index = 0;
unsigned char quote_index = 0;
unsigned char output_index = 0;
char line_chara;
char* current_output = NULL;
char type = 0; // 0: error, 1: cname, 2: a, 3: aaaa
do {
line_chara = line[line_index];
if (line_chara == '"') {
quote_index += 1;
switch (quote_index) {
case 7: // Start of name
current_output = name;
break;
case 8: // End of name
name[output_index] = '\0';
current_output = NULL;
break;
case 11: // Start of type
line_chara = line[++line_index];
if (line_chara == 'c') { // Must be CNAME
type = 1;
break;
} else if (line_chara == 'a') { // A or AAAA
line_chara = line[++line_index];
if (line[line_chara+2] == '"') { // Is A
type = 2;
quote_index++;
break;
} else if (line[line_chara+1] == 'a') { // Must be AAAA
type = 3;
break;
}
}
return 0;
case 15: // Start of value
current_output = value;
break;
case 16: // End of value
value[output_index] = '\0';
return type;
}
output_index = 0;
} else if (line_chara == '\0') {
return 0;
} else {
if (current_output != 0) {
if (output_index >= MAX_OUTPUT) {
return 0;
}
current_output[output_index] = line_chara;
output_index++;
}
}
line_index++;
} while (1); // This ugly thing save one comparison
return 0;
}

View file

@ -3,10 +3,16 @@
import database import database
import argparse import argparse
import sys import sys
import ctypes
import json
ACCEL = ctypes.cdll.LoadLibrary('./libaccel.so')
ACCEL_NAME_BUF = ctypes.create_string_buffer(b'Z'*255, 255)
ACCEL_VALUE_BUF = ctypes.create_string_buffer(b'Z'*255, 255)
FUNCTION_MAP = { FUNCTION_MAP = {
b'a': database.feed_a, b'a': database.feed_a,
b'cname': database.feed_cname, b'cname': database.feed_cname,
} }
if __name__ == '__main__': if __name__ == '__main__':
@ -21,21 +27,24 @@ if __name__ == '__main__':
database.open_db() database.open_db()
line = b'(none)'
def err(name: bytes, value: bytes) -> None:
print(f"Error with line: {line!r}")
FUNCTIONS = [err, database.feed_cname, database.feed_a]
try: try:
database.time_step('iowait') database.time_step('iowait')
line: bytes
for line in args.input: for line in args.input:
database.time_step('feed_json_parse') database.time_step('feed_json_parse')
split = line.split(b'"') dtype = ACCEL.feed_dns_parse_json(
name = split[7] ctypes.c_char_p(line),
dtype = split[11] ACCEL_NAME_BUF,
value = split[15] ACCEL_VALUE_BUF
# data = json.loads(line) )
# assert dtype == data['type']
# assert name == data['name']
# assert value == data['value']
database.time_step('feed_switch') database.time_step('feed_switch')
FUNCTION_MAP[dtype](name, value) FUNCTIONS[dtype](ACCEL_NAME_BUF.value, ACCEL_VALUE_BUF.value)
database.time_step('iowait') database.time_step('iowait')
except KeyboardInterrupt: except KeyboardInterrupt:
print("Interupted.") print("Interupted.")