Skip to content

Commit

Permalink
Ajustes Finais - Parte 4
Browse files Browse the repository at this point in the history
  • Loading branch information
jprtenorio00 committed Mar 2, 2024
1 parent 1793ed8 commit 8c7cd17
Show file tree
Hide file tree
Showing 4 changed files with 4 additions and 43 deletions.
Binary file not shown.
17 changes: 1 addition & 16 deletions src/data_sctructures.py
Original file line number Diff line number Diff line change
@@ -1,88 +1,73 @@
class Tupla:
"""Representa uma tupla, contendo a chave de busca e os dados associados."""
def __init__(self, chave, dados):
self.chave = chave
self.dados = dados

class Pagina:
"""Representa uma página, que armazena um conjunto limitado de tuplas."""
def __init__(self, tamanho_max):
self.tamanho_max = tamanho_max
self.tuplas = []

def adicionar_tupla(self, tupla):
"""Adiciona uma tupla à página se houver espaço disponível."""
if len(self.tuplas) < self.tamanho_max:
self.tuplas.append(tupla)
return True
return False

class Bucket:
"""Representa um bucket no índice hash, que pode armazenar múltiplas tuplas."""
def __init__(self):
self.entradas = []

def adicionar_entrada(self, tupla):
"""Adiciona uma tupla ao bucket."""
self.entradas.append(tupla)

class Tabela:
"""Representa a tabela completa, contendo páginas de tuplas e buckets para o índice hash."""
def __init__(self, tamanho_pagina):
self.tamanho_pagina = tamanho_pagina
self.paginas = []
self.buckets = []
self.num_buckets = 0

def adicionar_tupla(self, tupla):
"""Adiciona uma tupla à tabela, em uma nova página se necessário."""
if not self.paginas or not self.paginas[-1].adicionar_tupla(tupla):
nova_pagina = Pagina(self.tamanho_pagina)
nova_pagina.adicionar_tupla(tupla)
self.paginas.append(nova_pagina)

def inicializar_buckets(self, num_buckets):
"""Inicializa os buckets com base em um número especificado."""
self.num_buckets = num_buckets
self.buckets = [Bucket() for _ in range(num_buckets)]

def funcao_hash(self, chave):
"""Calcula o índice do bucket para uma dada chave usando uma função hash simples."""
return hash(chave) % self.num_buckets

def construir_indice(self):
"""Constrói o índice hash mapeando cada tupla para um bucket com base na chave."""
self.inicializar_buckets(self.calcular_num_buckets())
for pagina in self.paginas:
for tupla in pagina.tuplas:
indice_bucket = self.funcao_hash(tupla.chave)
self.buckets[indice_bucket].adicionar_entrada(tupla)

def buscar(self, chave):
"""Busca tuplas correspondentes à chave fornecida e retorna suas referências de página."""
indice_bucket = self.funcao_hash(chave)
bucket = self.buckets[indice_bucket]
return [(tupla, self.encontrar_pagina_ref(tupla)) for tupla in bucket.entradas if tupla.chave == chave]

def table_scan(self, limite):
"""Realiza um table scan limitado, retornando as primeiras 'limite' tuplas."""
return [tupla for pagina in self.paginas for tupla in pagina.tuplas][:limite]

def calcular_estatisticas(self):
"""Calcula estatísticas sobre o índice, como total de entradas e taxa de colisões."""
total_entradas = sum(len(bucket.entradas) for bucket in self.buckets)
colisoes = sum(len(bucket.entradas) - 1 for bucket in self.buckets if len(bucket.entradas) > 1)
taxa_colisoes = colisoes / total_entradas if total_entradas > 0 else 0
return {'total_entradas': total_entradas, 'total_colisoes': colisoes, 'taxa_colisoes': taxa_colisoes}

def calcular_num_buckets(self):
"""Calcula o número ideal de buckets com base no número total de tuplas e um fator de carga."""
NR = sum(len(pagina.tuplas) for pagina in self.paginas)
FR = 10 # Fator de carga desejado (número de tuplas por bucket)
FR = 10
return max(NR // FR, 1)

def encontrar_pagina_ref(self, tupla):
"""Encontra a referência da página para uma dada tupla."""
for i, pagina in enumerate(self.paginas):
if tupla in pagina.tuplas:
return i
Expand Down
19 changes: 3 additions & 16 deletions src/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,20 @@
class HashIndexGUI:
def __init__(self, root):
self.root = root
self.tabela = Tabela(tamanho_pagina=100) # Valor padrão, pode ser alterado pelo usuário
self.tabela = Tabela(tamanho_pagina=100)
self.setup_gui()

def setup_gui(self):
"""Configura os elementos da interface gráfica e os dispõe na janela."""
self.root.title("Índice Hash Estático")
self.root.geometry("1024x768")

# Configuração dos widgets e layout aqui
self.setup_load_frame()
self.setup_page_size_frame()
self.setup_search_frame()
self.setup_table_scan_frame()
self.setup_stats_display()

def setup_load_frame(self):
"""Configura o frame para carregar dados."""
load_frame = tk.Frame(self.root)
load_frame.pack(pady=10)

Expand All @@ -32,7 +29,6 @@ def setup_load_frame(self):
self.load_status.pack(side=tk.LEFT, padx=10)

def setup_page_size_frame(self):
"""Configura o frame para definir o tamanho da página."""
page_size_frame = tk.Frame(self.root)
page_size_frame.pack(pady=10)

Expand All @@ -45,7 +41,6 @@ def setup_page_size_frame(self):
set_page_size_button.pack(side=tk.LEFT, padx=10)

def setup_search_frame(self):
"""Configura o frame para buscar tuplas."""
search_frame = tk.Frame(self.root)
search_frame.pack(pady=10)

Expand All @@ -59,7 +54,6 @@ def setup_search_frame(self):
self.search_result.pack(pady=10)

def setup_table_scan_frame(self):
"""Configura o frame para o Table Scan."""
table_scan_frame = tk.Frame(self.root)
table_scan_frame.pack(pady=10)

Expand All @@ -73,7 +67,6 @@ def setup_table_scan_frame(self):
self.table_scan_text.pack(pady=10)

def setup_stats_display(self):
"""Configura a exibição de estatísticas."""
stats_label = tk.Label(self.root, text="Estatísticas:")
stats_label.pack(pady=10)

Expand All @@ -84,7 +77,6 @@ def setup_stats_display(self):
stats_button.pack(pady=10)

def load_data(self):
"""Carrega dados de um arquivo selecionado pelo usuário."""
filename = filedialog.askopenfilename(filetypes=(("Text files", "*.txt"), ("All files", "*.*")))
if filename:
try:
Expand All @@ -100,15 +92,13 @@ def load_data(self):
messagebox.showerror("Erro ao Carregar", f"Ocorreu um erro ao carregar o arquivo: {e}")

def set_page_size(self):
"""Define o tamanho da página com base na entrada do usuário."""
try:
valor = self.page_size_var.get()
messagebox.showinfo("Tamanho da Página", f"Tamanho da página definido como {valor}.")
except ValueError:
messagebox.showerror("Erro", "Por favor, insira um número inteiro válido.")

def search(self):
"""Realiza a busca por uma chave e atualiza a GUI com os resultados encontrados."""
query = self.search_entry.get()
resultados = self.tabela.buscar(query)

Expand All @@ -123,27 +113,24 @@ def search(self):
self.search_result.config(text="Nenhum resultado encontrado.")

def table_scan(self):
"""Realiza um table scan baseado no limite especificado pelo usuário e atualiza a GUI com os resultados."""
try:
limit = int(self.table_scan_entry.get())
resultados = self.tabela.table_scan(limit)

self.table_scan_text.delete('1.0', tk.END) # Limpa o texto anterior
self.table_scan_text.delete('1.0', tk.END)
for tupla in resultados:
self.table_scan_text.insert(tk.END, f"Chave: '{tupla.chave}'\n")
except ValueError:
messagebox.showerror("Erro", "Por favor, insira um número inteiro válido para o limite.")

def show_statistics(self):
"""Calcula estatísticas do índice hash e atualiza a GUI com essas informações."""
estatisticas = self.tabela.calcular_estatisticas()

self.stats_text.delete('1.0', tk.END) # Limpa o texto anterior
self.stats_text.delete('1.0', tk.END)
self.stats_text.insert(tk.END, f"Total de Entradas: {estatisticas['total_entradas']}\n")
self.stats_text.insert(tk.END, f"Total de Colisões: {estatisticas['total_colisoes']}\n")
self.stats_text.insert(tk.END, f"Taxa de Colisões: {estatisticas['taxa_colisoes'] * 100:.2f}%\n")


def setup_gui(root):
HashIndexGUI(root)

Expand Down
11 changes: 0 additions & 11 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,9 @@
from gui import setup_gui

def main():
"""
Função principal que inicializa a janela principal do Tkinter e configura a interface gráfica do usuário (GUI).
"""
# Cria a janela principal
root = tk.Tk()

# Configura a GUI dentro da janela principal
setup_gui(root)

# Inicia o loop principal da interface gráfica
# Isso mantém a janela aberta e responsiva aos eventos do usuário
root.mainloop()

if __name__ == "__main__":
# Garante que este script só execute a função main quando executado diretamente,
# e não quando importado como um módulo.
main()

0 comments on commit 8c7cd17

Please sign in to comment.