Skip to content

Using Relations

In traditional testing, relating two entities (like a User and their Address) usually requires a database or shared state. In Pseudata, relationships are stateless—calculated mathematically from entity indices using a coordinate system.

Pseudata generates Link classes that provide a simple, type-safe API for navigating relationships. No need to worry about bits or coordinates—just call intuitive methods like homeAddress() or manager().

Create a link from an array at a specific index:

import "github.com/pseudata/pseudata"
users := pseudata.NewUserArray(42)
// Create link from index
link := users.LinkAt(1000)
// Or from an object
user := users.At(1000)
link = users.LinkFor(&user)
// Access the source object
fmt.Println(link.Me().Name)

Navigate from a user to their single home address with O(1) performance.

import "github.com/pseudata/pseudata"
users := pseudata.NewUserArray(42)
link := users.LinkAt(1000)
// Navigate to home address
address := link.HomeAddress()
fmt.Printf("%s lives at %s\n", link.Me().Name, address.Formatted)
// Navigate to work address
workAddr := link.WorkAddress()
fmt.Printf("Works at: %s\n", workAddr.Formatted)

Navigate from a user to their single primary group with O(1) performance.

import "github.com/pseudata/pseudata"
users := pseudata.NewUserArray(42)
link := users.LinkAt(1000)
// Navigate to primary group
group := link.PrimaryGroup()
fmt.Printf("%s belongs to %s\n", link.Me().Name, group.Name)

Navigate from a user to all their addresses using language-native iterators.

import "github.com/pseudata/pseudata"
users := pseudata.NewUserArray(42)
link := users.LinkAt(1000)
// Iterate through all addresses
for addr := range link.Addresses() {
fmt.Printf(" - %s\n", addr.Formatted)
}
// Early termination supported
for addr := range link.Addresses() {
if addr.Country == "USA" {
fmt.Println("Found US address:", addr.Formatted)
break
}
}

Navigate backwards from an address to find its owner, or from a group to all its members.

import "github.com/pseudata/pseudata"
addresses := pseudata.NewAddressArray(42)
groups := pseudata.NewGroupArray(42)
// One-to-one reverse: Address → User
addrLink := addresses.LinkAt(5000)
user := addrLink.HomeAddressFor()
fmt.Printf("This address belongs to %s\n", user.Name)
// One-to-many reverse: Group → Users
groupLink := groups.LinkAt(100)
fmt.Printf("Group %s has members:\n", groupLink.Me().Name)
for member := range groupLink.Members() {
fmt.Printf(" - %s\n", member.Name)
}

Navigate hierarchical structures where entities reference themselves, like organizational charts (employee → manager).

Self-referencing relationships use neighborhood teleportation to prevent entities from referencing themselves. The Link class methods handle this automatically—you don’t need to worry about the mechanics.

import "github.com/pseudata/pseudata"
users := pseudata.NewUserArray(42)
link := users.LinkAt(1000)
// Navigate up: Find manager
manager := link.Manager()
fmt.Printf("%s reports to %s\n", link.Me().Name, manager.Name)
// Navigate down: Find direct reports
fmt.Printf("%s manages:\n", link.Me().Name)
for report := range link.Directs() {
fmt.Printf(" - %s\n", report.Name)
}

Behind the scenes, Pseudata treats each 40-bit index as a three-part coordinate:

  • Island (17 bits): High bits used for sharding—keeps related entities on the same shard
  • Neighborhood (20 bits): Middle bits that group related entities together
  • Connector (3 bits): Low bits that define relationship slots (8 possible relationships)

Link class methods like homeAddress() and manager() automatically manipulate these coordinates using the PseudoLink class. For most use cases, you don’t need to work with coordinates directly.

If you need fine-grained control over entity placement, you can use the PseudoLink class directly:

import "github.com/pseudata/pseudata"
users := pseudata.NewUserArray(42)
link := pseudata.NewPseudoLink(17, 20)
// Place Alice in specific coordinates (Island:1, Neighborhood:1000, Connector:0)
aliceIdx := link.Encode(1, 1000, 0)
alice := users.At(aliceIdx)
// Manually navigate to related entity
relatedIdx := link.Resolve(aliceIdx, 2) // Navigate to connector 2