package selection_queries import ( "encoding/json" "fmt" "sort" "strings" ) func nodeKey(termType, iri string) string { return termType + "\x00" + iri } func valuesTerm(n NodeRef) string { if n.TermType == "uri" { if n.IRI == "" { return "" } return "<" + n.IRI + ">" } if n.TermType == "bnode" { if n.IRI == "" { return "" } if strings.HasPrefix(n.IRI, "_:") { return n.IRI } return "_:" + n.IRI } return "" } func termKeyFromSparqlTerm(term sparqlTerm, includeBNodes bool) (string, bool) { if term.Type == "" || term.Value == "" { return "", false } if term.Type == "literal" { return "", false } if term.Type == "bnode" { if !includeBNodes { return "", false } return nodeKey("bnode", "_:"+term.Value), true } if term.Type == "uri" { return nodeKey("uri", term.Value), true } return "", false } func selectedNodesFromIDs(idx Index, selectedIDs []uint32, includeBNodes bool) ([]NodeRef, map[uint32]struct{}) { out := make([]NodeRef, 0, len(selectedIDs)) set := make(map[uint32]struct{}, len(selectedIDs)) for _, nid := range selectedIDs { n, ok := idx.IDToNode[nid] if !ok { continue } if n.TermType == "bnode" && !includeBNodes { continue } out = append(out, n) set[nid] = struct{}{} } return out, set } 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[uint32]struct{}) for _, b := range res.Results.Bindings { term, ok := b[varName] if !ok { continue } key, ok := termKeyFromSparqlTerm(term, includeBNodes) if !ok { continue } nid, ok := idx.KeyToID[key] if !ok { continue } if _, sel := selectedSet[nid]; sel { continue } neighborSet[nid] = struct{}{} } ids := make([]uint32, 0, len(neighborSet)) for nid := range neighborSet { ids = append(ids, nid) } sort.Slice(ids, func(i, j int) bool { return ids[i] < ids[j] }) return ids, nil }