Skip to content

Commit

Permalink
feat: matrix package
Browse files Browse the repository at this point in the history
  • Loading branch information
williamfzc committed Oct 4, 2023
1 parent f3f325b commit 10f1ebd
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 0 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require (
github.com/stretchr/testify v1.8.2
github.com/urfave/cli/v2 v2.25.1
github.com/vmihailenco/msgpack/v5 v5.3.5
gonum.org/v1/gonum v0.14.0
google.golang.org/protobuf v1.30.0
)

Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0=
gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
Expand Down
100 changes: 100 additions & 0 deletions matrix/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package matrix

import (
"github.com/dominikbraun/graph"
"github.com/williamfzc/srctx/graph/common"
"gonum.org/v1/gonum/mat"
)

const (
InvalidIndex = -1
InvalidValue = -1.0
)

/*
Matrix
Standard relationship representation layer based on matrix
*/
type Matrix struct {
IndexMap map[string]int
ReverseIndexMap map[int]string
Data *mat.Dense
}

func (m *Matrix) Size() int {
return len(m.IndexMap)
}

func (m *Matrix) Id(s string) int {
if item, ok := m.IndexMap[s]; ok {
return item
}
return InvalidIndex
}

func (m *Matrix) ById(id int) string {
if item, ok := m.ReverseIndexMap[id]; ok {
return item
}
return ""
}

func (m *Matrix) ForEach(s string, f func(i int, v float64)) {
index := m.Id(s)
if index == InvalidIndex {
return
}

for i := 0; i < m.Size(); i++ {
f(i, m.Data.At(i, index))
}
}

func CreateMatrixFromGraph[T string, U any](g graph.Graph[T, U]) (*Matrix, error) {
adjacencyMap, err := g.AdjacencyMap()
if err != nil {
return nil, err
}

nodeCount := len(adjacencyMap)
data := mat.NewDense(nodeCount, nodeCount, nil)

indexMap := make(map[string]int)
i := 0
for node := range adjacencyMap {
indexMap[string(node)] = i
i++
}

for source, edges := range adjacencyMap {
sourceIndex := indexMap[string(source)]

data.Set(sourceIndex, sourceIndex, float64(len(edges)))

for target, edge := range edges {
storage := edge.Properties.Data.(*common.EdgeStorage)
targetIndex := indexMap[string(target)]

currentValue := data.At(targetIndex, sourceIndex)
data.Set(targetIndex, sourceIndex, currentValue+float64(len(storage.RefLines)))
}
}

ret := &Matrix{
IndexMap: indexMap,
ReverseIndexMap: reverseMap(indexMap),
Data: data,
}
return ret, nil
}

func reverseMap(originalMap map[string]int) map[int]string {
reversedMap := make(map[int]string)

for key, value := range originalMap {
reversedMap[value] = key
}

return reversedMap
}
33 changes: 33 additions & 0 deletions matrix/api_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package matrix

import (
"path/filepath"
"runtime"
"testing"

log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/williamfzc/srctx/graph/common"
"github.com/williamfzc/srctx/graph/file"
)

func TestMatrix(t *testing.T) {
_, curFile, _, _ := runtime.Caller(0)
src := filepath.Dir(filepath.Dir(curFile))
opts := common.DefaultGraphOptions()
opts.Src = src
opts.LsifFile = filepath.Join(src, "dump.lsif")
fileGraph, err := file.CreateFileGraphFromDirWithLSIF(opts)
assert.Nil(t, err)

t.Run("test_a", func(t *testing.T) {
matrixFromGraph, err := CreateMatrixFromGraph(fileGraph.G)
assert.Nil(t, err)
assert.NotEmpty(t, matrixFromGraph)

targetFile := "graph/common/edge.go"
matrixFromGraph.ForEach(targetFile, func(i int, v float64) {
log.Infof("%s value: %v", matrixFromGraph.ById(i), v)
})
})
}

0 comments on commit 10f1ebd

Please sign in to comment.