This vector implementation does is optimized for the case of having only a small number of elements, which are stored directly on the vector object rather than being allocated from the heap. If the capacity exceeds this small number, then a heap allocation is done.
This should improve performance in a couple of cases where vectors typically store 1 element and rarely more than that.
These hashes are used in various places in the Panda codebase (for integrity checks, not for crypto), so using an internal implementation allows retaining this functionality when building Panda without OpenSSL.
Based on the following public domain implementation:
https://github.com/B-Con/crypto-algorithms
OpenALAudioManager::update iterates through all currently playing sounds
via a std::set / phash_set object, _sounds_playing.
If a stream queue corruption was detected during OpenALAudioSound::pull_used_buffers,
the logic added in a895890 would call cleanup() on
the sound if we could not successfully locate the target buffer and log an error.
However, the act of calling OpenALAudioSound::cleanup would lead to calling
stop() (since the sound was actively playing). In OpenALAudioSound::stop(),
we would then proceed to call _manager->stopping_sound which would erase
the current sound from _sounds_playing (while we still held an iterator
to it). Per STL standard and real-world observation, std::set::erase
will invalidate the current iterator held in update (https://en.cppreference.com/w/cpp/container/set/erase).
This leads to a segmentation fault when we attempt the next iteration on the loop.
To resolve this, let's ensure we don't hold onto invalid iterators during the updating of playing sounds.
Fixes#1452