Skip to content

Instantly share code, notes, and snippets.

@Zenithar
Last active March 5, 2025 07:01
Show Gist options
  • Save Zenithar/e81a0ff9371ecdaa763419eb0b44ad4f to your computer and use it in GitHub Desktop.
Save Zenithar/e81a0ff9371ecdaa763419eb0b44ad4f to your computer and use it in GitHub Desktop.

Revisions

  1. Zenithar revised this gist Mar 5, 2025. 1 changed file with 15 additions and 0 deletions.
    15 changes: 15 additions & 0 deletions @janusgraph_adapter.go
    Original file line number Diff line number Diff line change
    @@ -43,6 +43,21 @@ func readString(data *[]byte, i *int) (interface{}, error) {
    return string((*data)[*i-sz : *i]), nil
    }

    // janusgraphRelationIdentifierReader reads a JanusGraph relation identifier from the given byte slice.
    // It expects the data to be in a specific format and returns a map containing the relation identifier details.
    //
    // The format is as follows:
    // - 4 bytes: custom data type (0x1001)
    // - 1 byte: value flag (0x00)
    // - 1 byte: outVertexId type (0x00 for long, 0x01 for string)
    // - if 0x00: 8 bytes: outVertexId (long)
    // - if 0x01: 4 bytes: outVertexId length, followed by outVertexId string
    // - 8 bytes: typeId (long)
    // - 8 bytes: relationId (long)
    // - 1 byte: inVertexId type (0x00 for long, 0x01 for string)
    // - if 0x00: 8 bytes: inVertexId (long)
    // - if 0x01: 4 bytes: inVertexId length, followed by inVertexId string
    //
    // https://github.com/JanusGraph/janusgraph-python/blob/cd812fc0614047d25a2cabd143902806a74a8465/janusgraph_python/structure/io/graphbinaryV1.py#L133
    func janusgraphRelationIdentifierReader(data *[]byte, i *int) (interface{}, error) {
    const relationIdentifierType = 0x1001
  2. Zenithar revised this gist Mar 4, 2025. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -3,6 +3,8 @@
    It registers `janusgraph.RelationIdentifier` generated by JanusGraph when trying to
    do `path().by(elementMap())` which is raising a Serialization error.

    > E0409: unknown custom data type to deserialize janusgraph.RelationIdentifier
    Linked to issues:
    * https://issues.apache.org/jira/browse/TINKERPOP-2802
    * https://issues.apache.org/jira/browse/TINKERPOP-2828
  3. Zenithar revised this gist Mar 4, 2025. 2 changed files with 0 additions and 0 deletions.
    File renamed without changes.
    File renamed without changes.
  4. Zenithar renamed this gist Mar 4, 2025. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  5. Zenithar renamed this gist Mar 4, 2025. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  6. Zenithar renamed this gist Mar 4, 2025. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  7. Zenithar created this gist Mar 4, 2025.
    8 changes: 8 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,8 @@
    # Custom JanusGraph type handler

    It registers `janusgraph.RelationIdentifier` generated by JanusGraph when trying to
    do `path().by(elementMap())` which is raising a Serialization error.

    Linked to issues:
    * https://issues.apache.org/jira/browse/TINKERPOP-2802
    * https://issues.apache.org/jira/browse/TINKERPOP-2828
    105 changes: 105 additions & 0 deletions janusgraph_adapter.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,105 @@
    package gremlin

    import (
    "encoding/binary"
    "errors"
    "fmt"

    gremlingo "github.com/apache/tinkerpop/gremlin-go/v3/driver"
    )

    const (
    valueFlagNone byte = 0
    )

    func readTemp(data *[]byte, i *int, len int) *[]byte {
    tmp := make([]byte, len)
    for j := 0; j < len; j++ {
    tmp[j] = (*data)[j+*i]
    }
    *i += len
    return &tmp
    }

    func readUint32Safe(data *[]byte, i *int) uint32 {
    return binary.BigEndian.Uint32(*readTemp(data, i, 4))
    }

    func readByteSafe(data *[]byte, i *int) byte {
    *i++
    return (*data)[*i-1]
    }

    func readLongSafe(data *[]byte, i *int) int64 {
    return int64(binary.BigEndian.Uint64(*readTemp(data, i, 8)))
    }

    func readString(data *[]byte, i *int) (interface{}, error) {
    sz := int(readUint32Safe(data, i))
    if sz == 0 {
    return "", nil
    }
    *i += sz
    return string((*data)[*i-sz : *i]), nil
    }

    // https://github.com/JanusGraph/janusgraph-python/blob/cd812fc0614047d25a2cabd143902806a74a8465/janusgraph_python/structure/io/graphbinaryV1.py#L133
    func janusgraphRelationIdentifierReader(data *[]byte, i *int) (interface{}, error) {
    const relationIdentifierType = 0x1001
    const (
    longMarker = 0
    stringMarker = 1
    )

    // expect type code
    customDataTyp := readUint32Safe(data, i)
    if customDataTyp != relationIdentifierType {
    return nil, fmt.Errorf("unknown type code. got 0x%x, expected 0x%x", customDataTyp, relationIdentifierType)
    }

    // value flag, expect this to be non-nullable
    if readByteSafe(data, i) != valueFlagNone {
    return nil, errors.New("expected non-null value")
    }

    // outVertexId
    var (
    outVertexID any
    err error
    )
    if readByteSafe(data, i) == stringMarker {
    outVertexID, err = readString(data, i)
    if err != nil {
    return nil, fmt.Errorf("unable to read outVertexId: %w", err)
    }
    } else {
    outVertexID = readLongSafe(data, i)
    }

    typeID := readLongSafe(data, i)
    // relationID
    relationID := readLongSafe(data, i)

    // inVertexId
    var inVertexID any
    if readByteSafe(data, i) == stringMarker {
    inVertexID, err = readString(data, i)
    if err != nil {
    return nil, fmt.Errorf("unable to read inVertexId: %w", err)
    }
    } else {
    inVertexID = readLongSafe(data, i)
    }

    return map[string]any{
    "outVertexId": outVertexID,
    "typeId": typeID,
    "relationId": relationID,
    "inVertexId": inVertexID,
    }, nil
    }

    func init() {
    // https://issues.apache.org/jira/browse/TINKERPOP-2802
    gremlingo.RegisterCustomTypeReader("janusgraph.RelationIdentifier", janusgraphRelationIdentifierReader)
    }