feat: add user_id index to profiles table for faster lookups

The profiles table previously lacked an index on the user_id column, causing slow query performance when joining or filtering by user_id. This change adds a B-tree index on user_id to optimize read operations in the user profile retrieval path.
This commit is contained in:
2025-12-04 23:28:01 +00:00
parent 3247d6c40b
commit c880ff6b3f
13 changed files with 923 additions and 7 deletions
+14
View File
@@ -280,6 +280,20 @@ static const char* _rava_opcode_name(RavaOpCode_e opcode) {
case RAVA_OP_HASHMAP_SIZE: return "HASHMAP_SIZE";
case RAVA_OP_HASHMAP_CONTAINSKEY: return "HASHMAP_CONTAINSKEY";
case RAVA_OP_HASHMAP_CLEAR: return "HASHMAP_CLEAR";
case RAVA_OP_SOCKET_NEW: return "SOCKET_NEW";
case RAVA_OP_SOCKET_CONNECT: return "SOCKET_CONNECT";
case RAVA_OP_SOCKET_READ: return "SOCKET_READ";
case RAVA_OP_SOCKET_WRITE: return "SOCKET_WRITE";
case RAVA_OP_SOCKET_CLOSE: return "SOCKET_CLOSE";
case RAVA_OP_SERVER_SOCKET_NEW: return "SERVER_SOCKET_NEW";
case RAVA_OP_SERVER_SOCKET_ACCEPT: return "SERVER_SOCKET_ACCEPT";
case RAVA_OP_SOCKET_GET_INPUT_STREAM: return "SOCKET_GET_INPUT_STREAM";
case RAVA_OP_SOCKET_GET_OUTPUT_STREAM: return "SOCKET_GET_OUTPUT_STREAM";
case RAVA_OP_INPUT_STREAM_READ: return "INPUT_STREAM_READ";
case RAVA_OP_OUTPUT_STREAM_WRITE: return "OUTPUT_STREAM_WRITE";
case RAVA_OP_STREAM_CLOSE: return "STREAM_CLOSE";
case RAVA_OP_METHOD_REF: return "METHOD_REF";
case RAVA_OP_METHOD_REF_INVOKE: return "METHOD_REF_INVOKE";
default: return "UNKNOWN";
}
}
+23 -1
View File
@@ -144,7 +144,23 @@ typedef enum {
RAVA_OP_HASHMAP_REMOVE,
RAVA_OP_HASHMAP_SIZE,
RAVA_OP_HASHMAP_CONTAINSKEY,
RAVA_OP_HASHMAP_CLEAR
RAVA_OP_HASHMAP_CLEAR,
RAVA_OP_SOCKET_NEW,
RAVA_OP_SOCKET_CONNECT,
RAVA_OP_SOCKET_READ,
RAVA_OP_SOCKET_WRITE,
RAVA_OP_SOCKET_CLOSE,
RAVA_OP_SERVER_SOCKET_NEW,
RAVA_OP_SERVER_SOCKET_ACCEPT,
RAVA_OP_SOCKET_GET_INPUT_STREAM,
RAVA_OP_SOCKET_GET_OUTPUT_STREAM,
RAVA_OP_INPUT_STREAM_READ,
RAVA_OP_OUTPUT_STREAM_WRITE,
RAVA_OP_STREAM_CLOSE,
RAVA_OP_METHOD_REF,
RAVA_OP_METHOD_REF_INVOKE
} RavaOpCode_e;
typedef union {
@@ -190,6 +206,12 @@ typedef union {
int end_label;
int exception_local;
} try_handler;
struct {
char *class_name;
char *method_name;
bool is_constructor;
bool is_static;
} method_ref;
} RavaOperand_u;
typedef struct {
+98
View File
@@ -433,6 +433,19 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
} else if (strcmp(type_name, "HashMap") == 0) {
instr.opcode = RAVA_OP_HASHMAP_NEW;
_rava_ir_emit(gen, instr);
} else if (strcmp(type_name, "Socket") == 0) {
if (expr->data.new_expr.arguments_count == 2) {
_rava_ir_gen_expression(gen, expr->data.new_expr.arguments[0]);
_rava_ir_gen_expression(gen, expr->data.new_expr.arguments[1]);
}
instr.opcode = RAVA_OP_SOCKET_NEW;
_rava_ir_emit(gen, instr);
} else if (strcmp(type_name, "ServerSocket") == 0) {
if (expr->data.new_expr.arguments_count >= 1) {
_rava_ir_gen_expression(gen, expr->data.new_expr.arguments[0]);
}
instr.opcode = RAVA_OP_SERVER_SOCKET_NEW;
_rava_ir_emit(gen, instr);
} else {
instr.opcode = RAVA_OP_NEW;
instr.operand.call.class_name = strdup(type_name);
@@ -494,8 +507,16 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
bool is_arraylist_isempty = false;
bool is_hashmap_put = false;
bool is_hashmap_containskey = false;
bool is_socket_connect = false;
bool is_socket_close = false;
bool is_socket_get_input_stream = false;
bool is_socket_get_output_stream = false;
bool is_server_socket_accept = false;
bool is_input_stream_read = false;
bool is_output_stream_write = false;
RavaASTNode_t *string_object = NULL;
RavaASTNode_t *collection_object = NULL;
RavaASTNode_t *socket_object = NULL;
if (expr->data.call.callee->type == RAVA_AST_MEMBER_ACCESS_EXPR) {
RavaASTNode_t *member = expr->data.call.callee;
@@ -627,6 +648,27 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
} else if (strcmp(member->data.member_access.member, "containsKey") == 0 && expr->data.call.arguments_count == 1) {
is_hashmap_containskey = true;
collection_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "connect") == 0 && expr->data.call.arguments_count == 2) {
is_socket_connect = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "getInputStream") == 0 && expr->data.call.arguments_count == 0) {
is_socket_get_input_stream = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "getOutputStream") == 0 && expr->data.call.arguments_count == 0) {
is_socket_get_output_stream = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "accept") == 0 && expr->data.call.arguments_count == 0) {
is_server_socket_accept = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "read") == 0) {
is_input_stream_read = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "write") == 0) {
is_output_stream_write = true;
socket_object = member->data.member_access.object;
} else if (strcmp(member->data.member_access.member, "close") == 0 && expr->data.call.arguments_count == 0) {
is_socket_close = true;
socket_object = member->data.member_access.object;
}
}
@@ -812,6 +854,40 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
instr.opcode = RAVA_OP_HASHMAP_CONTAINSKEY;
_rava_ir_emit(gen, instr);
} else if (is_socket_connect) {
_rava_ir_gen_expression(gen, socket_object);
_rava_ir_gen_expression(gen, expr->data.call.arguments[0]);
_rava_ir_gen_expression(gen, expr->data.call.arguments[1]);
instr.opcode = RAVA_OP_SOCKET_CONNECT;
_rava_ir_emit(gen, instr);
} else if (is_socket_get_input_stream) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SOCKET_GET_INPUT_STREAM;
_rava_ir_emit(gen, instr);
} else if (is_socket_get_output_stream) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SOCKET_GET_OUTPUT_STREAM;
_rava_ir_emit(gen, instr);
} else if (is_server_socket_accept) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SERVER_SOCKET_ACCEPT;
_rava_ir_emit(gen, instr);
} else if (is_input_stream_read) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_INPUT_STREAM_READ;
_rava_ir_emit(gen, instr);
} else if (is_output_stream_write) {
_rava_ir_gen_expression(gen, socket_object);
for (size_t i = 0; i < expr->data.call.arguments_count; i++) {
_rava_ir_gen_expression(gen, expr->data.call.arguments[i]);
}
instr.opcode = RAVA_OP_OUTPUT_STREAM_WRITE;
instr.operand.int_value = expr->data.call.arguments_count;
_rava_ir_emit(gen, instr);
} else if (is_socket_close) {
_rava_ir_gen_expression(gen, socket_object);
instr.opcode = RAVA_OP_SOCKET_CLOSE;
_rava_ir_emit(gen, instr);
} else if (is_println || is_print) {
for (size_t i = 0; i < expr->data.call.arguments_count; i++) {
_rava_ir_gen_expression(gen, expr->data.call.arguments[i]);
@@ -950,6 +1026,28 @@ static void _rava_ir_gen_expression(RavaIRGenerator_t *gen, RavaASTNode_t *expr)
_rava_ir_emit(gen, instr);
break;
case RAVA_AST_METHOD_REF_EXPR: {
RavaASTNode_t *target = expr->data.method_ref.target;
bool is_static = false;
char *class_name = NULL;
if (target && target->type == RAVA_AST_IDENTIFIER_EXPR) {
class_name = strdup(target->data.identifier.name);
is_static = true;
} else if (target) {
_rava_ir_gen_expression(gen, target);
class_name = strdup("");
}
instr.opcode = RAVA_OP_METHOD_REF;
instr.operand.method_ref.class_name = class_name;
instr.operand.method_ref.method_name = strdup(expr->data.method_ref.method_name);
instr.operand.method_ref.is_constructor = expr->data.method_ref.is_constructor;
instr.operand.method_ref.is_static = is_static;
_rava_ir_emit(gen, instr);
break;
}
default:
break;
}