-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs(error-utils): add error_utils documentation
- Loading branch information
Showing
3 changed files
with
83 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Hash table | ||
|
||
One of the main problems with how the errors are defined is that their total number | ||
cannot be set from inside the library and dynamic memory allocation should be avoided. | ||
|
||
To solve this problems an **hash table** with **open addressing** is used. | ||
|
||
!!! Info The hash function used by the library is the 32 bit version of the | ||
**MurmurHash3** implementation, for details refer to [MurmurHash](https://en.wikipedia.org/wiki/MurmurHash) | ||
|
||
When a new error is set its hash value is calculated based on the type and its | ||
instance, then the calculated value is used as the index for the hash table. \ | ||
If a collision happens the next index is calculated using **quadratic probing** | ||
as described by this formula: `next_index = (curr_index + (offset * offset)) % buffer_size` | ||
where the `offset` is the number of collisions and the `buffer_size` variable | ||
is the size of the hash table. | ||
|
||
When an error is reset it's not removed completely from the hash table but can | ||
be replaced with another when needed. | ||
|
||
The advantages of the MurmurHash algorithm is that it takes as input a 32 bit | ||
integer **seed** (which is the error type in our case) and a **stream of bytes** | ||
(which is the error instance), and it is suitable for generic hash-based lookup | ||
like in the case of this library. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Heap | ||
|
||
To handle the expiration mechanism of the errors it is needed to get the error | ||
with the **minimum remaining amount of time** before it expire, keeping it possible | ||
to do fast insertion and removal. | ||
|
||
One possible solution would be to sort each error every time it is set or reset | ||
but, in the worst case scenario, it could take a lot of time to do that. | ||
|
||
To solve this problem a separate data structure containing pointer to the errors | ||
is **partially sorted** keeping the minimum element at the first index of the structure; | ||
this structure is a [min heap](https://it.wikipedia.org/wiki/Heap_(struttura_dati)) | ||
with a static array implementation. | ||
|
||
When an error is set a reference to that error is pushed at the end of the heap | ||
and than it is swapped with its parent until it restores the properties of the heap. | ||
|
||
When an error is reset the referenced to that error is swapped with the last element | ||
of the heap and removed, and then the properties of the heap are restored. | ||
|
||
Every time the first element (the minimum) is updated the expire handler is also | ||
updated as well, except for the case in which no errors are running where the | ||
expire handler is stopped. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# Error utils | ||
|
||
The main purpose of this library is to handle **critical errors** that should | ||
expire after a given time from the moment they were set. | ||
|
||
A critical error is defined as an abnormal situation that should be notified to | ||
the system and can be uniquely identified by a **type**, defined by the user, | ||
and an **instance** that should identify the cause of the error. | ||
|
||
The error instance can be a constant string (useful to give meaning to the instance) | ||
or an integer (useful to enumarate and iterate multiple instances). | ||
|
||
There are three main operations that can be done with an error: | ||
1. **Set** | ||
2. **Reset** | ||
3. **Expire** | ||
|
||
If an error is set the current *timestamp* is saved and an expire handler (usually a timer) | ||
is started or updated. | ||
If a running error is reset it cannot expire anymore, in that case the expire handler | ||
is updated or stopped if there are no running errors. | ||
If an error expires the system is notified through a callback, the expired error | ||
is reset and the expire handler is updated or stopped. | ||
|
||
!!! Important The exipre handler has to be defined and handled by the user, | ||
this library only defines a couple of interfaces and does not manage | ||
the handler internally. | ||
|
||
--- | ||
|
||
The internal structure of the error utils library takes advantage of **two data | ||
structures** to achieve fast insertion, deletion and search: | ||
1. [Hash table](data_structures/hash_table.md): to handle error insertion(*set*) | ||
and deletion(*reset*) | ||
2. [Min heap](data_structures/heap.md): to handle the expire mechanism and sort | ||
the errors based on their expiration time |