mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
Update chunkedvector.c
This commit is contained in:
parent
1194497b5c
commit
2f296994ae
@ -1,12 +1,12 @@
|
|||||||
#include "pocketpy/common/chunkedvector.h"
|
#include "pocketpy/common/chunkedvector.h"
|
||||||
#include "pocketpy/config.h"
|
#include "pocketpy/pocketpy.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline static int c11_bit_length(unsigned long x) {
|
PK_INLINE static int c11__bit_length(unsigned long x) {
|
||||||
#if(defined(__clang__) || defined(__GNUC__))
|
#if(defined(__clang__) || defined(__GNUC__))
|
||||||
return x == 0 ? 0 : (int)sizeof(unsigned long) * 8 - __builtin_clzl(x);
|
return x == 0 ? 0 : (int)sizeof(unsigned long) * 8 - __builtin_clzl(x);
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
@ -36,7 +36,6 @@ void c11_chunkedvector__ctor(c11_chunkedvector* self, int elem_size, int initial
|
|||||||
self->initial_chunks = initial_chunks;
|
self->initial_chunks = initial_chunks;
|
||||||
void* chunks_data = PK_MALLOC(elem_size * ((1U << (unsigned int)initial_chunks) - 1));
|
void* chunks_data = PK_MALLOC(elem_size * ((1U << (unsigned int)initial_chunks) - 1));
|
||||||
for(int i = 0; i < initial_chunks; i++) {
|
for(int i = 0; i < initial_chunks; i++) {
|
||||||
// TODO: optimize?
|
|
||||||
c11_chunkedvector_chunk chunk = {.length = 0,
|
c11_chunkedvector_chunk chunk = {.length = 0,
|
||||||
.capacity = 1U << i,
|
.capacity = 1U << i,
|
||||||
.data = (char*)chunks_data + elem_size * ((1U << i) - 1U)};
|
.data = (char*)chunks_data + elem_size * ((1U << i) - 1U)};
|
||||||
@ -56,10 +55,11 @@ void c11_chunkedvector__dtor(c11_chunkedvector* self) {
|
|||||||
|
|
||||||
void* c11_chunkedvector__emplace(c11_chunkedvector* self) {
|
void* c11_chunkedvector__emplace(c11_chunkedvector* self) {
|
||||||
if(self->length == self->capacity) {
|
if(self->length == self->capacity) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
c11_chunkedvector_chunk last_chunk = c11_vector__back(c11_chunkedvector_chunk, &self->chunks);
|
c11_chunkedvector_chunk last_chunk =
|
||||||
assert(last_chunk.capacity == last_chunk.length);
|
c11_vector__back(c11_chunkedvector_chunk, &self->chunks);
|
||||||
#endif
|
assert(last_chunk.capacity == last_chunk.length);
|
||||||
|
#endif
|
||||||
c11_chunkedvector_chunk chunk = {
|
c11_chunkedvector_chunk chunk = {
|
||||||
.length = 0,
|
.length = 0,
|
||||||
.capacity = 1U << (unsigned int)self->chunks.length,
|
.capacity = 1U << (unsigned int)self->chunks.length,
|
||||||
@ -67,9 +67,14 @@ void* c11_chunkedvector__emplace(c11_chunkedvector* self) {
|
|||||||
self->capacity += chunk.capacity;
|
self->capacity += chunk.capacity;
|
||||||
c11_vector__push(c11_chunkedvector_chunk, &self->chunks, chunk);
|
c11_vector__push(c11_chunkedvector_chunk, &self->chunks, chunk);
|
||||||
}
|
}
|
||||||
int last_chunk_index = c11_bit_length(self->length + 1) - 1;
|
#if 1
|
||||||
|
int last_chunk_index = c11__bit_length(self->length + 1) - 1;
|
||||||
c11_chunkedvector_chunk* last_chunk =
|
c11_chunkedvector_chunk* last_chunk =
|
||||||
c11__at(c11_chunkedvector_chunk, &self->chunks, last_chunk_index);
|
c11__at(c11_chunkedvector_chunk, &self->chunks, last_chunk_index);
|
||||||
|
#else
|
||||||
|
// This is not correct, because there is some pre-allocated chunks
|
||||||
|
c11_chunkedvector_chunk* last_chunk = &c11_vector__back(c11_chunkedvector_chunk, &self->chunks);
|
||||||
|
#endif
|
||||||
void* p = (char*)last_chunk->data + self->elem_size * last_chunk->length;
|
void* p = (char*)last_chunk->data + self->elem_size * last_chunk->length;
|
||||||
last_chunk->length++;
|
last_chunk->length++;
|
||||||
self->length++;
|
self->length++;
|
||||||
@ -77,7 +82,7 @@ void* c11_chunkedvector__emplace(c11_chunkedvector* self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* c11_chunkedvector__at(c11_chunkedvector* self, int index) {
|
void* c11_chunkedvector__at(c11_chunkedvector* self, int index) {
|
||||||
int chunk_index = c11_bit_length(index + 1) - 1;
|
int chunk_index = c11__bit_length(index + 1) - 1;
|
||||||
c11_chunkedvector_chunk* chunk = c11__at(c11_chunkedvector_chunk, &self->chunks, chunk_index);
|
c11_chunkedvector_chunk* chunk = c11__at(c11_chunkedvector_chunk, &self->chunks, chunk_index);
|
||||||
return (char*)chunk->data + (index + 1 - (1U << (unsigned int)chunk_index)) * self->elem_size;
|
return (char*)chunk->data + (index + 1 - (1U << (unsigned int)chunk_index)) * self->elem_size;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user