Skip to content

Instantly share code, notes, and snippets.

@matiasinsaurralde
Created November 19, 2021 01:32
Show Gist options
  • Save matiasinsaurralde/5682fc0b00253c01ede4e373caf24868 to your computer and use it in GitHub Desktop.
Save matiasinsaurralde/5682fc0b00253c01ede4e373caf24868 to your computer and use it in GitHub Desktop.
souffle
package main
import (
"fmt"
"runtime"
"github.com/cwarden/souffle-go-example/SwigInterface"
)
var (
// Use a channel to pass data from the Souffle program
// Can be modified to be a slice or whatever data type you require
// The channel will be initialized on main
ch chan int64
)
func callSouffle() {
// Not sure if instantiating multiple times is something that works in this context
// I've simplified the scenario and focused the scenario on a single instance for now:
p := SwigInterface.NewInstance("example")
p.SetNumThreads(int64(runtime.NumCPU()))
if p.Swigcptr() == 0 {
panic("Souffle program not found")
}
p.LoadAll(".")
edges := p.GetRelation("edge")
edges.Purge()
t := edges.NewTuple()
t.PutInteger(4)
t.PutInteger(5)
t.Insert()
SwigInterface.DeleteSWIGSouffleTuple(t)
t = edges.NewTuple()
t.PutInteger(5)
t.PutInteger(6)
t.Insert()
SwigInterface.DeleteSWIGSouffleTuple(t)
t = edges.NewTuple()
t.PutInteger(1)
t.PutInteger(4)
t.Insert()
SwigInterface.DeleteSWIGSouffleTuple(t)
SwigInterface.DeleteSWIGSouffleRelation(edges)
p.Run()
paths := p.GetRelation("path")
arity := paths.GetArity()
size := paths.Size()
// Not sure how you use this value, I've added this condition
// to avoid Golang compiler errors:
if arity == 0 {
}
var i, j uint
for i = 0; i < size; i++ {
tuple := paths.Next()
tuple.GetInteger(j)
n := tuple.GetInteger(j)
// Here I'm just writing the tuple.GetInteger value to the channel
ch <- n
SwigInterface.DeleteSWIGSouffleTuple(tuple)
}
SwigInterface.DeleteSWIGSouffleRelation(paths)
SwigInterface.DeleteSWIGSouffleProgram(p)
// Write -1 to the channel as a way of signaling that callSouffle finished:
ch <- -1
}
func main() {
// Initialize the channel:
ch = make(chan int64)
// Close the channel when this main function ends:
defer close(ch)
// Use a goroutine to handle everything:
go callSouffle()
// This main loop would just wait for data to be available on the channel:
for {
n := <-ch
if n == -1 {
fmt.Println("Got -1, closing the channel, main program returns")
break
}
// Use incoming n values:
// fmt.Println("Got:", n)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment