Skip to content

Commit 2df7b07

Browse files
Merge pull request #435 from qubic/develop (Release v1.247.0)
Release v1.247.0
2 parents 4927569 + 185aa85 commit 2df7b07

File tree

11 files changed

+1042
-149
lines changed

11 files changed

+1042
-149
lines changed

doc/contracts.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,23 @@ The callbacks `PRE_RELEASE_SHARES()` and `PRE_ACQUIRE_SHARES()` may also check t
470470

471471
## Other QPI features
472472

473+
### Container types
474+
475+
The following container types are available in the QPI:
476+
477+
- `Array<T, L>`: Array of L elements of type T (L must be 2^N)
478+
- `BitArray<L>`: Array of L bits encoded in array of uint64 (L must be 2^N, overall size is at least 8 bytes)
479+
- `Collection<T, L>`: Collection of priority queues of elements with type T and total element capacity L. Each ID pov (point of view) has an own queue.
480+
- `HashMap<KeyT, ValueT, L>`: Hash map of up to L pairs of key and value (types KeyT and ValueT). Lookup by key, insert, and remove run in approximately constant time if population is less than 80% of L.
481+
- `HashSet`: Hash set of keys of type KeyT and total element capacity L. Lookup by key, insert, and remove run in approximately constant time if population is less than 80% of L.
482+
483+
Please note that removing items from `Collection`, `HashMap`, and `HashSet` does not immediately free the hash map slots used for the removed items.
484+
This may negatively impact the lookup speed, which depends on the maximum population seen since the last cleanup.
485+
If the container isn't emptied by calling the method `reset()` regularly (such as at the end of each epoch), it is recommended to call `cleanup()` or `cleanupIfNeeded()` at the end of the epoch.
486+
Alternatively, if you expect a lot of removes during an epoch, you may call `cleanupIfNeeded()` at the end of a user procedure that removes items.
487+
Cleanup isn't done automatically when removing elements, because, first, it is very expensive compared to the lookup, the add, and remove operations and second, because it invalidates the indices of items, which may be used by the calling function.
488+
489+
473490
### Calling other user functions and procedures
474491

475492
TODO: invoking procedures, calling functions, including those of other contracts

src/contract_core/contract_def.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ constexpr unsigned short TESTEXD_CONTRACT_INDEX = (CONTRACT_INDEX + 1);
239239
// inaccessible for contracts
240240
#include "qpi_collection_impl.h"
241241
#include "qpi_trivial_impl.h"
242+
#include "qpi_hash_map_impl.h"
242243

243244
#include "platform/global_var.h"
244245

src/contract_core/qpi_collection_impl.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,13 +554,23 @@ namespace QPI
554554
}
555555
break;
556556
}
557+
// TODO: reuse slots marked for removal, as in HashSet
557558
povIndex = (povIndex + 1) & (L - 1);
558559
}
559560
}
560561
}
561562
return NULL_INDEX;
562563
}
563564

565+
template <typename T, uint64 L>
566+
void Collection<T, L>::cleanupIfNeeded(uint64 removalThresholdPercent)
567+
{
568+
if (_markRemovalCounter > (removalThresholdPercent * L / 100))
569+
{
570+
cleanup();
571+
}
572+
}
573+
564574
template <typename T, uint64 L>
565575
void Collection<T, L>::cleanup()
566576
{

0 commit comments

Comments
 (0)