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.
Quick Start with Link Classes
Section titled “Quick Start with Link Classes”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().
Creating Links
Section titled “Creating Links”Create a link from an array at a specific index:
import "github.com/pseudata/pseudata"
users := pseudata.NewUserArray(42)
// Create link from indexlink := users.LinkAt(1000)
// Or from an objectuser := users.At(1000)link = users.LinkFor(&user)
// Access the source objectfmt.Println(link.Me().Name)import dev.pseudata.UserArray;
UserArray users = new UserArray(42L);
// Create link from indexUserLink link = users.linkAt(1000);
// Or from an objectUser user = users.at(1000);link = users.linkFor(user);
// Access the source objectSystem.out.println(link.me().getName());from pseudata import UserArray
users = UserArray(42)
# Create link from indexlink = users.link_at(1000)
# Or from an objectuser = users.at(1000)link = users.link_for(user)
# Access the source objectprint(link.me().name)import { UserArray } from '@pseudata/core';
const users = new UserArray(42n);
// Create link from indexconst link = users.linkAt(1000);
// Or from an objectconst user = users.at(1000);const link2 = users.linkFor(user);
// Access the source objectconsole.log(link.me().name);One-to-One Relationships
Section titled “One-to-One Relationships”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 addressaddress := link.HomeAddress()fmt.Printf("%s lives at %s\n", link.Me().Name, address.Formatted)
// Navigate to work addressworkAddr := link.WorkAddress()fmt.Printf("Works at: %s\n", workAddr.Formatted)import dev.pseudata.UserArray;
UserArray users = new UserArray(42L);UserLink link = users.linkAt(1000);
// Navigate to home addressAddress address = link.homeAddress();System.out.printf("%s lives at %s%n", link.me().getName(), address.getFormatted());
// Navigate to work addressAddress workAddr = link.workAddress();System.out.printf("Works at: %s%n", workAddr.getFormatted());from pseudata import UserArray
users = UserArray(42)link = users.link_at(1000)
# Navigate to home addressaddress = link.home_address()print(f"{link.me().name} lives at {address.formatted}")
# Navigate to work addresswork_addr = link.work_address()print(f"Works at: {work_addr.formatted}")import { UserArray } from '@pseudata/core';
const users = new UserArray(42n);const link = users.linkAt(1000);
// Navigate to home addressconst address = link.homeAddress();console.log(`${link.me().name} lives at ${address.formatted}`);
// Navigate to work addressconst workAddr = link.workAddress();console.log(`Works at: ${workAddr.formatted}`);Many-to-One Relationships
Section titled “Many-to-One Relationships”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 groupgroup := link.PrimaryGroup()fmt.Printf("%s belongs to %s\n", link.Me().Name, group.Name)import dev.pseudata.UserArray;
UserArray users = new UserArray(42L);UserLink link = users.linkAt(1000);
// Navigate to primary groupGroup group = link.primaryGroup();System.out.printf("%s belongs to %s%n", link.me().getName(), group.getName());from pseudata import UserArray
users = UserArray(42)link = users.link_at(1000)
# Navigate to primary groupgroup = link.primary_group()print(f"{link.me().name} belongs to {group.name}")import { UserArray } from '@pseudata/core';
const users = new UserArray(42n);const link = users.linkAt(1000);
// Navigate to primary groupconst group = link.primaryGroup();console.log(`${link.me().name} belongs to ${group.name}`);One-to-Many Relationships
Section titled “One-to-Many Relationships”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 addressesfor addr := range link.Addresses() { fmt.Printf(" - %s\n", addr.Formatted)}
// Early termination supportedfor addr := range link.Addresses() { if addr.Country == "USA" { fmt.Println("Found US address:", addr.Formatted) break }}import dev.pseudata.UserArray;
UserArray users = new UserArray(42L);UserLink link = users.linkAt(1000);
// Iterate through all addressesfor (Address addr : link.addresses()) { System.out.printf(" - %s%n", addr.getFormatted());}
// Stream API supportlink.addresses().stream() .filter(addr -> addr.getCountry().equals("USA")) .findFirst() .ifPresent(addr -> System.out.println("Found US address: " + addr.getFormatted()) );from pseudata import UserArray
users = UserArray(42)link = users.link_at(1000)
# Iterate through all addressesfor addr in link.addresses(): print(f" - {addr.formatted}")
# List comprehension supportus_addresses = [ addr for addr in link.addresses() if addr.country == "USA"]
# Early terminationfor addr in link.addresses(): if addr.country == "USA": print(f"Found US address: {addr.formatted}") breakimport { UserArray } from '@pseudata/core';
const users = new UserArray(42n);const link = users.linkAt(1000);
// Iterate through all addressesfor (const addr of link.addresses()) { console.log(` - ${addr.formatted}`);}
// Convert to array for filteringconst usAddresses = Array.from(link.addresses()) .filter(addr => addr.country === 'USA');
// Early terminationfor (const addr of link.addresses()) { if (addr.country === 'USA') { console.log(`Found US address: ${addr.formatted}`); break; }}Reverse Navigation
Section titled “Reverse Navigation”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 → UseraddrLink := addresses.LinkAt(5000)user := addrLink.HomeAddressFor()fmt.Printf("This address belongs to %s\n", user.Name)
// One-to-many reverse: Group → UsersgroupLink := groups.LinkAt(100)fmt.Printf("Group %s has members:\n", groupLink.Me().Name)for member := range groupLink.Members() { fmt.Printf(" - %s\n", member.Name)}import dev.pseudata.AddressArray;import dev.pseudata.GroupArray;
AddressArray addresses = new AddressArray(42L);GroupArray groups = new GroupArray(42L);
// One-to-one reverse: Address → UserAddressLink addrLink = addresses.linkAt(5000);User user = addrLink.homeAddressFor();System.out.printf("This address belongs to %s%n", user.getName());
// One-to-many reverse: Group → UsersGroupLink groupLink = groups.linkAt(100);System.out.printf("Group %s has members:%n", groupLink.me().getName());for (User member : groupLink.members()) { System.out.printf(" - %s%n", member.getName());}from pseudata import AddressArray, GroupArray
addresses = AddressArray(42)groups = GroupArray(42)
# One-to-one reverse: Address → Useraddr_link = addresses.link_at(5000)user = addr_link.home_address_for()print(f"This address belongs to {user.name}")
# One-to-many reverse: Group → Usersgroup_link = groups.link_at(100)print(f"Group {group_link.me().name} has members:")for member in group_link.members(): print(f" - {member.name}")import { AddressArray, GroupArray } from '@pseudata/core';
const addresses = new AddressArray(42n);const groups = new GroupArray(42n);
// One-to-one reverse: Address → Userconst addrLink = addresses.linkAt(5000);const user = addrLink.homeAddressFor();console.log(`This address belongs to ${user.name}`);
// One-to-many reverse: Group → Usersconst groupLink = groups.linkAt(100);console.log(`Group ${groupLink.me().name} has members:`);for (const member of groupLink.members()) { console.log(` - ${member.name}`);}Self-Referencing Relationships
Section titled “Self-Referencing Relationships”Navigate hierarchical structures where entities reference themselves, like organizational charts (employee → manager).
How It Works
Section titled “How It Works”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 managermanager := link.Manager()fmt.Printf("%s reports to %s\n", link.Me().Name, manager.Name)
// Navigate down: Find direct reportsfmt.Printf("%s manages:\n", link.Me().Name)for report := range link.Directs() { fmt.Printf(" - %s\n", report.Name)}import dev.pseudata.UserArray;
UserArray users = new UserArray(42L);UserLink link = users.linkAt(1000);
// Navigate up: Find managerUser manager = link.manager();System.out.printf("%s reports to %s%n", link.me().getName(), manager.getName());
// Navigate down: Find direct reportsSystem.out.printf("%s manages:%n", link.me().getName());for (User report : link.directs()) { System.out.printf(" - %s%n", report.getName());}from pseudata import UserArray
users = UserArray(42)link = users.link_at(1000)
# Navigate up: Find managermanager = link.manager()print(f"{link.me().name} reports to {manager.name}")
# Navigate down: Find direct reportsprint(f"{link.me().name} manages:")for report in link.directs(): print(f" - {report.name}")import { UserArray } from '@pseudata/core';
const users = new UserArray(42n);const link = users.linkAt(1000);
// Navigate up: Find managerconst manager = link.manager();console.log(`${link.me().name} reports to ${manager.name}`);
// Navigate down: Find direct reportsconsole.log(`${link.me().name} manages:`);for (const report of link.directs()) { console.log(` - ${report.name}`);}Understanding the Coordinate System
Section titled “Understanding the Coordinate System”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.
Manual Coordinate Control
Section titled “Manual Coordinate Control”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 entityrelatedIdx := link.Resolve(aliceIdx, 2) // Navigate to connector 2import dev.pseudata.UserArray;import dev.pseudata.PseudoLink;
UserArray users = new UserArray(42L);PseudoLink link = new PseudoLink(17, 20);
// Place Alice in specific coordinateslong aliceIdx = link.encode(1, 1000, 0);User alice = users.at(aliceIdx);
// Manually navigate to related entitylong relatedIdx = link.resolve(aliceIdx, 2);from pseudata import UserArray, PseudoLink
users = UserArray(42)link = PseudoLink(17, 20)
# Place Alice in specific coordinatesalice_idx = link.encode(1, 1000, 0)alice = users.at(alice_idx)
# Manually navigate to related entityrelated_idx = link.resolve(alice_idx, 2)import { UserArray, PseudoLink } from '@pseudata/core';
const users = new UserArray(42n);const link = new PseudoLink(17, 20);
// Place Alice in specific coordinatesconst aliceIdx = link.encode(1, 1000, 0);const alice = users.at(aliceIdx);
// Manually navigate to related entityconst relatedIdx = link.resolve(aliceIdx, 2);Next Steps
Section titled “Next Steps”- Add Relations to Models – Learn how to define relationships in TypeSpec
- PseudoLink Reference – Deep dive into bit-math, teleportation, and coordinate systems
- PseudoID Reference – Learn how indices are encoded into standard UUIDs
© 2025 Pseudata Project. Open Source under Apache License 2.0. · RSS Feed