---
name: graph_spatial_hash
kind: function
lang: cpp
domain: core
version: "1.0.0"
purity: pure
signature: "SpatialHash(float cell_size, int table_size)"
description: "Spatial hash grid para busqueda O(1) de puntos por posicion, usado para hit-testing de nodos en grafos"
tags: [spatial, hash, acceleration, graph, query, hittest]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "cpp/functions/core/graph_spatial_hash.cpp"
framework: imgui
params:
  - name: cell_size
    desc: "Tamaño de cada celda del grid espacial (debe ser >= radio maximo de nodos)"
  - name: table_size
    desc: "Numero de buckets en la tabla hash (potencia de 2 recomendada para distribucion uniforme)"
output: "Estructura de hash espacial lista para queries de puntos cercanos"
---

# graph_spatial_hash

Spatial hash grid para busqueda eficiente de nodos en grafos por posicion 2D. Util para hit-testing de nodos en editores de grafos basados en ImGui, donde se necesita saber que nodo esta bajo el cursor en cada frame.

## Uso

```cpp
SpatialHash sh(20.0f, 4096);

// Reconstruir cada frame (o cuando cambian posiciones)
sh.build(node_xs, node_ys, node_sizes, node_count);

// Hit-test: nodo mas cercano al cursor
float dist;
int hovered = sh.query_nearest(mouse_x, mouse_y, 30.0f, &dist);

// Seleccion por area: todos los nodos dentro de un radio
int results[256];
int count = sh.query_radius(center_x, center_y, radius, results, 256);
```

## Estructura interna

- `buckets[table_size]`: cada entrada contiene el indice del primer slot de la cadena, o -1 si el bucket esta vacio.
- `entries[2 * entry_capacity]`: pares `[node_index, next_in_chain]` almacenados como flat array. Se expande con `realloc` si el numero de nodos supera la capacidad inicial (256).
- El snapshot de posiciones (`xs`, `ys`, `sizes`) se copia internamente en `build()` para que `query_nearest` y `query_radius` puedan calcular distancias sin recibir los arrays como parametro.

## Hash function

```
hash(cx, cy) = (cx * 73856093 ^ cy * 19349663) % table_size
```

Donde `cx = floor(x / cell_size)`, `cy = floor(y / cell_size)`.

## Notas

- No es thread-safe: disenado para uso single-threaded en el hilo de render de ImGui.
- `build()` debe llamarse cada frame si las posiciones de los nodos cambian.
- `cell_size` debe ser >= al radio maximo de los nodos para que la vecindad 3x3 capture todos los candidatos posibles.
- La distancia efectiva al nodo se calcula como `dist(centro) - size`, de modo que el hit-test funciona correctamente para nodos de distintos tamaños.
- No implementa `operator=` ni copy constructor (deleted) para evitar doble-free de los arrays internos.
