mirror of
https://github.com/typesense/typesense.git
synced 2025-05-17 20:22:32 +08:00
69 lines
1.8 KiB
C++
69 lines
1.8 KiB
C++
#pragma once
|
|
|
|
#include <stdio.h>
|
|
#include <cstdlib>
|
|
#include <for.h>
|
|
|
|
#define FOR_GROWTH_FACTOR 1.3
|
|
#define FOR_ELE_SIZE sizeof(uint32_t)
|
|
#define SORTED_METADATA_OVERHEAD 5
|
|
|
|
class forarray {
|
|
private:
|
|
uint32_t size_bytes = 0;
|
|
uint32_t length_bytes = 0;
|
|
uint32_t length = 0;
|
|
uint8_t* in;
|
|
public:
|
|
forarray(const uint32_t n=2) {
|
|
size_bytes = n * FOR_ELE_SIZE;
|
|
in = new uint8_t[size_bytes];
|
|
}
|
|
|
|
static inline uint32_t required_bits(const uint32_t v) {
|
|
return v == 0 ? 0 : 32 - __builtin_clz(v);
|
|
}
|
|
|
|
uint32_t inline sorted_append_size_required(uint32_t value) {
|
|
uint32_t m = *(uint32_t *)(in + 0);
|
|
uint32_t bnew = required_bits(value - m);
|
|
return SORTED_METADATA_OVERHEAD + for_compressed_size_bits(length+1, bnew);
|
|
}
|
|
|
|
// returns false if malloc fails
|
|
bool append_sorted(uint32_t value) {
|
|
uint32_t size_required = sorted_append_size_required(value);
|
|
|
|
if(size_required > size_bytes) {
|
|
// grow the array first
|
|
size_t new_size = (size_t) (size_required * FOR_GROWTH_FACTOR);
|
|
uint8_t *new_location = (uint8_t *) realloc(in, new_size);
|
|
if(new_location == NULL) return false;
|
|
in = new_location;
|
|
size_bytes = (uint32_t) new_size;
|
|
}
|
|
|
|
uint32_t new_length_bytes = for_append_sorted(in, length, value);
|
|
if(new_length_bytes == 0) return false;
|
|
|
|
length_bytes = new_length_bytes;
|
|
length++;
|
|
return true;
|
|
}
|
|
|
|
uint32_t at(uint32_t index) {
|
|
return for_select(in, index);
|
|
}
|
|
|
|
uint32_t getSizeInBytes() {
|
|
return size_bytes;
|
|
}
|
|
|
|
uint32_t getLength() {
|
|
return length;
|
|
}
|
|
|
|
void print_stats() {
|
|
printf("length: %d, length_bytes: %d, size_bytes: %d\n", length, length_bytes, size_bytes);
|
|
}
|
|
}; |