Some code clean-up + added Makefile.

This commit is contained in:
LoRd_MuldeR 2022-11-20 18:02:12 +01:00
parent b8a6287e14
commit 1bf74ffafb
3 changed files with 90 additions and 30 deletions

3
.gitignore vendored
View File

@ -1,5 +1,6 @@
/.vs /.vs
/*.suo /*.suo
/*.user /*.user
/**/bin
/**/lib
/**/obj /**/obj
/bin

34
Makefile Normal file
View File

@ -0,0 +1,34 @@
DUMPMACHINE := $(shell $(CC) -dumpmachine)
ifneq ($(firstword $(filter x86_64-%,$(DUMPMACHINE))),)
XCFLAGS = -march=x86-64 -mtune=nocona
else ifneq ($(firstword $(filter i686-%,$(DUMPMACHINE))),)
XCFLAGS = -march=pentiumpro -mtune=intel
endif
CFLAGS = -O3 -DNDEBUG -Ilibhashset/include $(XCFLAGS)
BASE_DIR := libhashset
SRC_PATH := $(BASE_DIR)/src
OBJ_PATH := $(BASE_DIR)/obj
LIB_PATH := $(BASE_DIR)/lib
LIB_FILE := $(LIB_PATH)/libhashset-1.a
OBJ_FILE := $(OBJ_PATH)/hash_set.o
.PHONY: all clean
all: $(LIB_FILE)
$(LIB_FILE): $(OBJ_FILE) $(LIB_PATH)
$(AR) rcs $@ $<
$(OBJ_FILE): $(SRC_PATH) $(OBJ_PATH)
$(CC) $(CFLAGS) -c $(SRC_PATH)/$(patsubst %.o,%.c,$(notdir $@)) -o $@
$(SRC_PATH) $(OBJ_PATH) $(LIB_PATH):
mkdir -p $@
clean:
rm -f $(LIB_FILE) $(OBJ_PATH)/*.o

View File

@ -38,15 +38,50 @@ struct _hash_set
struct _hash_set_data data; struct _hash_set_data data;
}; };
/* ========================================================================= */
/* PRIVATE FUNCTIONS */
/* ========================================================================= */
#define IS_VALID(X,Y) (get_flag((X).used, (Y)) && (!get_flag((X).deleted, (Y)))) #define IS_VALID(X,Y) (get_flag((X).used, (Y)) && (!get_flag((X).deleted, (Y))))
#define BOUND(MIN,VAL,MAX) (((VAL) < (MIN)) ? (MIN) : (((VAL) > (MAX)) ? (MAX) : (VAL))) #define BOUND(MIN,VAL,MAX) (((VAL) < (MIN)) ? (MIN) : (((VAL) > (MAX)) ? (MAX) : (VAL)))
#define SAFE_FREE(X) do { if ((X)) { free((X)); (X) = NULL; } } while(0) #define SAFE_FREE(X) do { if ((X)) { free((X)); (X) = NULL; } } while(0)
/* ========================================================================= */ /* ------------------------------------------------- */
/* PRIVATE FUNCTIONS */ /* Math */
/* ========================================================================= */ /* ------------------------------------------------- */
static FORCE_INLINE size_t round_sz(double d)
{
return (d >= 0.0) ? ((size_t)(d + 0.5)) : ((size_t)0U);
}
static FORCE_INLINE size_t div_ceil(const size_t value, const size_t divisor)
{
return (value / divisor) + ((value % divisor != 0U) ? 1U : 0U);
}
static FORCE_INLINE size_t safe_mult2(const size_t value)
{
return (value < (SIZE_MAX >> 1)) ? (value << 1) : SIZE_MAX;
}
static FORCE_INLINE size_t next_pow2(const size_t minimum)
{
size_t result = 2U;
while (result < minimum)
{
result = safe_mult2(result);
}
return result;
}
/* ------------------------------------------------- */
/* Hash function */
/* ------------------------------------------------- */
static FORCE_INLINE void hash_u64(uint64_t *const h, uint64_t value) static FORCE_INLINE void hash_u64(uint64_t *const h, uint64_t value)
{ {
@ -66,27 +101,9 @@ static INLINE size_t hash(const uint64_t value, const uint64_t tweak, const size
return (size_t)(h % ((uint64_t)capacity)); return (size_t)(h % ((uint64_t)capacity));
} }
static FORCE_INLINE size_t safe_mult2(const size_t value) /* ------------------------------------------------- */
{ /* Allocation */
return (value < (SIZE_MAX >> 1)) ? (value << 1) : SIZE_MAX; /* ------------------------------------------------- */
}
static FORCE_INLINE size_t round_sz(double d)
{
return (d >= 0.0) ? ((size_t)(d + 0.5)) : ((size_t)(d - ((double)((size_t)(d - 1))) + 0.5)) + ((size_t)(d - 1));
}
static FORCE_INLINE size_t next_pow2(const size_t minimum)
{
size_t result = 2U;
while (result < minimum)
{
result = safe_mult2(result);
}
return result;
}
static INLINE bool_t alloc_data(struct _hash_set_data *const data, const size_t capacity) static INLINE bool_t alloc_data(struct _hash_set_data *const data, const size_t capacity)
{ {
@ -98,14 +115,14 @@ static INLINE bool_t alloc_data(struct _hash_set_data *const data, const size_t
return FALSE; return FALSE;
} }
data->used = (uint8_t*) calloc((capacity / 8U) + ((capacity % 8U != 0U) ? 1U : 0U), sizeof(uint8_t)); data->used = (uint8_t*) calloc(div_ceil(capacity, 8U), sizeof(uint8_t));
if (!data->used) if (!data->used)
{ {
SAFE_FREE(data->values); SAFE_FREE(data->values);
return FALSE; return FALSE;
} }
data->deleted = (uint8_t*) calloc((capacity / 8U) + ((capacity % 8U != 0U) ? 1U : 0U), sizeof(uint8_t)); data->deleted = (uint8_t*) calloc(div_ceil(capacity, 8U), sizeof(uint8_t));
if (!data->deleted) if (!data->deleted)
{ {
SAFE_FREE(data->used); SAFE_FREE(data->used);
@ -128,21 +145,29 @@ static INLINE void free_data(struct _hash_set_data *const data)
} }
} }
static INLINE bool_t get_flag(const uint8_t *const flags, const size_t index) /* ------------------------------------------------- */
/* Flags */
/* ------------------------------------------------- */
static INLINE bool_t get_flag(const uint8_t* const flags, const size_t index)
{ {
return (flags[index / 8U] >> (index % 8U)) & 1U; return (flags[index / 8U] >> (index % 8U)) & 1U;
} }
static INLINE void set_flag(uint8_t *const flags, const size_t index) static INLINE void set_flag(uint8_t* const flags, const size_t index)
{ {
flags[index / 8U] |= UINT8_C(1) << (index % 8U); flags[index / 8U] |= UINT8_C(1) << (index % 8U);
} }
static INLINE void clear_flag(uint8_t *const flags, const size_t index) static INLINE void clear_flag(uint8_t* const flags, const size_t index)
{ {
flags[index / 8U] &= ~(UINT8_C(1) << (index % 8U)); flags[index / 8U] &= ~(UINT8_C(1) << (index % 8U));
} }
/* ------------------------------------------------- */
/* Set functions */
/* ------------------------------------------------- */
static INLINE bool_t find_slot(const struct _hash_set_data *const data, const uint64_t value, size_t *const index_out) static INLINE bool_t find_slot(const struct _hash_set_data *const data, const uint64_t value, size_t *const index_out)
{ {
size_t index; size_t index;