32bit Node ID
This commit is contained in:
@@ -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
|
WORKDIR /src
|
||||||
|
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ func graphFromSparqlBindings(
|
|||||||
nodeLimit int,
|
nodeLimit int,
|
||||||
includeBNodes bool,
|
includeBNodes bool,
|
||||||
) (nodes []Node, edges []Edge) {
|
) (nodes []Node, edges []Edge) {
|
||||||
nodeIDByKey := map[termKey]int{}
|
nodeIDByKey := map[termKey]uint32{}
|
||||||
nodeMeta := make([]termMeta, 0, min(nodeLimit, 4096))
|
nodeMeta := make([]termMeta, 0, min(nodeLimit, 4096))
|
||||||
|
|
||||||
getOrAdd := func(term sparqlTerm) (int, bool) {
|
getOrAdd := func(term sparqlTerm) (uint32, bool) {
|
||||||
if term.Type == "" || term.Value == "" {
|
if term.Type == "" || term.Value == "" {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ func graphFromSparqlBindings(
|
|||||||
if len(nodeMeta) >= nodeLimit {
|
if len(nodeMeta) >= nodeLimit {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
nid := len(nodeMeta)
|
nid := uint32(len(nodeMeta))
|
||||||
nodeIDByKey[key] = nid
|
nodeIDByKey[key] = nid
|
||||||
nodeMeta = append(nodeMeta, meta)
|
nodeMeta = append(nodeMeta, meta)
|
||||||
return nid, true
|
return nid, true
|
||||||
@@ -78,7 +78,7 @@ func graphFromSparqlBindings(
|
|||||||
nodes = make([]Node, len(nodeMeta))
|
nodes = make([]Node, len(nodeMeta))
|
||||||
for i, m := range nodeMeta {
|
for i, m := range nodeMeta {
|
||||||
nodes[i] = Node{
|
nodes[i] = Node{
|
||||||
ID: i,
|
ID: uint32(i),
|
||||||
TermType: m.termType,
|
TermType: m.termType,
|
||||||
IRI: m.iri,
|
IRI: m.iri,
|
||||||
Label: nil,
|
Label: nil,
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ func fetchGraphSnapshot(
|
|||||||
// Layout: invert edges for hierarchy (target -> source).
|
// Layout: invert edges for hierarchy (target -> source).
|
||||||
hierEdges := make([][2]int, 0, len(edges))
|
hierEdges := make([][2]int, 0, len(edges))
|
||||||
for _, e := range 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)
|
layers, cycleErr := levelSynchronousKahnLayers(len(nodes), hierEdges)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ type HealthResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Node struct {
|
type Node struct {
|
||||||
ID int `json:"id"`
|
ID uint32 `json:"id"`
|
||||||
TermType string `json:"termType"` // "uri" | "bnode"
|
TermType string `json:"termType"` // "uri" | "bnode"
|
||||||
IRI string `json:"iri"`
|
IRI string `json:"iri"`
|
||||||
Label *string `json:"label"`
|
Label *string `json:"label"`
|
||||||
@@ -18,8 +18,8 @@ type Node struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Edge struct {
|
type Edge struct {
|
||||||
Source int `json:"source"`
|
Source uint32 `json:"source"`
|
||||||
Target int `json:"target"`
|
Target uint32 `json:"target"`
|
||||||
Predicate string `json:"predicate"`
|
Predicate string `json:"predicate"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,27 +55,27 @@ type SparqlQueryRequest struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type NeighborsRequest struct {
|
type NeighborsRequest struct {
|
||||||
SelectedIDs []int `json:"selected_ids"`
|
SelectedIDs []uint32 `json:"selected_ids"`
|
||||||
NodeLimit *int `json:"node_limit,omitempty"`
|
NodeLimit *int `json:"node_limit,omitempty"`
|
||||||
EdgeLimit *int `json:"edge_limit,omitempty"`
|
EdgeLimit *int `json:"edge_limit,omitempty"`
|
||||||
GraphQueryID *string `json:"graph_query_id,omitempty"`
|
GraphQueryID *string `json:"graph_query_id,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type NeighborsResponse struct {
|
type NeighborsResponse struct {
|
||||||
SelectedIDs []int `json:"selected_ids"`
|
SelectedIDs []uint32 `json:"selected_ids"`
|
||||||
NeighborIDs []int `json:"neighbor_ids"`
|
NeighborIDs []uint32 `json:"neighbor_ids"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SelectionQueryRequest struct {
|
type SelectionQueryRequest struct {
|
||||||
QueryID string `json:"query_id"`
|
QueryID string `json:"query_id"`
|
||||||
SelectedIDs []int `json:"selected_ids"`
|
SelectedIDs []uint32 `json:"selected_ids"`
|
||||||
NodeLimit *int `json:"node_limit,omitempty"`
|
NodeLimit *int `json:"node_limit,omitempty"`
|
||||||
EdgeLimit *int `json:"edge_limit,omitempty"`
|
EdgeLimit *int `json:"edge_limit,omitempty"`
|
||||||
GraphQueryID *string `json:"graph_query_id,omitempty"`
|
GraphQueryID *string `json:"graph_query_id,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SelectionQueryResponse struct {
|
type SelectionQueryResponse struct {
|
||||||
QueryID string `json:"query_id"`
|
QueryID string `json:"query_id"`
|
||||||
SelectedIDs []int `json:"selected_ids"`
|
SelectedIDs []uint32 `json:"selected_ids"`
|
||||||
NeighborIDs []int `json:"neighbor_ids"`
|
NeighborIDs []uint32 `json:"neighbor_ids"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,9 +49,9 @@ func termKeyFromSparqlTerm(term sparqlTerm, includeBNodes bool) (string, bool) {
|
|||||||
return "", false
|
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))
|
out := make([]NodeRef, 0, len(selectedIDs))
|
||||||
set := make(map[int]struct{}, len(selectedIDs))
|
set := make(map[uint32]struct{}, len(selectedIDs))
|
||||||
for _, nid := range selectedIDs {
|
for _, nid := range selectedIDs {
|
||||||
n, ok := idx.IDToNode[nid]
|
n, ok := idx.IDToNode[nid]
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -66,13 +66,13 @@ func selectedNodesFromIDs(idx Index, selectedIDs []int, includeBNodes bool) ([]N
|
|||||||
return out, set
|
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
|
var res sparqlResponse
|
||||||
if err := json.Unmarshal(raw, &res); err != nil {
|
if err := json.Unmarshal(raw, &res); err != nil {
|
||||||
return nil, fmt.Errorf("failed to parse SPARQL JSON: %w", err)
|
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 {
|
for _, b := range res.Results.Bindings {
|
||||||
term, ok := b[varName]
|
term, ok := b[varName]
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -92,11 +92,10 @@ func idsFromBindings(raw []byte, varName string, idx Index, selectedSet map[int]
|
|||||||
neighborSet[nid] = struct{}{}
|
neighborSet[nid] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
ids := make([]int, 0, len(neighborSet))
|
ids := make([]uint32, 0, len(neighborSet))
|
||||||
for nid := range neighborSet {
|
for nid := range neighborSet {
|
||||||
ids = append(ids, nid)
|
ids = append(ids, nid)
|
||||||
}
|
}
|
||||||
sort.Ints(ids)
|
sort.Slice(ids, func(i, j int) bool { return ids[i] < ids[j] })
|
||||||
return ids, nil
|
return ids, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,10 +62,10 @@ WHERE {
|
|||||||
`, values, bnodeFilter)
|
`, 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)
|
selectedNodes, selectedSet := selectedNodesFromIDs(idx, selectedIDs, includeBNodes)
|
||||||
if len(selectedNodes) == 0 {
|
if len(selectedNodes) == 0 {
|
||||||
return []int{}, nil
|
return []uint32{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
raw, err := q.Query(ctx, neighborsQuery(selectedNodes, includeBNodes))
|
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)
|
return idsFromBindings(raw, "nbr", idx, selectedSet, includeBNodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,10 +40,10 @@ WHERE {
|
|||||||
`, values, bnodeFilter)
|
`, 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)
|
selectedNodes, selectedSet := selectedNodesFromIDs(idx, selectedIDs, includeBNodes)
|
||||||
if len(selectedNodes) == 0 {
|
if len(selectedNodes) == 0 {
|
||||||
return []int{}, nil
|
return []uint32{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
raw, err := q.Query(ctx, subclassesQuery(selectedNodes, includeBNodes))
|
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)
|
return idsFromBindings(raw, "nbr", idx, selectedSet, includeBNodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,10 +40,10 @@ WHERE {
|
|||||||
`, values, bnodeFilter)
|
`, 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)
|
selectedNodes, selectedSet := selectedNodesFromIDs(idx, selectedIDs, includeBNodes)
|
||||||
if len(selectedNodes) == 0 {
|
if len(selectedNodes) == 0 {
|
||||||
return []int{}, nil
|
return []uint32{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
raw, err := q.Query(ctx, superclassesQuery(selectedNodes, includeBNodes))
|
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)
|
return idsFromBindings(raw, "nbr", idx, selectedSet, includeBNodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ type Querier interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type NodeRef struct {
|
type NodeRef struct {
|
||||||
ID int
|
ID uint32
|
||||||
TermType string // "uri" | "bnode"
|
TermType string // "uri" | "bnode"
|
||||||
IRI string
|
IRI string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Index struct {
|
type Index struct {
|
||||||
IDToNode map[int]NodeRef
|
IDToNode map[uint32]NodeRef
|
||||||
KeyToID map[string]int
|
KeyToID map[string]uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
type Meta struct {
|
type Meta struct {
|
||||||
@@ -24,6 +24,5 @@ type Meta struct {
|
|||||||
|
|
||||||
type Definition struct {
|
type Definition struct {
|
||||||
Meta Meta
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,16 +12,16 @@ func runSelectionQuery(
|
|||||||
sparql *AnzoGraphClient,
|
sparql *AnzoGraphClient,
|
||||||
snapshot GraphResponse,
|
snapshot GraphResponse,
|
||||||
queryID string,
|
queryID string,
|
||||||
selectedIDs []int,
|
selectedIDs []uint32,
|
||||||
includeBNodes bool,
|
includeBNodes bool,
|
||||||
) ([]int, error) {
|
) ([]uint32, error) {
|
||||||
def, ok := selectionqueries.Get(queryID)
|
def, ok := selectionqueries.Get(queryID)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("unknown query_id: %s", queryID)
|
return nil, fmt.Errorf("unknown query_id: %s", queryID)
|
||||||
}
|
}
|
||||||
|
|
||||||
idToNode := make(map[int]selectionqueries.NodeRef, len(snapshot.Nodes))
|
idToNode := make(map[uint32]selectionqueries.NodeRef, len(snapshot.Nodes))
|
||||||
keyToID := make(map[string]int, len(snapshot.Nodes))
|
keyToID := make(map[string]uint32, len(snapshot.Nodes))
|
||||||
for _, n := range snapshot.Nodes {
|
for _, n := range snapshot.Nodes {
|
||||||
nr := selectionqueries.NodeRef{ID: n.ID, TermType: n.TermType, IRI: n.IRI}
|
nr := selectionqueries.NodeRef{ID: n.ID, TermType: n.TermType, IRI: n.IRI}
|
||||||
idToNode[n.ID] = nr
|
idToNode[n.ID] = nr
|
||||||
@@ -30,4 +30,3 @@ func runSelectionQuery(
|
|||||||
|
|
||||||
return def.Run(ctx, sparql, selectionqueries.Index{IDToNode: idToNode, KeyToID: keyToID}, selectedIDs, includeBNodes)
|
return def.Run(ctx, sparql, selectionqueries.Index{IDToNode: idToNode, KeyToID: keyToID}, selectedIDs, includeBNodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ func (s *APIServer) handleSelectionQuery(w http.ResponseWriter, r *http.Request)
|
|||||||
writeJSON(w, http.StatusOK, SelectionQueryResponse{
|
writeJSON(w, http.StatusOK, SelectionQueryResponse{
|
||||||
QueryID: req.QueryID,
|
QueryID: req.QueryID,
|
||||||
SelectedIDs: req.SelectedIDs,
|
SelectedIDs: req.SelectedIDs,
|
||||||
NeighborIDs: []int{},
|
NeighborIDs: []uint32{},
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -247,7 +247,7 @@ func (s *APIServer) handleNeighbors(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(req.SelectedIDs) == 0 {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user