Martin Prikryl ad3406fad9 OpenSSL 3.3.7 2 дней назад
..
aes ad3406fad9 OpenSSL 3.3.7 2 дней назад
aria 255fc56feb OpenSSL 3.3.6 2 месяцев назад
asn1 ad3406fad9 OpenSSL 3.3.7 2 дней назад
async 255fc56feb OpenSSL 3.3.6 2 месяцев назад
bf ad3406fad9 OpenSSL 3.3.7 2 дней назад
bio ad3406fad9 OpenSSL 3.3.7 2 дней назад
bn ad3406fad9 OpenSSL 3.3.7 2 дней назад
buffer 255fc56feb OpenSSL 3.3.6 2 месяцев назад
camellia 255fc56feb OpenSSL 3.3.6 2 месяцев назад
cast ad3406fad9 OpenSSL 3.3.7 2 дней назад
chacha 255fc56feb OpenSSL 3.3.6 2 месяцев назад
cmac 255fc56feb OpenSSL 3.3.6 2 месяцев назад
cmp 255fc56feb OpenSSL 3.3.6 2 месяцев назад
cms ad3406fad9 OpenSSL 3.3.7 2 дней назад
comp 255fc56feb OpenSSL 3.3.6 2 месяцев назад
conf ad3406fad9 OpenSSL 3.3.7 2 дней назад
crmf 255fc56feb OpenSSL 3.3.6 2 месяцев назад
ct 255fc56feb OpenSSL 3.3.6 2 месяцев назад
des ad3406fad9 OpenSSL 3.3.7 2 дней назад
dh ad3406fad9 OpenSSL 3.3.7 2 дней назад
dsa ad3406fad9 OpenSSL 3.3.7 2 дней назад
dso 255fc56feb OpenSSL 3.3.6 2 месяцев назад
ec ad3406fad9 OpenSSL 3.3.7 2 дней назад
encode_decode 255fc56feb OpenSSL 3.3.6 2 месяцев назад
engine 255fc56feb OpenSSL 3.3.6 2 месяцев назад
err ad3406fad9 OpenSSL 3.3.7 2 дней назад
ess ad3406fad9 OpenSSL 3.3.7 2 дней назад
evp ad3406fad9 OpenSSL 3.3.7 2 дней назад
ffc 255fc56feb OpenSSL 3.3.6 2 месяцев назад
hmac 255fc56feb OpenSSL 3.3.6 2 месяцев назад
hpke 255fc56feb OpenSSL 3.3.6 2 месяцев назад
http ad3406fad9 OpenSSL 3.3.7 2 дней назад
idea ad3406fad9 OpenSSL 3.3.7 2 дней назад
kdf 3c34a35624 OpenSSL 3.1.0 2 лет назад
lhash 255fc56feb OpenSSL 3.3.6 2 месяцев назад
md2 255fc56feb OpenSSL 3.3.6 2 месяцев назад
md4 255fc56feb OpenSSL 3.3.6 2 месяцев назад
md5 255fc56feb OpenSSL 3.3.6 2 месяцев назад
mdc2 255fc56feb OpenSSL 3.3.6 2 месяцев назад
modes ad3406fad9 OpenSSL 3.3.7 2 дней назад
objects 255fc56feb OpenSSL 3.3.6 2 месяцев назад
ocsp 255fc56feb OpenSSL 3.3.6 2 месяцев назад
pem 255fc56feb OpenSSL 3.3.6 2 месяцев назад
perlasm ad3406fad9 OpenSSL 3.3.7 2 дней назад
pkcs12 ad3406fad9 OpenSSL 3.3.7 2 дней назад
pkcs7 ad3406fad9 OpenSSL 3.3.7 2 дней назад
poly1305 255fc56feb OpenSSL 3.3.6 2 месяцев назад
property 255fc56feb OpenSSL 3.3.6 2 месяцев назад
rand ad3406fad9 OpenSSL 3.3.7 2 дней назад
rc2 ad3406fad9 OpenSSL 3.3.7 2 дней назад
rc4 255fc56feb OpenSSL 3.3.6 2 месяцев назад
rc5 ad3406fad9 OpenSSL 3.3.7 2 дней назад
ripemd 255fc56feb OpenSSL 3.3.6 2 месяцев назад
rsa ad3406fad9 OpenSSL 3.3.7 2 дней назад
seed 255fc56feb OpenSSL 3.3.6 2 месяцев назад
sha ad3406fad9 OpenSSL 3.3.7 2 дней назад
siphash 255fc56feb OpenSSL 3.3.6 2 месяцев назад
sm2 255fc56feb OpenSSL 3.3.6 2 месяцев назад
sm3 255fc56feb OpenSSL 3.3.6 2 месяцев назад
sm4 255fc56feb OpenSSL 3.3.6 2 месяцев назад
srp 255fc56feb OpenSSL 3.3.6 2 месяцев назад
stack 255fc56feb OpenSSL 3.3.6 2 месяцев назад
store ad3406fad9 OpenSSL 3.3.7 2 дней назад
thread 255fc56feb OpenSSL 3.3.6 2 месяцев назад
ts ad3406fad9 OpenSSL 3.3.7 2 дней назад
txt_db 255fc56feb OpenSSL 3.3.6 2 месяцев назад
ui 255fc56feb OpenSSL 3.3.6 2 месяцев назад
whrlpool 255fc56feb OpenSSL 3.3.6 2 месяцев назад
x509 ad3406fad9 OpenSSL 3.3.7 2 дней назад
LPdir_nyi.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
LPdir_unix.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
LPdir_vms.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
LPdir_win.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
LPdir_win32.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
LPdir_wince.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
README-sparse_array.md 3c34a35624 OpenSSL 3.1.0 2 лет назад
alphacpuid.pl 3c34a35624 OpenSSL 3.1.0 2 лет назад
arm64cpuid.pl 3c34a35624 OpenSSL 3.1.0 2 лет назад
arm_arch.h 255fc56feb OpenSSL 3.3.6 2 месяцев назад
armcap.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
armv4cpuid.pl a322da3810 OpenSSL 3.3.3 1 год назад
asn1_dsa.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
bsearch.c ad3406fad9 OpenSSL 3.3.7 2 дней назад
build.info 513d92a184 OpenSSL 3.2.0 2 лет назад
c64xpluscpuid.pl 3c34a35624 OpenSSL 3.1.0 2 лет назад
context.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
core_algorithm.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
core_fetch.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
core_namemap.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
cpt_err.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
cpuid.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
cryptlib.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
ctype.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
cversion.c 3c34a35624 OpenSSL 3.1.0 2 лет назад
der_writer.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
deterministic_nonce.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
dllmain.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
ebcdic.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
ex_data.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
getenv.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
ia64cpuid.S 3c34a35624 OpenSSL 3.1.0 2 лет назад
info.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
init.c ad3406fad9 OpenSSL 3.3.7 2 дней назад
initthread.c ad3406fad9 OpenSSL 3.3.7 2 дней назад
loongarch64cpuid.pl 80313efea9 OpenSSL 3.3.4 9 месяцев назад
loongarch_arch.h 255fc56feb OpenSSL 3.3.6 2 месяцев назад
loongarchcap.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
mem.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
mem_clr.c 3c34a35624 OpenSSL 3.1.0 2 лет назад
mem_sec.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
mips_arch.h 255fc56feb OpenSSL 3.3.6 2 месяцев назад
o_dir.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
o_fopen.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
o_init.c 3c34a35624 OpenSSL 3.1.0 2 лет назад
o_str.c ad3406fad9 OpenSSL 3.3.7 2 дней назад
o_time.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
packet.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
param_build.c ad3406fad9 OpenSSL 3.3.7 2 дней назад
param_build_set.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
params.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
params_dup.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
params_from_text.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
params_idx.c.in 255fc56feb OpenSSL 3.3.6 2 месяцев назад
pariscid.pl 3c34a35624 OpenSSL 3.1.0 2 лет назад
passphrase.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
ppccap.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
ppccpuid.pl 3c34a35624 OpenSSL 3.1.0 2 лет назад
provider.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
provider_child.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
provider_conf.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
provider_core.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
provider_local.h 255fc56feb OpenSSL 3.3.6 2 месяцев назад
provider_predefined.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
punycode.c ad3406fad9 OpenSSL 3.3.7 2 дней назад
quic_vlint.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
rcu_internal.h 255fc56feb OpenSSL 3.3.6 2 месяцев назад
riscv32cpuid.pl 6ec29a5a18 OpenSSL 3.3.5 6 месяцев назад
riscv64cpuid.pl 6ec29a5a18 OpenSSL 3.3.5 6 месяцев назад
riscvcap.c ad3406fad9 OpenSSL 3.3.7 2 дней назад
s390x_arch.h 255fc56feb OpenSSL 3.3.6 2 месяцев назад
s390xcap.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
s390xcpuid.pl 255fc56feb OpenSSL 3.3.6 2 месяцев назад
self_test_core.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
sleep.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
sparccpuid.S 3c34a35624 OpenSSL 3.1.0 2 лет назад
sparcv9cap.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
sparse_array.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
threads_lib.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
threads_none.c ad3406fad9 OpenSSL 3.3.7 2 дней назад
threads_pthread.c ad3406fad9 OpenSSL 3.3.7 2 дней назад
threads_win.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
time.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
trace.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
uid.c 255fc56feb OpenSSL 3.3.6 2 месяцев назад
vms_rms.h 255fc56feb OpenSSL 3.3.6 2 месяцев назад
x86_64cpuid.pl 3c34a35624 OpenSSL 3.1.0 2 лет назад
x86cpuid.pl 3c34a35624 OpenSSL 3.1.0 2 лет назад

README-sparse_array.md

Sparse Arrays

The sparse_array.c file contains an implementation of a sparse array that attempts to be both space and time efficient.

The sparse array is represented using a tree structure. Each node in the tree contains a block of pointers to either the user supplied leaf values or to another node.

There are a number of parameters used to define the block size:

OPENSSL_SA_BLOCK_BITS   Specifies the number of bits covered by each block
SA_BLOCK_MAX            Specifies the number of pointers in each block
SA_BLOCK_MASK           Specifies a bit mask to perform modulo block size
SA_BLOCK_MAX_LEVELS     Indicates the maximum possible height of the tree

These constants are inter-related:

SA_BLOCK_MAX        = 2 ^ OPENSSL_SA_BLOCK_BITS
SA_BLOCK_MASK       = SA_BLOCK_MAX - 1
SA_BLOCK_MAX_LEVELS = number of bits in size_t divided by
                      OPENSSL_SA_BLOCK_BITS rounded up to the next multiple
                      of OPENSSL_SA_BLOCK_BITS

OPENSSL_SA_BLOCK_BITS can be defined at compile time and this overrides the built in setting.

As a space and performance optimisation, the height of the tree is usually less than the maximum possible height. Only sufficient height is allocated to accommodate the largest index added to the data structure.

The largest index used to add a value to the array determines the tree height:

    +----------------------+---------------------+
    | Largest Added Index  |   Height of Tree    |
    +----------------------+---------------------+
    | SA_BLOCK_MAX     - 1 |          1          |
    | SA_BLOCK_MAX ^ 2 - 1 |          2          |
    | SA_BLOCK_MAX ^ 3 - 1 |          3          |
    | ...                  |          ...        |
    | size_t max           | SA_BLOCK_MAX_LEVELS |
    +----------------------+---------------------+

The tree height is dynamically increased as needed based on additions.

An empty tree is represented by a NULL root pointer. Inserting a value at index 0 results in the allocation of a top level node full of null pointers except for the single pointer to the user's data (N = SA_BLOCK_MAX for brevity):

    +----+
    |Root|
    |Node|
    +-+--+
      |
      |
      |
      v
    +-+-+---+---+---+---+
    | 0 | 1 | 2 |...|N-1|
    |   |nil|nil|...|nil|
    +-+-+---+---+---+---+
      |
      |
      |
      v
    +-+--+
    |User|
    |Data|
    +----+
Index 0

Inserting at element 2N+1 creates a new root node and pushes down the old root node. It then creates a second second level node to hold the pointer to the user's new data:

    +----+
    |Root|
    |Node|
    +-+--+
      |
      |
      |
      v
    +-+-+---+---+---+---+
    | 0 | 1 | 2 |...|N-1|
    |   |nil|   |...|nil|
    +-+-+---+-+-+---+---+
      |       |
      |       +------------------+
      |                          |
      v                          v
    +-+-+---+---+---+---+      +-+-+---+---+---+---+
    | 0 | 1 | 2 |...|N-1|      | 0 | 1 | 2 |...|N-1|
    |nil|   |nil|...|nil|      |nil|   |nil|...|nil|
    +-+-+---+---+---+---+      +---+-+-+---+---+---+
      |                              |
      |                              |
      |                              |
      v                              v
    +-+--+                         +-+--+
    |User|                         |User|
    |Data|                         |Data|
    +----+                         +----+
Index 0                       Index 2N+1

The nodes themselves are allocated in a sparse manner. Only nodes which exist along a path from the root of the tree to an added leaf will be allocated. The complexity is hidden and nodes are allocated on an as needed basis. Because the data is expected to be sparse this doesn't result in a large waste of space.

Values can be removed from the sparse array by setting their index position to NULL. The data structure does not attempt to reclaim nodes or reduce the height of the tree on removal. For example, now setting index 0 to NULL would result in:

    +----+
    |Root|
    |Node|
    +-+--+
      |
      |
      |
      v
    +-+-+---+---+---+---+
    | 0 | 1 | 2 |...|N-1|
    |   |nil|   |...|nil|
    +-+-+---+-+-+---+---+
      |       |
      |       +------------------+
      |                          |
      v                          v
    +-+-+---+---+---+---+      +-+-+---+---+---+---+
    | 0 | 1 | 2 |...|N-1|      | 0 | 1 | 2 |...|N-1|
    |nil|nil|nil|...|nil|      |nil|   |nil|...|nil|
    +---+---+---+---+---+      +---+-+-+---+---+---+
                                     |
                                     |
                                     |
                                     v
                                   +-+--+
                                   |User|
                                   |Data|
                                   +----+
                              Index 2N+1

Accesses to elements in the sparse array take O(log n) time where n is the largest element. The base of the logarithm is SA_BLOCK_MAX, so for moderately small indices (e.g. NIDs), single level (constant time) access is achievable. Space usage is O(minimum(m, n log(n)) where m is the number of elements in the array.

Note: sparse arrays only include pointers to types. Thus, SPARSE_ARRAY_OF(char) can be used to store a string.