summaryrefslogtreecommitdiff
path: root/src/bucketed-array.hpp
blob: cf34bddc8575525d382f583049290474e1d343c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#ifndef PKE_BUCKETED_ARRAY_HPP
#define PKE_BUCKETED_ARRAY_HPP

#include <cstddef>
#include <cassert>

#include "pk.h"

constexpr pk_handle_bucket_index_T BucketContainerDefaultBucketCount = 16;
constexpr pk_handle_item_index_T BucketContainerDefaultItemCount = 256;

template<typename T, typename CT = struct pk_handle, pk_handle_item_index_T BKT_CNT = BucketContainerDefaultBucketCount>
struct BucketContainer {
	CT limits;
	CT pkeHandle;
	T* buckets[BKT_CNT];
};

template<typename T, typename CT, pk_handle_item_index_T BKT_CNT>
void Buckets_Init(BucketContainer<T, CT, BKT_CNT> &bktContainer, size_t maxItemCount = BucketContainerDefaultItemCount) {
	bktContainer.limits.bucketIndex = BKT_CNT;
	bktContainer.limits.itemIndex = maxItemCount;
	bktContainer.pkeHandle.bucketIndex = 0;
	bktContainer.pkeHandle.itemIndex = 0;
	for (pk_handle_item_index_T i = 0; i < BKT_CNT; ++i) {
		bktContainer.buckets[i] = nullptr;
	}
	bktContainer.buckets[0] = pk_new<T>(maxItemCount);
}

template<typename T, typename CT, pk_handle_item_index_T BKT_CNT>
inline CT Buckets_NewHandle(BucketContainer<T, CT, BKT_CNT> &bktContainer) {
	CT returnValue = bktContainer.pkeHandle;
	bktContainer.pkeHandle.itemIndex += 1;
	if (bktContainer.pkeHandle.itemIndex >= bktContainer.limits.itemIndex) {
		bktContainer.pkeHandle.itemIndex = 0;
		bktContainer.pkeHandle.bucketIndex += 1;
		assert(bktContainer.pkeHandle.bucketIndex < bktContainer.limits.bucketIndex);
	}
	if (bktContainer.pkeHandle.itemIndex == 0) {
		bktContainer.buckets[bktContainer.pkeHandle.bucketIndex] = pk_new<T>(bktContainer.limits.itemIndex);
	}
	return returnValue;
}

template<typename T, typename CT, pk_handle_item_index_T BKT_CNT>
static inline constexpr void Buckets_Destroy(BucketContainer<T, CT, BKT_CNT> &bktContainer) {
	for (pk_handle_item_index_T i = 0; i <= bktContainer.pkeHandle.bucketIndex; ++i) {
		pk_delete<T>(bktContainer.buckets[i], bktContainer.limits.itemIndex);
		bktContainer.buckets[i] = CAFE_BABE(T);
	}
}

#endif /* PKE_BUCKETED_ARRAY_HPP */