Skip to content
Snippets Groups Projects
Commit da880620 authored by Eduardo Souza's avatar Eduardo Souza
Browse files

Primeiro commit

parents
No related branches found
No related tags found
No related merge requests found
a.out 0 → 100644
File added
t2.c 0 → 100644
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define TAM_MAX_FINGER 32
// Estrutura para armazenar um nó na DHT
typedef struct Node {
int id;
int *finger; //array para a tabela finger
int *keys; //array para as chaves armazenadas
int key_count;
struct Node* next;
} Node;
typedef struct DHT {
Node* head;
int max_id;
} DHT;
// Função para criar um novo nó
Node* create_node(int id, int max_id) {
Node* node = (Node*)malloc(sizeof(Node));
node->id = id;
node->key_count = 0;
node->finger = (int*)malloc(TAM_MAX_FINGER* 10 * sizeof(int));
//O tamanho do array de chave é calculado por id - 1 < k <= id
node->keys = (int*)malloc((id - 1)*sizeof(int));
node->next = NULL;
return node;
}
// Função para inserir um nó na DHT (circular e ordenado)
Node *insert_node(Node *head, int id, int max_id) {
Node* new_node = create_node(id, max_id);
if (head == NULL) {
new_node->next = new_node;
return new_node;
}
Node* current = head;
Node* prev = NULL;
do {
prev = current;
current = current->next;
} while (current != head && current->id < id);
if (current->id == id) {
return head;
}
if (prev) {
prev->next = new_node;
} else {
head = new_node;
}
new_node->next = current;
return head;
}
void imprime_lista(Node* head) {
Node* current = head;
do {
printf("%d -> ", current->id);
current = current->next;
} while (current != head);
}
void transfer_keys(Node* from, Node* to) {
int* new_keys = (int*)malloc((from->key_count + to->key_count) * sizeof(int));
for (int i = 0; i < to->key_count; i++) {
new_keys[i] = to->keys[i];
}
for (int i = 0; i < from->key_count; i++) {
new_keys[to->key_count + i] = from->keys[i];
}
free(to->keys);
to->keys = new_keys;
to->key_count += from->key_count;
}
Node* remove_node(Node* head, int id) {
if (head == NULL) {
return NULL; // Lista vazia
}
Node* current = head;
Node* prev = NULL;
// Caso especial: o nó a ser removido é o nó cabeça
if (head->id == id) {
if (head->next == head) {
// A lista contém apenas um nó
free(head);
return NULL;
} else {
// Encontrar o último nó para atualizar seu ponteiro
Node* last = head;
while (last->next != head) {
last = last->next;
}
last->next = head->next;
Node* new_head = head->next;
transfer_keys(head, new_head);
free(head);
return new_head;
}
}
// Percorrer a lista para encontrar o nó a ser removido
do {
prev = current;
current = current->next;
} while (current != head && current->id != id);
if (current->id == id) {
prev->next = current->next;
free(current);
}
return head;
}
// Função para calcular a tabela finger
void calculate_finger_table(Node* head, int max_id) {
Node* current = head;
printf("Max_id:%d\n", max_id);
int log2_max_id = ceil(log2(max_id));
printf("Log2_max_id:%d\n", log2_max_id);
do {
for (int k = 1; k <= log2_max_id; k++) {
printf("N:%d", current->id);
int finger_id = (current->id + (1 << k-1)) % (1 << log2_max_id);
printf(" Finger_id:%d\n", finger_id);
Node* temp = head;
//Inserir na tabela_finger o id do nó que é o menor id maior que o id do finger_id, ou seja, o id mais próximo do finger_id
while(temp->id < finger_id && temp->next != head) {
temp = temp->next;
}
current->finger[k-1] = temp->id;
}
current = current->next;
} while (current != head);
}
// Função para imprimir todas as tabelas finger
void print_finger_table(Node* head, int timestamp) {
Node* current = head;
do {
printf("%d F %d {", timestamp, current->id);
for (int i = 0; i < TAM_MAX_FINGER; i++) {
printf("%d -> ", current->finger[i]);
}
printf("%d}\n", current->id);
current = current->next;
} while (current != head);
}
// Função para realizar lookup de uma chave
void lookup(Node* head, int timestamp, int node_id, int key) {
Node* current = head;
Node* nodes_involved[TAM_MAX_FINGER];
int nodes_count = 0;
while (current->id != node_id) {
current = current->next;
}
printf("%d L %d {", timestamp, key);
Node* start = current;
while (!(current->id - 1 < key && key <= current->id)) {
printf("%d -> ", current->id);
nodes_involved[nodes_count++] = current;
int closest_node = current->finger[0];
for (int i = 1; i < log2(TAM_MAX_FINGER); i++) {
if (current->finger[i] < key) {
closest_node = current->finger[i];
}
}
current = current->next;
if (current == start) {
break; // Prevent infinite loop
}
}
printf("%d}\n", current->id);
nodes_involved[nodes_count++] = current;
// Print finger tables of nodes involved in the lookup
// for (int i = 0; i < nodes_count; i++) {
// print_finger_table(head, timestamp, nodes_involved[i]->id);
// }
}
// Função para adicionar uma chave a um nó
void insert_key(Node* head, int node_id, int key) {
Node* current = head;
while (current->id != node_id) {
current = current->next;
}
current->keys[current->key_count++] = key;
}
// Função principal para testar a inserção de nós
int main() {
Node* dht = NULL;
int timestamp, id, key;
int max_id = 0;
char op;
while (scanf("%d %c %d %d", &timestamp, &op, &id, &key) != EOF) {
if(id > max_id) {
max_id = id;
}
if (op == 'E') {
dht = insert_node(dht, id, max_id);
calculate_finger_table(dht, max_id);
} else if (op == 'S') {
dht = remove_node(dht, id);
} else if (op == 'I') {
insert_key(dht, id, key);
} else if (op == 'L') {
lookup(dht, timestamp, id, key);
} else if (op == 'P'){
print_finger_table(dht, timestamp);
}
}
return 0;
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment