32bit Node ID

This commit is contained in:
Oxy8
2026-03-06 16:10:52 -03:00
parent 3c487d088b
commit a0c5bec19f
11 changed files with 46 additions and 51 deletions

View File

@@ -1,4 +1,5 @@
FROM golang:1.22-alpine AS builder
ARG GO_VERSION=1.24
FROM golang:${GO_VERSION}-alpine AS builder
WORKDIR /src

View File

@@ -15,10 +15,10 @@ func graphFromSparqlBindings(
nodeLimit int,
includeBNodes bool,
) (nodes []Node, edges []Edge) {
nodeIDByKey := map[termKey]int{}
nodeIDByKey := map[termKey]uint32{}
nodeMeta := make([]termMeta, 0, min(nodeLimit, 4096))
getOrAdd := func(term sparqlTerm) (int, bool) {
getOrAdd := func(term sparqlTerm) (uint32, bool) {
if term.Type == "" || term.Value == "" {
return 0, false
}
@@ -46,7 +46,7 @@ func graphFromSparqlBindings(
if len(nodeMeta) >= nodeLimit {
return 0, false
}
nid := len(nodeMeta)
nid := uint32(len(nodeMeta))
nodeIDByKey[key] = nid
nodeMeta = append(nodeMeta, meta)
return nid, true
@@ -78,7 +78,7 @@ func graphFromSparqlBindings(
nodes = make([]Node, len(nodeMeta))
for i, m := range nodeMeta {
nodes[i] = Node{
ID: i,
ID: uint32(i),
TermType: m.termType,
IRI: m.iri,
Label: nil,

View File

@@ -40,7 +40,7 @@ func fetchGraphSnapshot(
// Layout: invert edges for hierarchy (target -> source).
hierEdges := make([][2]int, 0, len(edges))
for _, e := range edges {
hierEdges = append(hierEdges, [2]int{e.Target, e.Source})
hierEdges = append(hierEdges, [2]int{int(e.Target), int(e.Source)})
}
layers, cycleErr := levelSynchronousKahnLayers(len(nodes), hierEdges)

View File

@@ -9,7 +9,7 @@ type HealthResponse struct {
}
type Node struct {
ID int `json:"id"`
ID uint32 `json:"id"`
TermType string `json:"termType"` // "uri" | "bnode"
IRI string `json:"iri"`
Label *string `json:"label"`
@@ -18,8 +18,8 @@ type Node struct {
}
type Edge struct {
Source int `json:"source"`
Target int `json:"target"`
Source uint32 `json:"source"`
Target uint32 `json:"target"`
Predicate string `json:"predicate"`
}
@@ -55,27 +55,27 @@ type SparqlQueryRequest struct {
}
type NeighborsRequest struct {
SelectedIDs []int `json:"selected_ids"`
NodeLimit *int `json:"node_limit,omitempty"`
EdgeLimit *int `json:"edge_limit,omitempty"`
GraphQueryID *string `json:"graph_query_id,omitempty"`
SelectedIDs []uint32 `json:"selected_ids"`
NodeLimit *int `json:"node_limit,omitempty"`
EdgeLimit *int `json:"edge_limit,omitempty"`
GraphQueryID *string `json:"graph_query_id,omitempty"`
}
type NeighborsResponse struct {
SelectedIDs []int `json:"selected_ids"`
NeighborIDs []int `json:"neighbor_ids"`
SelectedIDs []uint32 `json:"selected_ids"`
NeighborIDs []uint32 `json:"neighbor_ids"`
}
type SelectionQueryRequest struct {
QueryID string `json:"query_id"`
SelectedIDs []int `json:"selected_ids"`
NodeLimit *int `json:"node_limit,omitempty"`
EdgeLimit *int `json:"edge_limit,omitempty"`
GraphQueryID *string `json:"graph_query_id,omitempty"`
QueryID string `json:"query_id"`
SelectedIDs []uint32 `json:"selected_ids"`
NodeLimit *int `json:"node_limit,omitempty"`
EdgeLimit *int `json:"edge_limit,omitempty"`
GraphQueryID *string `json:"graph_query_id,omitempty"`
}
type SelectionQueryResponse struct {
QueryID string `json:"query_id"`
SelectedIDs []int `json:"selected_ids"`
NeighborIDs []int `json:"neighbor_ids"`
QueryID string `json:"query_id"`
SelectedIDs []uint32 `json:"selected_ids"`
NeighborIDs []uint32 `json:"neighbor_ids"`
}

View File

@@ -49,9 +49,9 @@ func termKeyFromSparqlTerm(term sparqlTerm, includeBNodes bool) (string, bool) {
return "", false
}
func selectedNodesFromIDs(idx Index, selectedIDs []int, includeBNodes bool) ([]NodeRef, map[int]struct{}) {
func selectedNodesFromIDs(idx Index, selectedIDs []uint32, includeBNodes bool) ([]NodeRef, map[uint32]struct{}) {
out := make([]NodeRef, 0, len(selectedIDs))
set := make(map[int]struct{}, len(selectedIDs))
set := make(map[uint32]struct{}, len(selectedIDs))
for _, nid := range selectedIDs {
n, ok := idx.IDToNode[nid]
if !ok {
@@ -66,13 +66,13 @@ func selectedNodesFromIDs(idx Index, selectedIDs []int, includeBNodes bool) ([]N
return out, set
}
func idsFromBindings(raw []byte, varName string, idx Index, selectedSet map[int]struct{}, includeBNodes bool) ([]int, error) {
func idsFromBindings(raw []byte, varName string, idx Index, selectedSet map[uint32]struct{}, includeBNodes bool) ([]uint32, error) {
var res sparqlResponse
if err := json.Unmarshal(raw, &res); err != nil {
return nil, fmt.Errorf("failed to parse SPARQL JSON: %w", err)
}
neighborSet := make(map[int]struct{})
neighborSet := make(map[uint32]struct{})
for _, b := range res.Results.Bindings {
term, ok := b[varName]
if !ok {
@@ -92,11 +92,10 @@ func idsFromBindings(raw []byte, varName string, idx Index, selectedSet map[int]
neighborSet[nid] = struct{}{}
}
ids := make([]int, 0, len(neighborSet))
ids := make([]uint32, 0, len(neighborSet))
for nid := range neighborSet {
ids = append(ids, nid)
}
sort.Ints(ids)
sort.Slice(ids, func(i, j int) bool { return ids[i] < ids[j] })
return ids, nil
}

View File

@@ -62,10 +62,10 @@ WHERE {
`, values, bnodeFilter)
}
func runNeighbors(ctx context.Context, q Querier, idx Index, selectedIDs []int, includeBNodes bool) ([]int, error) {
func runNeighbors(ctx context.Context, q Querier, idx Index, selectedIDs []uint32, includeBNodes bool) ([]uint32, error) {
selectedNodes, selectedSet := selectedNodesFromIDs(idx, selectedIDs, includeBNodes)
if len(selectedNodes) == 0 {
return []int{}, nil
return []uint32{}, nil
}
raw, err := q.Query(ctx, neighborsQuery(selectedNodes, includeBNodes))
@@ -74,4 +74,3 @@ func runNeighbors(ctx context.Context, q Querier, idx Index, selectedIDs []int,
}
return idsFromBindings(raw, "nbr", idx, selectedSet, includeBNodes)
}

View File

@@ -40,10 +40,10 @@ WHERE {
`, values, bnodeFilter)
}
func runSubclasses(ctx context.Context, q Querier, idx Index, selectedIDs []int, includeBNodes bool) ([]int, error) {
func runSubclasses(ctx context.Context, q Querier, idx Index, selectedIDs []uint32, includeBNodes bool) ([]uint32, error) {
selectedNodes, selectedSet := selectedNodesFromIDs(idx, selectedIDs, includeBNodes)
if len(selectedNodes) == 0 {
return []int{}, nil
return []uint32{}, nil
}
raw, err := q.Query(ctx, subclassesQuery(selectedNodes, includeBNodes))
@@ -52,4 +52,3 @@ func runSubclasses(ctx context.Context, q Querier, idx Index, selectedIDs []int,
}
return idsFromBindings(raw, "nbr", idx, selectedSet, includeBNodes)
}

View File

@@ -40,10 +40,10 @@ WHERE {
`, values, bnodeFilter)
}
func runSuperclasses(ctx context.Context, q Querier, idx Index, selectedIDs []int, includeBNodes bool) ([]int, error) {
func runSuperclasses(ctx context.Context, q Querier, idx Index, selectedIDs []uint32, includeBNodes bool) ([]uint32, error) {
selectedNodes, selectedSet := selectedNodesFromIDs(idx, selectedIDs, includeBNodes)
if len(selectedNodes) == 0 {
return []int{}, nil
return []uint32{}, nil
}
raw, err := q.Query(ctx, superclassesQuery(selectedNodes, includeBNodes))
@@ -52,4 +52,3 @@ func runSuperclasses(ctx context.Context, q Querier, idx Index, selectedIDs []in
}
return idsFromBindings(raw, "nbr", idx, selectedSet, includeBNodes)
}

View File

@@ -7,14 +7,14 @@ type Querier interface {
}
type NodeRef struct {
ID int
ID uint32
TermType string // "uri" | "bnode"
IRI string
}
type Index struct {
IDToNode map[int]NodeRef
KeyToID map[string]int
IDToNode map[uint32]NodeRef
KeyToID map[string]uint32
}
type Meta struct {
@@ -24,6 +24,5 @@ type Meta struct {
type Definition struct {
Meta Meta
Run func(ctx context.Context, q Querier, idx Index, selectedIDs []int, includeBNodes bool) ([]int, error)
Run func(ctx context.Context, q Querier, idx Index, selectedIDs []uint32, includeBNodes bool) ([]uint32, error)
}

View File

@@ -12,16 +12,16 @@ func runSelectionQuery(
sparql *AnzoGraphClient,
snapshot GraphResponse,
queryID string,
selectedIDs []int,
selectedIDs []uint32,
includeBNodes bool,
) ([]int, error) {
) ([]uint32, error) {
def, ok := selectionqueries.Get(queryID)
if !ok {
return nil, fmt.Errorf("unknown query_id: %s", queryID)
}
idToNode := make(map[int]selectionqueries.NodeRef, len(snapshot.Nodes))
keyToID := make(map[string]int, len(snapshot.Nodes))
idToNode := make(map[uint32]selectionqueries.NodeRef, len(snapshot.Nodes))
keyToID := make(map[string]uint32, len(snapshot.Nodes))
for _, n := range snapshot.Nodes {
nr := selectionqueries.NodeRef{ID: n.ID, TermType: n.TermType, IRI: n.IRI}
idToNode[n.ID] = nr
@@ -30,4 +30,3 @@ func runSelectionQuery(
return def.Run(ctx, sparql, selectionqueries.Index{IDToNode: idToNode, KeyToID: keyToID}, selectedIDs, includeBNodes)
}

View File

@@ -189,7 +189,7 @@ func (s *APIServer) handleSelectionQuery(w http.ResponseWriter, r *http.Request)
writeJSON(w, http.StatusOK, SelectionQueryResponse{
QueryID: req.QueryID,
SelectedIDs: req.SelectedIDs,
NeighborIDs: []int{},
NeighborIDs: []uint32{},
})
return
}
@@ -247,7 +247,7 @@ func (s *APIServer) handleNeighbors(w http.ResponseWriter, r *http.Request) {
return
}
if len(req.SelectedIDs) == 0 {
writeJSON(w, http.StatusOK, NeighborsResponse{SelectedIDs: req.SelectedIDs, NeighborIDs: []int{}})
writeJSON(w, http.StatusOK, NeighborsResponse{SelectedIDs: req.SelectedIDs, NeighborIDs: []uint32{}})
return
}