flat_index is an artificial autoincrement to make a demo, it does not needed, it just a flat array index for a translation table.

```sql
drop dictionary if exists dict_complex_hashed;
drop dictionary if exists dict_translation;
drop dictionary if exists dict_flat;
drop table if exists dict_source;

create table dict_source(key String, flat_index UInt64, s1 String, s2 String, s3 String, 
s4 String, s5 String, s6 String, s7 String, s8 String, s9 String, s10 String) Engine=Log;  

insert into dict_source select 'some key String :'||toString(cityHash64(number)), number,
    (arrayMap(i->'some atribute string'||toString(number*i), range(10)) as x)[1],
    x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10] from numbers(1000000);

create dictionary dict_complex_hashed (key String, s1 String, s2 String, s3 String, 
s4 String, s5 String, s6 String, s7 String, s8 String, s9 String, s10 String)
PRIMARY KEY key SOURCE(CLICKHOUSE(DATABASE 'default' TABLE 'dict_source')) lifetime(0)  
LAYOUT(complex_key_hashed);



create dictionary dict_translation(key String, flat_index UInt64)
PRIMARY KEY key SOURCE(CLICKHOUSE(DATABASE 'default' TABLE 'dict_source')) lifetime(0)  
LAYOUT(complex_key_hashed);

create dictionary dict_flat (flat_index UInt64, s1 String, s2 String, s3 String, 
s4 String, s5 String, s6 String, s7 String, s8 String, s9 String, s10 String)
PRIMARY KEY flat_index SOURCE(CLICKHOUSE(DATABASE 'default' TABLE 'dict_source')) lifetime(0)  
LAYOUT(flat(INITIAL_ARRAY_SIZE 50000 MAX_ARRAY_SIZE 5000000));


select database, name, status, element_count, formatReadableSize(bytes_allocated) mem, loading_duration, type from system.dictionaries where name like 'dict_%';
┌─database─┬─name────────────────┬─status─┬─element_count─┬─mem────────┬─loading_duration─┬─type─────────────┐
│ default  │ dict_flat           │ LOADED │      10000000 │ 479.96 MiB │            1.052 │ Flat             │
│ default  │ dict_translation    │ LOADED │       1000000 │ 128.00 MiB │            0.224 │ ComplexKeyHashed │
│ default  │ dict_complex_hashed │ LOADED │      10000000 │ 1.59 GiB   │            2.931 │ ComplexKeyHashed │
└──────────┴─────────────────────┴────────┴───────────────┴────────────┴──────────────────┴──────────────────┘

479.96 MiB + 128.00 MiB < 1.59 GiB
1.052 + 0.224 < 2.931

select dictGet('dict_complex_hashed', 's8', tuple('some key String :17349973131760655344')) x ;
┌─x───────────────────────────┐
│ some atribute string4406801 │
└─────────────────────────────┘

select dictGet('dict_flat', 's8', dictGet('dict_translation', 'flat_index', tuple('some key String :17349973131760655344'))) x;
┌─x───────────────────────────┐
│ some atribute string4406801 │
└─────────────────────────────┘

select dictGet('dict_complex_hashed', 's5',  tuple('some key String :'||toString(cityHash64(number))) ) 
from numbers(1000000) format Null;
Elapsed: 0.166 sec. Processed 1.05 million rows

select dictGet('dict_flat', 's5', toUInt64(dictGet('dict_translation', 'flat_index', tuple('some key String :'||toString(cityHash64(number)))))) 
from numbers(1000000) format Null;
Elapsed: 0.180 sec. Processed 1.05 million rows
```
#include "DictionaryFactory.h"
#include "DictionarySourceFactory.h"
namespace DB
{
class DictionarySourceFactory;