High-Performance Zero-Copy Cognitive Graph for Advanced Code Analysis
The CognitiveGraph library provides a high-performance, zero-copy graph structure for advanced code analysis. The API is designed around three core concepts:
CognitiveGraphBuilderCognitiveGraphThe main entry point for reading and navigating cognitive graphs.
public sealed class CognitiveGraph : IDisposable
GetRootNode() - Returns the root SymbolNode of the graphGetNode(uint offset) - Retrieves a specific node by offsetQuery(string queryExpression) - Executes a graph queryGetSourceText() - Returns the original source code textusing var graph = new CognitiveGraph(buffer);
var rootNode = graph.GetRootNode();
var sourceText = graph.GetSourceText();
Builder class for creating cognitive graphs with zero-copy architecture.
public sealed class CognitiveGraphBuilder : IDisposable
WriteSymbolNode(...) - Creates a symbol node with propertiesWritePackedNode(...) - Creates a packed node for ambiguous parsingWriteCpgEdge(...) - Creates control/data flow edgesBuild(...) - Finalizes the graph and returns bufferusing var builder = new CognitiveGraphBuilder();
var nodeOffset = builder.WriteSymbolNode(
symbolId: 1,
nodeType: 200,
sourceStart: 0,
sourceLength: 13,
properties: properties
);
var buffer = builder.Build(nodeOffset, sourceCode);
Represents a symbol in the Abstract Syntax Tree with zero-copy access.
public readonly ref struct SymbolNode
SymbolID - Unique identifier for the symbolNodeType - Type identifier for the nodeSourceStart - Starting position in source codeSourceLength - Length of source spanIsAmbiguous - Whether this node has multiple parse interpretationsTryGetProperty(string key, out Property value) - Type-safe property accessGetPackedNodes() - Returns all parse interpretations for ambiguous nodesGetCpgEdges() - Returns control/data flow edgesGetChildNodes() - Returns child symbol nodesif (rootNode.TryGetProperty("Operator", out var op))
{
Console.WriteLine($"Operator: {op.AsString()}");
}
if (rootNode.IsAmbiguous)
{
var interpretations = rootNode.GetPackedNodes();
foreach (var interpretation in interpretations)
{
// Process each possible parse tree
}
}
Represents a specific parse interpretation for ambiguous syntax.
public readonly ref struct PackedNode
RuleID - Grammar rule identifierNodeType - Type of the parsed constructChildCount - Number of child nodesGetChildNodes() - Returns child nodes for this interpretationGetSourceSpan() - Returns source code span covered by this nodeType-safe property value accessor supporting multiple data types.
public readonly ref struct Property
Type - Property value type (PropertyValueType enum)Key - Property name/keyAsString() - Returns string value (throws if wrong type)AsInt32() - Returns 32-bit integer valueAsInt64() - Returns 64-bit integer valueAsDouble() - Returns double-precision floating point valueAsBoolean() - Returns boolean valueTryAsString(out string value) - Safe string conversionTryAsInt32(out int value) - Safe integer conversionif (node.TryGetProperty("LineNumber", out var lineProp))
{
if (lineProp.TryAsInt32(out int lineNum))
{
Console.WriteLine($"Line: {lineNum}");
}
}
Represents control flow and data flow relationships between nodes.
public readonly ref struct CpgEdge
EdgeType - Type of relationship (CpgEdgeType enum)SourceOffset - Source node offsetTargetOffset - Target node offsetLabel - Optional edge labelControlFlow - Sequential execution flowDataFlow - Variable/value dependenciesTypeHierarchy - Type inheritance relationshipsCallGraph - Function call relationshipsSupported property value types:
String - UTF-8 encoded stringInt32 - 32-bit signed integerInt64 - 64-bit signed integerDouble - Double-precision floating pointBoolean - Boolean true/falseTypes of relationships in the Code Property Graph:
ControlFlow - Program execution flowDataFlow - Data dependenciesTypeHierarchy - Type relationshipsCallGraph - Function callsThe library uses ReadOnlySpan<T> and ref struct types to provide direct memory access without allocations:
ref struct)// Builder disposal
using var builder = new CognitiveGraphBuilder();
// Automatically disposed when out of scope
// Graph disposal
using var graph = new CognitiveGraph(buffer);
// Automatically disposed when out of scope
// Memory-mapped file usage
using var mmf = MemoryMappedFile.CreateFromFile("graph.bin");
using var accessor = mmf.CreateViewAccessor();
// Resources automatically cleaned up
ArgumentException - Invalid parameters passed to methodsInvalidOperationException - Graph is in invalid stateObjectDisposedException - Attempting to use disposed objectsInvalidCastException - Type mismatch in property access// Always use try-get methods for optional data
if (node.TryGetProperty("OptionalProp", out var prop))
{
// Property exists, safe to use
}
// Check type before casting
if (prop.Type == PropertyValueType.String)
{
string value = prop.AsString();
}
// Use using statements for proper disposal
using var graph = new CognitiveGraph(buffer);
// Graph automatically disposed at end of scope
CognitiveGraphBuilder instance is single-threadedvar graph = new CognitiveGraph(buffer);
// Multiple threads can safely read from the same graph
Parallel.ForEach(nodeOffsets, offset =>
{
var node = graph.GetNode(offset);
// Process node safely in parallel
});
// 1. Build a graph
using var builder = new CognitiveGraphBuilder();
var rootOffset = builder.WriteSymbolNode(/* parameters */);
var buffer = builder.Build(rootOffset, sourceCode);
// 2. Read and navigate
using var graph = new CognitiveGraph(buffer);
var root = graph.GetRootNode();
// 3. Extract information
if (root.TryGetProperty("NodeType", out var nodeType))
{
ProcessNodeType(nodeType.AsString());
}
// 4. Navigate structure
foreach (var child in root.GetChildNodes())
{
ProcessChild(child);
}
// For very large graphs that don't fit in memory
using var mmf = MemoryMappedFile.CreateFromFile("huge-graph.bin");
using var accessor = mmf.CreateViewAccessor();
unsafe
{
byte* ptr = (byte*)accessor.SafeMemoryMappedViewHandle.DangerousGetHandle();
var span = new ReadOnlySpan<byte>(ptr, (int)accessor.Capacity);
var buffer = new CognitiveGraphBuffer(span);
using var graph = new CognitiveGraph(buffer);
// Process without loading entire file into memory
}
For more examples and advanced usage patterns, see the Examples directory in the source code.