Workflow: JSON parser acceleration
Sadly is even worse because of the ctypes-induced conversions.
This commit is contained in:
parent
55877be891
commit
66ac52c5db
66
accel.c
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;
|
||||
}
|
||||
|
|
29
feed_dns.py
29
feed_dns.py
|
@ -3,6 +3,12 @@
|
|||
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,
|
||||
|
@ -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…
Reference in a new issue