diff --git a/a.out b/a.out index de6ef6253ca9ce973828b56682fce5d0dbe456b3..1fbd779e432f2e38888994a22274d7ae67d21dee 100644 Binary files a/a.out and b/a.out differ diff --git a/t2.c b/t2.c index de73b1e7f9e175c151c873a5ae4b181d139a91f3..47928afe0e01f38cb1d2430916a4d01b8114c1af 100644 --- a/t2.c +++ b/t2.c @@ -9,9 +9,11 @@ typedef struct Node { int id; int *finger; //array para a tabela finger + int tam_finger; int *keys; //array para as chaves armazenadas int key_count; struct Node* next; + struct Node* prev; } Node; typedef struct DHT { @@ -19,6 +21,27 @@ typedef struct DHT { int max_id; } DHT; +void redistribute_keys(Node* new_node) { + Node* current = new_node; + do { + Node* next_node = current->next; + // Transferir chaves que são menores ou iguais ao id do próximo nó + for (int i = 0; i < current->key_count; i++) { + if ((current->keys[i] > current->id && current->keys[i] <= next_node->id) || + (current->id > next_node->id && (current->keys[i] > current->id || current->keys[i] <= next_node->id))) { + next_node->keys[next_node->key_count++] = current->keys[i]; + // Remover a chave do nó atual + for (int j = i; j < current->key_count - 1; j++) { + current->keys[j] = current->keys[j + 1]; + } + current->key_count--; + i--; // Reavaliar a posição atual + } + } + current = next_node; + } while (current != new_node); +} + // Função para criar um novo nó Node* create_node(int id, int max_id) { Node* node = (Node*)malloc(sizeof(Node)); @@ -28,6 +51,7 @@ Node* create_node(int id, int max_id) { //O tamanho do array de chave é calculado por id - 1 < k <= id node->keys = (int*)malloc((id - 1)*sizeof(int)); node->next = NULL; + node->prev = NULL; return node; } @@ -36,26 +60,40 @@ 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; + new_node->prev = new_node; return new_node; } - Node* current = head; Node* prev = NULL; + + // Caso especial: inserir antes do nó cabeça + if (id < head->id) { + // Encontrar o último nó para atualizar seu ponteiro + Node* last = head; + while (last->next != head) { + last = last->next; + } + last->next = new_node; + new_node->next = head; + new_node->prev = last; + head->prev = new_node; + redistribute_keys(new_node); + return new_node; // Novo nó se torna a nova cabeça + } + + // Inserir em posição ordenada 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; - } + prev->next = new_node; new_node->next = current; + new_node->prev = prev; + current->prev = new_node; + + redistribute_keys(new_node); + return head; } @@ -103,6 +141,7 @@ Node* remove_node(Node* head, int id) { last = last->next; } last->next = head->next; + head->next->prev = last; Node* new_head = head->next; transfer_keys(head, new_head); free(head); @@ -118,6 +157,8 @@ Node* remove_node(Node* head, int id) { if (current->id == id) { prev->next = current->next; + current->next->prev = prev; + transfer_keys(current, current->next); free(current); } @@ -130,6 +171,7 @@ 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)); + current->tam_finger = log2_max_id; printf("Log2_max_id:%d\n", log2_max_id); do { for (int k = 1; k <= log2_max_id; k++) { @@ -163,7 +205,8 @@ void print_finger_table(Node* head, int timestamp) { // Função para realizar lookup de uma chave -void lookup(Node* head, int timestamp, int node_id, int key) { +void lookup(Node* head, int timestamp, int node_id, int key){ + printf("ENTREI\n"); Node* current = head; Node* nodes_involved[TAM_MAX_FINGER]; int nodes_count = 0; @@ -173,37 +216,82 @@ void lookup(Node* head, int timestamp, int node_id, int key) { } 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]; + Node* start = current; //Meu nó partida + int id_aux = current->id; + printf("%d,", current->id); + + while(1){ + int found = 0; + for (int i = 0; i < current->key_count; i++) { + if (current->keys[i] == key) { + printf("%d}\n", current->id); + return; } } - current = current->next; - if (current == start) { - break; // Prevent infinite loop + //Procura o maior nó conhecido pela finger_table que precede o valor da chave + for (int i = 0; i < current->tam_finger; i++) { + if (current->finger[i] < key && current->finger[i] > id_aux) { + printf("%d,", current->finger[i]); + id_aux = current->finger[i]; + found = 1; + + } + //Se não encontrar um nó na tabela finger que preceda o valor da chave, sai do loop + if(!found){ + break; + } + + // Mover para o nó com ID id_aux + while(current->id != id_aux){ + current = current->next; } + nodes_involved[nodes_count++] = current; //Adiciona o nó atual ao array de nós envolvidos + + //Verificar se o nó atual já tem a chave + for (int i = 0; i < current->key_count; i++) { + if (current->keys[i] == key) { + printf("%d}\n", current->id); + return; + } + } + + start = current; } 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ó +// Função para adicionar uma chave a um nó respeitando o limite de um nó guarda as chaves maiores que seu antecessor e menores e iguais a ele. void insert_key(Node* head, int node_id, int key) { - Node* current = head; + Node* current = head; //Lista circular + + //Procuramos o nó com o id igual ao node_id while (current->id != node_id) { current = current->next; } - current->keys[current->key_count++] = key; + do{ + if ((current->id < current->next->id && key > current->id && key <= current->next->id) || + (current->id > current->next->id && (key > current->id || key <= current->next->id))) { + current->next->keys[current->next->key_count++] = key; + printf("Chave %d inserida no nó %d\n", key, current->id); + return; + } + current = current->next; + } while (current != head); + +} + +void imprime_chaves(Node* head) { + Node* current = head; + do { + printf("%d -> ", current->id); + for (int i = 0; i < current->key_count; i++) { + printf("%d ", current->keys[i]); + } + printf("\n"); + current = current->next; + } while (current != head); } // Função principal para testar a inserção de nós @@ -227,6 +315,7 @@ int main() { } else if (op == 'L') { lookup(dht, timestamp, id, key); } else if (op == 'P'){ + imprime_chaves(dht); print_finger_table(dht, timestamp); } }