<commit_before>#include "skynet.h"
#include "mread.h"

#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdarg.h>

struct connection {
	char * agent;
	char * client;
	int connection_id;
	int uid;
};

struct gate {
	struct mread_pool * pool;
	const char * watchdog;
	int id_index;
	int cap;
	int max_connection;
	struct connection ** agent;
	struct connection * map;
};

struct gate *
gate_create(void) {
	struct gate * g = malloc(sizeof(*g));
	g->pool = NULL;
	g->max_connection = 0;
	g->agent = NULL;
	return g;
}

static inline struct connection * 
_id_to_agent(struct gate *g,int uid) {
	return g->agent[uid & (g->cap - 1)];
}

static void
_parm(char *msg, int sz, int command_sz) {
	while (command_sz < sz) {
		if (msg[command_sz] != ' ')
			break;
		++command_sz;
	}
	int i;
	for (i=command_sz;i<sz;i++) {
		msg[i-command_sz] = msg[i];
	}
	msg[i-command_sz] = '\0';
}

static void
_forward_agent(struct gate * g, int id, const char * agentaddr, const char *clientaddr) {
	struct connection * agent = _id_to_agent(g,id);
	if (agent->agent) {
		free(agent->agent);
	}
	agent->agent = strdup(agentaddr);
	if (agent->client) {
		free(agent->client);
	}
	agent->client = strdup(clientaddr);
}

static void
_ctrl(struct skynet_context * ctx, struct gate * g, const void * msg, int sz) {
	char tmp[sz+1];
	memcpy(tmp, msg, sz);
	tmp[sz] = '\0';
	char * command = tmp;
	int i;
	if (sz == 0)
		return;
	for (i=0;i<sz;i++) {
		if (command[i]==' ') {
			break;
		}
	}
	if (memcmp(command,"kick",i)==0) {
		_parm(tmp, sz, i);
		int uid = strtol(command , NULL, 10);
		struct connection * agent = _id_to_agent(g,uid);
		int connection_id = agent->connection_id;

		mread_close_client(g->pool,connection_id);
		return;
	}
	if (memcmp(command,"forward",i)==0) {
		_parm(tmp, sz, i);
		char * client = tmp;
		char * idstr = strsep(&client, " ");
		if (client == NULL) {
			return;
		}
		int id = strtol(idstr , NULL, 10);
		char * agent = strsep(&client, " ");
		if (client == NULL) {
			return;
		}
		_forward_agent(g, id, agent, client);
		return;
	}
	skynet_error(ctx, "[gate] Unkown command : %s", command);
}

static void
_report(struct gate *g, struct skynet_context * ctx, const char * data, ...) {
	va_list ap;
	va_start(ap, data);
	char tmp[1024];
	int n = vsnprintf(tmp, sizeof(tmp), data, ap);
	va_end(ap);

	skynet_send(ctx, NULL, g->watchdog, 0, tmp, n, 0);
}

static void
_forward(struct skynet_context * ctx,struct gate *g, int uid, void * data, size_t len) {
	struct connection * agent = _id_to_agent(g,uid);
	if (agent->agent) {
		// todo: client package has not session , send 0x7fffffff
		skynet_send(ctx, agent->client, agent->agent, 0x7fffffff, data, len, 0);
	} else {
		char * tmp = malloc(len + 32);
		int n = snprintf(tmp,len+32,"%d data ",uid);
		memcpy(tmp+n,data,len);
		skynet_send(ctx, NULL, g->watchdog, 0, tmp, len + n, DONTCOPY);
	}
}

static int
_gen_id(struct gate * g, int connection_id) {
	int uid = ++g->id_index;
	int i;
	for (;;) {
		for (i=0;i<g->cap;i++) {
			int hash = (uid + i) & (g->cap - 1);
			if (g->agent[hash] == NULL) {
				uid = uid + i;
				struct connection * conn = &g->map[connection_id];
				conn->uid = uid;
				g->agent[hash] = conn;
				return uid;
			}
		}
		struct connection ** new_hash = malloc(g->cap * 2 * sizeof(struct connection *));
		memset(new_hash, 0, sizeof(g->cap * 2 * sizeof(struct connection *)));
		for (i=0;i<g->max_connection;i++) {
			struct connection * conn = &g->map[connection_id];
			assert(conn->uid == 0);
			new_hash[conn->uid & (g->cap * 2 -1)] = conn;
		}
		free(g->agent);
		g->agent = new_hash;
	}
}
<commit_msg>bugifx : gate alloc uid<commit_after>#include "skynet.h"
#include "mread.h"

#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdarg.h>

struct connection {
	char * agent;
	char * client;
	int connection_id;
	int uid;
};

struct gate {
	struct mread_pool * pool;
	const char * watchdog;
	int id_index;
	int cap;
	int max_connection;
	struct connection ** agent;
	struct connection * map;
};

struct gate *
gate_create(void) {
	struct gate * g = malloc(sizeof(*g));
	g->pool = NULL;
	g->max_connection = 0;
	g->agent = NULL;
	return g;
}

static inline struct connection * 
_id_to_agent(struct gate *g,int uid) {
	return g->agent[uid & (g->cap - 1)];
}

static void
_parm(char *msg, int sz, int command_sz) {
	while (command_sz < sz) {
		if (msg[command_sz] != ' ')
			break;
		++command_sz;
	}
	int i;
	for (i=command_sz;i<sz;i++) {
		msg[i-command_sz] = msg[i];
	}
	msg[i-command_sz] = '\0';
}

static void
_forward_agent(struct gate * g, int id, const char * agentaddr, const char *clientaddr) {
	struct connection * agent = _id_to_agent(g,id);
	if (agent->agent) {
		free(agent->agent);
	}
	agent->agent = strdup(agentaddr);
	if (agent->client) {
		free(agent->client);
	}
	agent->client = strdup(clientaddr);
}

static void
_ctrl(struct skynet_context * ctx, struct gate * g, const void * msg, int sz) {
	char tmp[sz+1];
	memcpy(tmp, msg, sz);
	tmp[sz] = '\0';
	char * command = tmp;
	int i;
	if (sz == 0)
		return;
	for (i=0;i<sz;i++) {
		if (command[i]==' ') {
			break;
		}
	}
	if (memcmp(command,"kick",i)==0) {
		_parm(tmp, sz, i);
		int uid = strtol(command , NULL, 10);
		struct connection * agent = _id_to_agent(g,uid);
		int connection_id = agent->connection_id;

		mread_close_client(g->pool,connection_id);
		return;
	}
	if (memcmp(command,"forward",i)==0) {
		_parm(tmp, sz, i);
		char * client = tmp;
		char * idstr = strsep(&client, " ");
		if (client == NULL) {
			return;
		}
		int id = strtol(idstr , NULL, 10);
		char * agent = strsep(&client, " ");
		if (client == NULL) {
			return;
		}
		_forward_agent(g, id, agent, client);
		return;
	}
	skynet_error(ctx, "[gate] Unkown command : %s", command);
}

static void
_report(struct gate *g, struct skynet_context * ctx, const char * data, ...) {
	va_list ap;
	va_start(ap, data);
	char tmp[1024];
	int n = vsnprintf(tmp, sizeof(tmp), data, ap);
	va_end(ap);

	skynet_send(ctx, NULL, g->watchdog, 0, tmp, n, 0);
}

static void
_forward(struct skynet_context * ctx,struct gate *g, int uid, void * data, size_t len) {
	struct connection * agent = _id_to_agent(g,uid);
	if (agent->agent) {
		// todo: client package has not session , send 0x7fffffff
		skynet_send(ctx, agent->client, agent->agent, 0x7fffffff, data, len, 0);
	} else {
		char * tmp = malloc(len + 32);
		int n = snprintf(tmp,len+32,"%d data ",uid);
		memcpy(tmp+n,data,len);
		skynet_send(ctx, NULL, g->watchdog, 0, tmp, len + n, DONTCOPY);
	}
}

static int
_gen_id(struct gate * g, int connection_id) {
	int uid = ++g->id_index;
	int i;
	for (i=0;i<g->cap;i++) {
		int hash = (uid + i) & (g->cap - 1);
		if (g->agent[hash] == NULL) {
			uid = uid + i;
			struct connection * conn = &g->map[connection_id];
			conn->uid = uid;
			g->agent[hash] = conn;
			g->id_index = uid;
			return uid;
		}
	}
	assert(0);
}

{'fraction_non_alphanumeric': 0.17544357700496807, 'fraction_numerical': 0.0099361249112846, 'mean_word_length': 3.7899388171312034, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 79, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3979322', 'n_tokens_mistral': 3044, 'n_tokens_neox': 2850, 'n_words': 712}