Index / Search

A Component Index enables efficient search of indexed component field values. This enables lookup aka search of entities having components with specific a specific value like in the example below. Any type can be used as indexed component type. E.g. int, long, float, Guid, DateTime, enum, ... . A search / query for a specific value executes in O(1).

Info A component index is the counterpart of database index used to index a column with CREATE INDEX in SQL.

Indexed Components

An IIndexedComponent<> provide the same functionality and behavior as normal components implementing IComponent. For every indexed component type the store creates a an inverted index โ‹… Wikipedia. Adding, removing or updating an indexed component updates the index. These operations are executed in O(1) but significant slower than the non indexed counterparts ~10x. Performance: Indexing 1000 different component values ~60 ฮผs.

The ComponentIndex<,> provide access to indexed components.

struct TileComponent : IIndexedComponent<int> // indexed field type: int
{
    public  int  tileId;
    public  int  GetIndexedValue() => tileId; // indexed field
}

public static void ComponentLookup()
{
    var store   = new EntityStore();
    var index   = store.ComponentIndex<TileComponent,int>();
    store.CreateEntity(new TileComponent{ tileId = 10 });
    store.CreateEntity(new TileComponent{ tileId = 20 });

    // lookup entities where component tileId = 10 in O(1)
    var entities = index[10];   // Count: 1

    // get all unique tileId's in O(1)
    var values = index.Values;  // { 10, 20 }
}

Important When changing the indexed component value entity.AddComponent<>() must be used to enable the store updating the index. Changing the indexed component with ref access don't update the index. E.g. with entity.GetComponent<>() or within a Query() using the ref parameter of a component.

Range query

In case the indexed component type implements IComparable<> like int, string, DateTime, ... range queries can be executed. A range query returns all entities with a component value in the specified range. See example code.

Benchmark - Indexing

The number of components having the same key value should not exceed 100. The reason is that inserting and removing a component to / from the index is executed in O(N). N: number of components having the same key value (duplicates).

Benchmark see Tests Add 1.000.000 indexed int components. Each to an individual entity. Type:

duplicateCount
duration ms
entities

1

119.68

1000000

2

91.73

1000000

4

96.08

1000000

8

97.06

1000000

16

103.75

1000000

32

150.19

1000000

64

98.52

1000000

128

106.64

1000000

256

111.62

1000000

512

123.53

1000000

1024

137.13

1000000

2048

254.83

1000000

4096

234.58

1000000

8192

433.60

1000000

16384

817.92

1000000

32768

1662.16

1000000

Last updated