Browse Source

Workflow: JSON parser acceleration

Sadly is even worse because of the ctypes-induced conversions.
newworkflow_parseropti
Geoffrey Frogeye 2 years ago
parent
commit
66ac52c5db
Signed by: geoffrey GPG Key ID: D8A7ECA00A8CD3DD
  1. 66
      accel.c
  2. 33
      feed_dns.py

66
accel.c

@ -1,6 +1,7 @@
#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 octet_index = 0;
@ -35,3 +36,66 @@ int ip4_flat(char* value, wchar_t* flat)
} while (1); // This ugly thing save one comparison
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;
}

33
feed_dns.py

@ -3,10 +3,16 @@
import database
import argparse
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 = {
b'a': database.feed_a,
b'cname': database.feed_cname,
b'a': database.feed_a,
b'cname': database.feed_cname,
}
if __name__ == '__main__':
@ -21,21 +27,24 @@ if __name__ == '__main__':
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:
database.time_step('iowait')
line: bytes
for line in args.input:
database.time_step('feed_json_parse')
split = line.split(b'"')
name = split[7]
dtype = split[11]
value = split[15]
# data = json.loads(line)
# assert dtype == data['type']
# assert name == data['name']
# assert value == data['value']
dtype = ACCEL.feed_dns_parse_json(
ctypes.c_char_p(line),
ACCEL_NAME_BUF,
ACCEL_VALUE_BUF
)
database.time_step('feed_switch')
FUNCTION_MAP[dtype](name, value)
FUNCTIONS[dtype](ACCEL_NAME_BUF.value, ACCEL_VALUE_BUF.value)
database.time_step('iowait')
except KeyboardInterrupt:
print("Interupted.")

Loading…
Cancel
Save