SOMA(Scheme-Oriented Memory Architecture)
Schema-Defined, High-Performance Runtime-State Computing for Java.
SOMA 是面向 Java 8 的进程内编译式 Table 引擎。它把稳定的运行时状态 Scheme 编译为类型安全的 generated API、紧凑的列式存储布局和专用执行计划,让 application 使用自然 Java object 管理 大规模、频繁变化的计算状态。
SOMA 适用于 schema-defined、状态变化频繁、需要高性能计算,并且对延迟和内存敏感的运行时计算场景, 例如调度与组合优化、仿真和实时派工。
Schema declaration
-> generated Soma / Group / Table / Field / Index API
-> Canonical Logical IR and optimizer
-> specialized execution
-> chunked columnar runtime state
在 SOMA 中,Scheme 是 application 运行时状态的稳定组织方式:
Runtime-state Scheme
= Table structure
+ Field and Value shape
+ Key and Index access paths
+ legal computation relationships
Application 声明 Scheme,annotation processor 在编译期获得完整结构信息,并生成与之对应的 Java
类型和能力。Runtime 因而不需要把所有操作退化成反射、通用 Object 容器或统一 boxed executor;
它可以在保持 Java API 类型安全的同时,使用面向数据的存储和专用执行路径。
SOMA 不试图替代 Java Stream、数据库或 ECS。它专注的是同一 JVM 中、schema 已知且频繁变化的 authoritative runtime state。
| 体系 | 主要职责 | 执行与状态边界 | 类型与结构 | 典型计算方式 |
|---|---|---|---|---|
| Java Collection / Stream | 对 application collection 进行通用计算 | 同进程;状态由 application object/collection 拥有 | generic type;不规定物理布局 | iterator、pipeline、collector |
| In-memory Database | 内存中的查询、事务或 Key/Value 服务 | embedded 或独立服务;数据库拥有数据 | runtime schema、SQL 或 Key/Value model | query engine、transaction、network/client API |
| ECS | 组织 Entity 与 Component,并驱动 System | 通常同进程;application/game runtime 拥有生命周期 | component-oriented layout | component scan 与 system update |
| ClickHouse 等列式分析数据库 | 大规模持久化分析与聚合 | 通常独立数据库进程;数据库拥有持久化数据 | database schema 与 SQL | 批量写入、列式 scan、distributed analytics |
| SOMA | 管理算法运行时的可变 Table 状态并执行关系计算 | 同 JVM、无 IPC;SomaGroup 拥有状态 |
compiler-known Scheme 与 generated exact API | Key/Index、typed pipeline、GroupBy、Join、controlled mutation |
SOMA 借鉴 Java Stream 的 source/intermediate/terminal、lazy pipeline、familiar naming 和显式并行, 但它的 source 是 SOMA 管理的 Table、Field、IndexSelection 和 Relation。Table 还拥有 Key、Index、 point mutation、Selection mutation、GroupBy、Join、资源准入和 structured failure。
普通 application 只需要理解以下层级:
Soma
-> SomaGroup
-> Table
-> Field
-> nested Field
Soma:一个 compiled composition 的配置和默认入口;SomaGroup:一组相互隔离、可以参与关系计算的 Table 状态;Table:authoritative mutable state,以及 Key、Index 和 Table-local mutation 的 Owner;Field:类型安全的 logical value source,不向用户暴露 physical Column;- generated pipeline:从 reusable source 形成的 lazy、finite、one-shot computation;
- terminal:返回 detached result,或者原子发布一次 Table-local state change。
Table、Field 和 IndexSelection 本身就是 source,不需要先调用 stream()。Sequential 是默认模式;
只有显式调用 parallel() 才进入 SOMA 的受控并行路径。
当前要求 Java 8 JDK 和 Maven 3.9.x。仓库尚未发布到 Maven Central,因此先从源码安装两项 production artifact:
git clone https://github.com/somaruntime/soma-java.git
cd soma-java
mvn clean install -Dmaven.install.skip=false -DskipTests在 consumer pom.xml 中加入 runtime 和 annotation processor:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<soma.version>1.0.0-SNAPSHOT</soma.version>
</properties>
<dependencies>
<dependency>
<groupId>io.github.somaruntime.soma</groupId>
<artifactId>soma-runtime</artifactId>
<version>${soma.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<release>8</release>
<source>8</source>
<target>8</target>
<encoding>${project.build.sourceEncoding}</encoding>
<compilerArgs>
<arg>-Asoma.fullSourceSet=true</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
<groupId>io.github.somaruntime.soma</groupId>
<artifactId>soma-processor</artifactId>
<version>${soma.version}</version>
</path>
<path>
<groupId>io.github.somaruntime.soma</groupId>
<artifactId>soma-runtime</artifactId>
<version>${soma.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>一个 package-level @SomaSchema 定义一个 composition。创建
src/main/java/example/jobs/schema/package-info.java:
@io.github.somaruntime.soma.SomaSchema
package example.jobs.schema;在同一个 package 中创建两张 Table。Job.java:
package example.jobs.schema;
import io.github.somaruntime.soma.SomaField;
import io.github.somaruntime.soma.SomaIndex;
import io.github.somaruntime.soma.SomaKey;
import io.github.somaruntime.soma.SomaTable;
@SomaTable(defaultCapacity = 4096)
final class Job {
@SomaKey long jobId;
@SomaIndex long machineId;
@SomaField int status;
@SomaField long durationMinutes;
}Machine.java:
package example.jobs.schema;
import io.github.somaruntime.soma.SomaField;
import io.github.somaruntime.soma.SomaIndex;
import io.github.somaruntime.soma.SomaKey;
import io.github.somaruntime.soma.SomaTable;
@SomaTable(defaultCapacity = 256)
final class Machine {
@SomaKey long machineId;
@SomaIndex String zone;
@SomaField long availableMinute;
@SomaField long workloadMinutes;
@SomaField boolean enabled;
}Processor 只收集该 schema package 直接包含的 Table,并在父 package example.jobs 中生成:
Soma / SomaGroup
Job / JobTable
Machine / MachineTable
JobTable.View / JobTable.Editor
MachineTable.View / MachineTable.Editor
typed Field, Index, GroupBy and Join endpoints
Schema declaration type 不进入 application API。
创建 src/main/java/example/jobs/JobsMain.java:
package example.jobs;
import io.github.somaruntime.soma.LongGroupedLongResult;
import io.github.somaruntime.soma.RemoveResult;
import io.github.somaruntime.soma.UpdateResult;
import java.util.List;
public final class JobsMain {
private static final int PENDING = 0;
private static final int SCHEDULED = 1;
private JobsMain() {}
public static void main(String[] args) {
SomaGroup group = Soma.createGroup();
JobTable jobs = group.jobTable();
MachineTable machines = group.machineTable();
jobs.add(new Job(101L, 7L, PENDING, 30L));
jobs.add(new Job(102L, 7L, PENDING, 20L));
jobs.add(new Job(103L, 9L, SCHEDULED, 45L));
jobs.add(new Job(104L, 11L, PENDING, 15L));
machines.add(new Machine(7L, "NORTH", 10L, 0L, true));
machines.add(new Machine(9L, "NORTH", 5L, 45L, true));
machines.add(new Machine(11L, "SOUTH", 0L, 0L, false));
// Key、missing 与 secondary Index
Job first = jobs.get(101L);
boolean missing = !jobs.find(999L).isPresent();
List<Job> machine7Jobs = jobs.byMachineId(7L).toList();
long northMachines = machines.byZone("NORTH").count();
// Field source、typed filter、projection 与 aggregate
long allMinutes = jobs.durationMinutes.sum();
long pendingMinutes = jobs
.filter(jobs.status.eq(PENDING))
.mapToLong(jobs.durationMinutes)
.sum();
// typed GroupBy
LongGroupedLongResult jobsPerMachine = jobs
.groupBy(jobs.machineId)
.count();
// 两张 Table 的 Equality Join;typed predicate 可以下推到左右输入
long runnableJobs = jobs.join(machines)
.on(jobs.machineId, machines.machineId)
.inner()
.filter(jobs.status.eq(PENDING))
.filter(machines.enabled.eq(true))
.count();
// Join Pair projection:同时读取左右两侧 generated View
long projectedCompletion = jobs.join(machines)
.on(jobs.machineId, machines.machineId)
.inner()
.filter(jobs.status.eq(PENDING))
.filter(machines.enabled.eq(true))
.mapToLong(pair -> pair.right().availableMinute()
+ pair.left().durationMinutes())
.sum();
// sequential 是默认模式;parallel 必须显式请求
long parallelPending = jobs.parallel()
.filter(jobs.status.eq(PENDING))
.count();
// Advanced diagnostic,不作为业务逻辑输入
String plan = jobs.join(machines)
.on(jobs.machineId, machines.machineId)
.inner()
.filter(machines.enabled.eq(true))
._explain();
// point update、Selection update 与 point remove
UpdateResult machineUpdated = machines.update(7L, editor -> {
editor.availableMinute(40L);
editor.workloadMinutes(editor.workloadMinutes() + 30L);
});
UpdateResult jobsUpdated = jobs
.filter(jobs.status.eq(PENDING))
.update(editor -> editor.status(SCHEDULED));
RemoveResult removed = jobs.remove(102L);
if (first.durationMinutes() != 30L
|| !missing
|| machine7Jobs.size() != 2
|| northMachines != 2L
|| allMinutes != 110L
|| pendingMinutes != 65L
|| jobsPerMachine.size() != 3L
|| runnableJobs != 2L
|| projectedCompletion != 70L
|| parallelPending != 3L
|| plan.length() == 0
|| machineUpdated.changed() != 1
|| jobsUpdated.changed() != 3
|| removed.removed() != 1) {
throw new AssertionError("unexpected SOMA result");
}
System.out.println("SOMA two-table quick start: PASS");
}
}这个程序在一条连续路径中使用了 SOMA 的主要 generated API:
| API family | 示例中的作用 |
|---|---|
add/get/find |
写入 detached object,并通过 Key 访问 0..1 条记录 |
byMachineId/byZone |
使用 generated secondary Index selection |
| Field source与typed filter | 直接聚合 Field,并形成 optimizer-visible predicate |
groupBy |
按 typed Field 生成结构化分组结果 |
join(...).on(...) |
在同一 Group 的两张 Table 之间执行 Equality Join |
| Join Pair mapper | 同时读取 pair.left() 和 pair.right() |
parallel() |
显式进入受控并行;默认仍为 sequential |
| point/Selection mutation | 更新一条 Key record,或原子更新一次 Table-local selection |
_explain() |
观察 logical/physical decision,不参与业务判断 |
上例使用显式 Group,使 JobTable 与 MachineTable 可以进行关系计算。普通单状态场景也可以使用
JVM-global default Group:
JobTable defaultJobs = Soma.jobTable();
SomaGroup active = Soma.createGroup();
SomaGroup backup = Soma.createGroup();
JobTable activeJobs = active.jobTable();
JobTable backupJobs = backup.jobTable();同一 Group 的同一种 generated Table 只有一个 instance;不同 Group 的状态相互隔离。
mvn clean compile
java -cp "target/classes:$HOME/.m2/repository/io/github/somaruntime/soma/\
soma-runtime/1.0.0-SNAPSHOT/soma-runtime-1.0.0-SNAPSHOT.jar" \
example.jobs.JobsMain预期输出:
SOMA two-table quick start: PASS
上面的完整程序已经使用了这些能力。下面保留几个可以直接迁移到实际项目的组合写法:
Job exact = jobs.get(101L);
Optional<Job> optional = jobs.find(101L);
List<Job> machineJobs = jobs.byMachineId(7L)
.filter(jobs.status.eq(0))
.toList();
long totalMinutes = jobs.durationMinutes.sum();
long[] pendingDurations = jobs
.filter(jobs.status.eq(0))
.mapToLong(jobs.durationMinutes)
.toArray();只有保留单 Table row lineage 的 Selection 才生成 mutation terminal:
UpdateResult updated = jobs
.byMachineId(7L)
.filter(jobs.status.eq(PENDING))
.update(editor -> editor.status(SCHEDULED));
RemoveResult removed = jobs
.byMachineId(7L)
.remove();Field、mapped result、Group 和 Join 不负责删除 Record;Record membership 始终由 Table 管理。
Join 可以继续执行 projection、aggregate 和 relation filter,而不是只能返回匹配数量:
LongGroupedLongResult minutesPerMachine = jobs
.groupBy(jobs.machineId)
.sum(jobs.durationMinutes);
long enabledMinutes = jobs
.join(machines)
.on(jobs.machineId, machines.machineId)
.inner()
.filter(machines.enabled.eq(true))
.mapToLong(pair -> pair.left().durationMinutes())
.sum();
long parallelPending = jobs
.parallel()
.filter(jobs.status.eq(0))
.count();GroupBy 和 Join 的完整可运行代码见
real-time-dispatch 与
group-relation consumer。
String plan = jobs
.filter(jobs.machineId.eq(7L))
._explain();
TableMetadata metadata = jobs._metadata();_metadata() 和 _explain() 面向高级用户、诊断与 profile,不应成为 application 业务逻辑的
输入合同。
- package-level
@SomaSchema与 aggregating Java 8 annotation processor; - generated
Soma、SomaGroup、Table、Field、Index、View 和 Editor API; - compile-time type、capability、owner、name collision 和完整 source-set validation;
- deterministic full regeneration,不依赖 reflection 或 application-written planner SPI。
- primitive/reference chunked column storage 与 logical Value flattening;
- checked 32-bit Table-local structural domain、checked 64-bit cumulative domain 和 schema-defined application numeric types;
- Key、secondary Index、point mutation 与 Selection atomic mutation;
- AUTO/OFF compression、retained/temporary managed-memory accounting。
- Table、Field、IndexSelection 与 Relation direct source;
- typed filter、map、aggregate、sort、top、slice 与 materialization;
- typed GroupBy、binary Equality Join 和 bounded Cross Join;
- Canonical Logical IR、semantics-preserving optimizer、specialized sequential execution;
- application-owned/common
ForkJoinPool和显式parallel()。
- operation lifecycle、resource preflight、callback scope 和 deterministic order;
- stable structured failure 与 failed mutation zero publication;
- typed
_metadata()与 safe_explain()。
SOMA 是同 JVM、单进程、同步的 runtime-state computation library,不是 persistence database、ORM 或分布式计算服务。Application 继续拥有跨 Table 编排、external I/O、side effect、业务补偿、普通 Java object 的线程安全,以及跨系统 transaction。SOMA V1 不提供 cross-Table transaction、动态 runtime schema、ChildTable、任意多路/non-equality Join 或 public physical Column API。
这里的 example 不是片段式 demo,而是三个只使用 SOMA public/generated API、按真实 application 责任组织的 reference project:
| Project | 展示内容 |
|---|---|
scheduling |
标准 100K-operation FJSP、四张 runtime Table、FCFS + SPT 与自然 waiting add/remove |
simulation |
Grassing空间个体仿真、两张runtime Table、五阶段tick、UI/headless与确定性验证 |
real-time-dispatch |
Index 缩窄、typed Join、显式并行与 external dispatch boundary |
从仓库根目录构建并运行全部 reference application:
mvn clean install -Dmaven.install.skip=false -DskipTests
mvn -f soma-examples/pom.xml clean package更多说明见 SOMA reference applications。
./scripts/check.sh # 日常完整正确性与本地交付检查
./scripts/qualify.sh # 完整 non-publishing qualification
./scripts/benchmark.sh # 独立性能与场景证据
./scripts/package-local.sh # 本地 artifact、SBOM、checksum 与 source bundle当前 V1 implementation、Canonical IR/Execution replacement 与 G1–G10 local/non-publishing qualification 已完成。仓库尚未发布 GitHub Release、GitHub Package 或 Maven Central artifact, 因此当前外部使用方式仍是 source build。该状态不构成正式 release、跨硬件性能 SLA 或一亿行性能承诺。
| Path | 主要读者 | 内容 |
|---|---|---|
soma-runtime/ |
Library user | annotations、shared/generated API linkage 与 runtime |
soma-processor/ |
Library user | schema compiler 与 generated source processor |
soma-examples/ |
Library user | 三个完整 reference application |
docs/ |
Library user | 用户文档入口;当前仅占位,等待独立专题 |
benchmarks/ |
Maintainer | 长期 non-production performance/correctness evidence |
scripts/ |
Maintainer / CI | 四个稳定检查、资格、benchmark 与本地打包入口 |
项目蓝图、正式 Design、Engineering 与 Conformance 集中在 project/,服务
Product Owner、maintainer 和 Codex/Agent。Codex/Agent 应从 AGENTS.md 开始导航;
普通 Library user 不需要阅读完整内部治理过程。
- 使用问题与支持边界:SUPPORT.md
- 安全问题:SECURITY.md
- 行为准则:CODE_OF_CONDUCT.md
- 许可证:Apache License 2.0
- 品牌与第三方声明:NOTICE、assets/README.md
