diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..b68024f --- /dev/null +++ b/.clang-format @@ -0,0 +1,246 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveAssignments: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: true +AlignConsecutiveBitFields: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveDeclarations: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveMacros: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveShortCaseStatements: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCaseColons: false +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: + Kind: Always + OverEmptyLines: 0 +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowBreakBeforeNoexceptSpecifier: Never +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortCompoundRequirementOnASingleLine: true +AllowShortEnumsOnASingleLine: true +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: true +BitFieldColonSpacing: Both +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterExternBlock: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakAdjacentStringLiterals: true +BreakAfterAttributes: Leave +BreakAfterJavaFieldAnnotations: false +BreakArrays: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: Always +BreakBeforeBraces: Attach +BreakBeforeInlineASMColon: OnlyMultiline +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakInheritanceList: BeforeColon +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: false +IndentCaseBlocks: false +IndentCaseLabels: false +IndentExternBlock: AfterExternBlock +IndentGotoLabels: true +IndentPPDirectives: None +IndentRequiresClause: true +IndentWidth: 2 +IndentWrappedFunctionNames: false +InsertBraces: false +InsertNewlineAtEOF: false +InsertTrailingCommas: None +IntegerLiteralSeparator: + Binary: 0 + BinaryMinDigits: 0 + Decimal: 0 + DecimalMinDigits: 0 + Hex: 0 + HexMinDigits: 0 +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +KeepEmptyLinesAtEOF: false +LambdaBodyIndentation: Signature +LineEnding: DeriveLF +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PackConstructorInitializers: BinPack +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakScopeResolution: 500 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyIndentedWhitespace: 0 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +PPIndentWidth: -1 +QualifierAlignment: Leave +ReferenceAlignment: Pointer +ReflowComments: true +RemoveBracesLLVM: false +RemoveParentheses: Leave +RemoveSemicolon: false +RequiresClausePosition: OwnLine +RequiresExpressionIndentation: OuterScope +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SkipMacroDefinitionBody: false +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: LexicographicNumeric +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceAroundPointerQualifiers: Default +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeJsonColon: false +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + AfterPlacementOperator: true + AfterRequiresInClause: false + AfterRequiresInExpression: false + BeforeNonEmptyParentheses: false +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Never +SpacesInContainerLiterals: true +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParens: Never +SpacesInParensOptions: + InCStyleCasts: false + InConditionalStatements: false + InEmptyParentheses: false + Other: false +SpacesInSquareBrackets: false +Standard: Latest +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseTab: Never +VerilogBreakBetweenInstancePorts: true +WhitespaceSensitiveMacros: + - BOOST_PP_STRINGIZE + - CF_SWIFT_NAME + - NS_SWIFT_NAME + - PP_STRINGIZE + - STRINGIZE +... + diff --git a/.clang-format-ignore b/.clang-format-ignore new file mode 100644 index 0000000..9d08084 --- /dev/null +++ b/.clang-format-ignore @@ -0,0 +1,6 @@ +.git/* +.github/* +.direnv/* +build/* +result/* +tests/munit/* diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2bb27a2..d7a89e9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: "build" +name: build on: pull_request: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..6a6deb8 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,22 @@ +name: lint + +on: + push: + pull_request: + +jobs: + lint: + name: Formatting Check + runs-on: ubuntu-latest + strategy: + matrix: + path: + - "src" + - "tests" + steps: + - uses: actions/checkout@v4 + - name: Run clang-format style check for C/C++/Protobuf programs. + uses: jidicula/clang-format-action@v4.13.0 + with: + clang-format-version: "18" + check-path: ${{ matrix.path }} diff --git a/README.md b/README.md index 937530a..881e58d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # C hashmap implementations -[![build](https://github.com/theobori/tinyhash/actions/workflows/build.yml/badge.svg)](https://github.com/theobori/tinyhash/actions/workflows/build.yml) +[![build](https://github.com/theobori/tinyhash/actions/workflows/build.yml/badge.svg)](https://github.com/theobori/tinyhash/actions/workflows/build.yml) [![lint](https://github.com/theobori/tinyhash/actions/workflows/lint.yml/badge.svg)](https://github.com/theobori/tinyhash/actions/workflows/lint.yml) This is a library containing multiple C implementations of hashmap. The public API is deliberately simple and user-friendly. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6f80368..bc74d99 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,32 +1,27 @@ -project (tinyhash-lib) +project(tinyhash-lib) -set (TINYHASH_NAME "tinyhash" CACHE INTERNAL "") +set(TINYHASH_NAME "tinyhash" CACHE INTERNAL "") if (BUILD_STATIC) - set (TINYHASH_LIB_TYPE STATIC) -else () - set (TINYHASH_LIB_TYPE SHARED) -endif () + set(TINYHASH_LIB_TYPE STATIC) +else() + set(TINYHASH_LIB_TYPE SHARED) +endif() add_subdirectory(common) add_subdirectory(separate_chaining) add_subdirectory(open_addressing) -set (TINYHASH_SRC - tinyhash.c -) +set(TINYHASH_SRC tinyhash.c) -set (TINYHASH_HEADERS - tinyhash.h -) +set(TINYHASH_HEADERS tinyhash.h) -add_library( - ${TINYHASH_NAME} ${TINYHASH_LIB_TYPE} +add_library(${TINYHASH_NAME} ${TINYHASH_LIB_TYPE} ${TINYHASH_SRC} $ $ $ ) -install (TARGETS ${TINYHASH_NAME} DESTINATION lib) -install (FILES ${TINYHASH_HEADERS} DESTINATION include/${TINYHASH_NAME}) +install(TARGETS ${TINYHASH_NAME} DESTINATION lib) +install(FILES ${TINYHASH_HEADERS} DESTINATION include/${TINYHASH_NAME}) diff --git a/src/common/hash.c b/src/common/hash.c index 6c73668..177e22c 100644 --- a/src/common/hash.c +++ b/src/common/hash.c @@ -4,16 +4,16 @@ #define TH_HASH_INITIAL_VALUE 2166136261u #define TH_HASH_MUL_VALUE 16777619 -uint32_t th_hash(uint8_t *bytes, size_t size) -{ - if (bytes == NULL) return 0; - - uint32_t hash = TH_HASH_INITIAL_VALUE; +uint32_t th_hash(uint8_t *bytes, size_t size) { + if (bytes == NULL) + return 0; - for (int i = 0; i < size; i++) { - hash ^= bytes[i]; - hash *= TH_HASH_MUL_VALUE; - } + uint32_t hash = TH_HASH_INITIAL_VALUE; - return hash; + for (int i = 0; i < size; i++) { + hash ^= bytes[i]; + hash *= TH_HASH_MUL_VALUE; + } + + return hash; } diff --git a/src/common/key.c b/src/common/key.c index 057851f..5218541 100644 --- a/src/common/key.c +++ b/src/common/key.c @@ -1,20 +1,20 @@ +#include "key.h" + #include -#include "key.h" #include "hash.h" -th_key_t th_key_create(th_any_t data, size_t size) -{ - return (th_key_t) { - .hash = th_hash(data, size), - .size = size, - .data = data, - }; +th_key_t th_key_create(th_any_t data, size_t size) { + return (th_key_t){ + .hash = th_hash(data, size), + .size = size, + .data = data, + }; } -bool th_key_is_equal(th_key_t *first, th_key_t *second) -{ - if (first->size != second->size) return false; +bool th_key_is_equal(th_key_t *first, th_key_t *second) { + if (first->size != second->size) + return false; - return memcmp(first->data, second->data, first->size) == 0; + return memcmp(first->data, second->data, first->size) == 0; } diff --git a/src/common/key.h b/src/common/key.h index d7276eb..f208b2f 100644 --- a/src/common/key.h +++ b/src/common/key.h @@ -1,16 +1,16 @@ #ifndef __TINYHASH_COMMON_KEY_H__ #define __TINYHASH_COMMON_KEY_H__ +#include #include #include -#include #include "types.h" typedef struct { - uint32_t hash; - size_t size; - th_any_t data; + uint32_t hash; + size_t size; + th_any_t data; } th_key_t; th_key_t th_key_create(th_any_t data, size_t size); diff --git a/src/common/table.h b/src/common/table.h index 0aa95c9..c0bf2e0 100644 --- a/src/common/table.h +++ b/src/common/table.h @@ -1,7 +1,6 @@ #ifndef __TINYHASH_COMMON_TABLE_H__ #define __TINYHASH_COMMON_TABLE_H__ -#define TH_TABLE_NEXT_CAPACITY(capacity) \ - (capacity) == 0 ? 8 : (capacity) * 2 +#define TH_TABLE_NEXT_CAPACITY(capacity) (capacity) == 0 ? 8 : (capacity) * 2 #endif diff --git a/src/open_addressing/CMakeLists.txt b/src/open_addressing/CMakeLists.txt index f423fe3..8db2de3 100644 --- a/src/open_addressing/CMakeLists.txt +++ b/src/open_addressing/CMakeLists.txt @@ -1,10 +1,10 @@ set(OPEN_ADDRESSING_SRC - table.c + table.c ) set(OPEN_ADDRESSING_HEADERS - entry.h - table.h + entry.h + table.h ) add_library(open_addressing_objects OBJECT ${OPEN_ADDRESSING_SRC}) diff --git a/src/open_addressing/entry.h b/src/open_addressing/entry.h index 44d241f..df078d4 100644 --- a/src/open_addressing/entry.h +++ b/src/open_addressing/entry.h @@ -1,17 +1,17 @@ #ifndef __TINYHASH_OA_ENTRY_H__ #define __TINYHASH_OA_ENTRY_H__ +#include #include #include -#include #include "../common/hash.h" #include "../common/key.h" typedef struct th_oa_entry_s { - th_key_t *key; - th_any_t value; - bool is_tombstone; + th_key_t *key; + th_any_t value; + bool is_tombstone; } th_oa_entry_t; #endif diff --git a/src/open_addressing/table.c b/src/open_addressing/table.c index d52e8b4..be39646 100644 --- a/src/open_addressing/table.c +++ b/src/open_addressing/table.c @@ -1,184 +1,183 @@ +#include "../common/table.h" + #include #include #include #include -#include "table.h" -#include "../common/table.h" #include "entry.h" +#include "table.h" static bool th_oa_table_put_with_key(th_oa_table_t *table, th_key_t *key, - th_any_t value); + th_any_t value); -void th_oa_table_init(th_oa_table_t *table) -{ - table->capacity = 0; - table->count = 0; - table->entries = NULL; +void th_oa_table_init(th_oa_table_t *table) { + table->capacity = 0; + table->count = 0; + table->entries = NULL; } -static th_oa_table_t *_th_oa_table_create() -{ - th_oa_table_t *table = malloc(sizeof(th_oa_table_t)); +static th_oa_table_t *_th_oa_table_create() { + th_oa_table_t *table = malloc(sizeof(th_oa_table_t)); - if (table == NULL) return NULL; + if (table == NULL) + return NULL; - th_oa_table_init(table); + th_oa_table_init(table); - return table; + return table; } -th_generic_table_t th_oa_table_create() -{ - return (th_generic_table_t) _th_oa_table_create(); +th_generic_table_t th_oa_table_create() { + return (th_generic_table_t)_th_oa_table_create(); } -static bool th_oa_table_copy(th_oa_table_t *dest, th_oa_table_t *src) -{ - bool success; +static bool th_oa_table_copy(th_oa_table_t *dest, th_oa_table_t *src) { + bool success; - for (int i = 0; i < src->capacity; i++) { - th_oa_entry_t *entry = &src->entries[i]; + for (int i = 0; i < src->capacity; i++) { + th_oa_entry_t *entry = &src->entries[i]; - if (entry->key == NULL) continue; - - success = th_oa_table_put_with_key( - dest, - entry->key, - entry->value - ); + if (entry->key == NULL) + continue; - if (success == false) return false; - } + success = th_oa_table_put_with_key(dest, entry->key, entry->value); - return true; + if (success == false) + return false; + } + + return true; } -static bool th_oa_table_increase(th_oa_table_t *table) -{ - th_oa_table_t new_table; - bool success; +static bool th_oa_table_increase(th_oa_table_t *table) { + th_oa_table_t new_table; + bool success; - th_oa_table_init(&new_table); + th_oa_table_init(&new_table); - new_table.capacity = TH_TABLE_NEXT_CAPACITY(table->capacity); + new_table.capacity = TH_TABLE_NEXT_CAPACITY(table->capacity); - size_t size = sizeof(th_oa_entry_t) * new_table.capacity; + size_t size = sizeof(th_oa_entry_t) * new_table.capacity; - new_table.entries = malloc(size); - if (new_table.entries == NULL) return false; + new_table.entries = malloc(size); + if (new_table.entries == NULL) + return false; - memset(new_table.entries, 0, size); + memset(new_table.entries, 0, size); - success = th_oa_table_copy(&new_table, table); - if (success == false) return false; + success = th_oa_table_copy(&new_table, table); + if (success == false) + return false; - th_oa_table_free(table); + th_oa_table_free(table); - *table = new_table; + *table = new_table; - return true; + return true; } -static th_oa_entry_t *th_oa_table_find(th_oa_table_t *table, th_key_t *key) -{ - int index = key->hash % table->capacity; - - th_oa_entry_t *tombstone = NULL; - for (;;) { - th_oa_entry_t *entry = &table->entries[index]; - - if (entry->key == NULL) { - if (entry->is_tombstone == false) { - return tombstone != NULL ? tombstone : entry; - } else { - if (tombstone == NULL) tombstone = entry; - } - } else if (th_key_is_equal(key, entry->key) == true) { - return entry; - } - - index = (index + 1) % table->capacity; +static th_oa_entry_t *th_oa_table_find(th_oa_table_t *table, th_key_t *key) { + int index = key->hash % table->capacity; + + th_oa_entry_t *tombstone = NULL; + for (;;) { + th_oa_entry_t *entry = &table->entries[index]; + + if (entry->key == NULL) { + if (entry->is_tombstone == false) { + return tombstone != NULL ? tombstone : entry; + } else { + if (tombstone == NULL) + tombstone = entry; + } + } else if (th_key_is_equal(key, entry->key) == true) { + return entry; } + + index = (index + 1) % table->capacity; + } } th_any_t th_oa_table_get(th_generic_table_t generic_table, th_any_t data, - size_t data_size) -{ - th_oa_table_t *table = (th_oa_table_t *) generic_table; - if (table->capacity == 0) return NULL; - - th_key_t key = th_key_create(data, data_size); - th_oa_entry_t *entry = th_oa_table_find(table, &key); - if (entry->key == NULL) return NULL; - - return entry->value; -} + size_t data_size) { + th_oa_table_t *table = (th_oa_table_t *)generic_table; + if (table->capacity == 0) + return NULL; -static bool th_oa_table_put_with_key(th_oa_table_t *table, th_key_t *key, - th_any_t value) -{ - if (table->count >= (table->capacity * TH_OA_LOAD_FACTOR)) { - if (th_oa_table_increase(table) == false) return false; - } + th_key_t key = th_key_create(data, data_size); + th_oa_entry_t *entry = th_oa_table_find(table, &key); + if (entry->key == NULL) + return NULL; - th_oa_entry_t *entry = th_oa_table_find(table, key); + return entry->value; +} - if (entry->key == NULL) { - if (entry->is_tombstone == false) table->count++; - } else { - free(entry->key); - } +static bool th_oa_table_put_with_key(th_oa_table_t *table, th_key_t *key, + th_any_t value) { + if (table->count >= (table->capacity * TH_OA_LOAD_FACTOR)) { + if (th_oa_table_increase(table) == false) + return false; + } + + th_oa_entry_t *entry = th_oa_table_find(table, key); + + if (entry->key == NULL) { + if (entry->is_tombstone == false) + table->count++; + } else { + free(entry->key); + } - entry->key = malloc(sizeof(th_key_t)); - *entry->key = *key; - entry->value = value; - entry->is_tombstone = false; + entry->key = malloc(sizeof(th_key_t)); + *entry->key = *key; + entry->value = value; + entry->is_tombstone = false; - return true; + return true; } bool th_oa_table_put(th_generic_table_t generic_table, th_any_t data, - size_t data_size, th_any_t value) -{ - th_oa_table_t *table = (th_oa_table_t *) generic_table; - th_key_t key = th_key_create(data, data_size); + size_t data_size, th_any_t value) { + th_oa_table_t *table = (th_oa_table_t *)generic_table; + th_key_t key = th_key_create(data, data_size); - return th_oa_table_put_with_key(table, &key, value); + return th_oa_table_put_with_key(table, &key, value); } bool th_oa_table_delete(th_generic_table_t generic_table, th_any_t data, - size_t data_size) -{ - th_oa_table_t *table = (th_oa_table_t *) generic_table; - if (table->capacity == 0) return false; + size_t data_size) { + th_oa_table_t *table = (th_oa_table_t *)generic_table; + if (table->capacity == 0) + return false; - th_key_t key = th_key_create(data, data_size); + th_key_t key = th_key_create(data, data_size); - th_oa_entry_t *entry = th_oa_table_find(table, &key); - if (entry->key == NULL) return false; + th_oa_entry_t *entry = th_oa_table_find(table, &key); + if (entry->key == NULL) + return false; - free(entry->key); + free(entry->key); - entry->key = NULL; - entry->is_tombstone = true; + entry->key = NULL; + entry->is_tombstone = true; - return true; + return true; } -void th_oa_table_free(th_generic_table_t generic_table) -{ - th_oa_table_t *table = (th_oa_table_t *) generic_table; +void th_oa_table_free(th_generic_table_t generic_table) { + th_oa_table_t *table = (th_oa_table_t *)generic_table; - for (int i = 0; i < table->capacity; i++) { - th_oa_entry_t *entry = &table->entries[i]; + for (int i = 0; i < table->capacity; i++) { + th_oa_entry_t *entry = &table->entries[i]; - if (entry->key == NULL) continue; + if (entry->key == NULL) + continue; - free(entry->key); - } + free(entry->key); + } - if (table->entries != NULL) { - free(table->entries); - } + if (table->entries != NULL) { + free(table->entries); + } } diff --git a/src/open_addressing/table.h b/src/open_addressing/table.h index 688cad1..5c8a2e4 100644 --- a/src/open_addressing/table.h +++ b/src/open_addressing/table.h @@ -1,19 +1,19 @@ #ifndef __TINYHASH_OA_TABLE_H__ #define __TINYHASH_OA_TABLE_H__ +#include #include #include -#include -#include "entry.h" #include "../common/types.h" +#include "entry.h" #define TH_OA_LOAD_FACTOR 0.75 typedef struct { - uint32_t count; - uint32_t capacity; - th_oa_entry_t *entries; + uint32_t count; + uint32_t capacity; + th_oa_entry_t *entries; } th_oa_table_t; void th_oa_table_init(th_oa_table_t *table); @@ -21,14 +21,14 @@ void th_oa_table_init(th_oa_table_t *table); th_generic_table_t th_oa_table_create(); th_any_t th_oa_table_get(th_generic_table_t table, th_any_t data, - size_t data_size); + size_t data_size); -bool th_oa_table_put(th_generic_table_t table, th_any_t data, - size_t data_size, th_any_t value); +bool th_oa_table_put(th_generic_table_t table, th_any_t data, size_t data_size, + th_any_t value); void th_oa_table_free(th_generic_table_t table); bool th_oa_table_delete(th_generic_table_t table, th_any_t data, - size_t data_size); + size_t data_size); #endif diff --git a/src/separate_chaining/CMakeLists.txt b/src/separate_chaining/CMakeLists.txt index f3154a4..931fbd7 100644 --- a/src/separate_chaining/CMakeLists.txt +++ b/src/separate_chaining/CMakeLists.txt @@ -1,11 +1,11 @@ set(SEPARATE_CHAINING_SRC - entry.c - table.c + entry.c + table.c ) set(SEPARATE_CHAINING_HEADERS - entry.h - table.h + entry.h + table.h ) add_library(separate_chaining_objects OBJECT ${SEPARATE_CHAINING_SRC}) diff --git a/src/separate_chaining/entry.c b/src/separate_chaining/entry.c index 968f45d..9721362 100644 --- a/src/separate_chaining/entry.c +++ b/src/separate_chaining/entry.c @@ -1,29 +1,30 @@ #include "entry.h" -static th_sc_entry_t *th_sc_entry_new(th_key_t *key, th_any_t value) -{ - th_sc_entry_t *entry = malloc(sizeof(th_sc_entry_t)); +static th_sc_entry_t *th_sc_entry_new(th_key_t *key, th_any_t value) { + th_sc_entry_t *entry = malloc(sizeof(th_sc_entry_t)); - if (entry == NULL) return NULL; + if (entry == NULL) + return NULL; - entry->key = *key; - entry->value = value; - entry->previous = NULL; - entry->next = NULL; + entry->key = *key; + entry->value = value; + entry->previous = NULL; + entry->next = NULL; - return entry; + return entry; } -bool th_sc_entry_add(th_sc_entry_t **root, th_key_t *key, th_any_t value) -{ - th_sc_entry_t *entry = th_sc_entry_new(key, value); +bool th_sc_entry_add(th_sc_entry_t **root, th_key_t *key, th_any_t value) { + th_sc_entry_t *entry = th_sc_entry_new(key, value); - if (entry == NULL) return false; + if (entry == NULL) + return false; - if (*root != NULL) (*root)->previous = entry; + if (*root != NULL) + (*root)->previous = entry; - entry->next = *root; - *root = entry; + entry->next = *root; + *root = entry; - return true; + return true; } diff --git a/src/separate_chaining/entry.h b/src/separate_chaining/entry.h index 0885736..efcc23e 100644 --- a/src/separate_chaining/entry.h +++ b/src/separate_chaining/entry.h @@ -1,18 +1,18 @@ #ifndef __TINYHASH_SC_ENTRY_H__ #define __TINYHASH_SC_ENTRY_H__ +#include #include #include -#include #include "../common/hash.h" #include "../common/key.h" typedef struct th_sc_entry_s { - th_key_t key; - th_any_t value; - struct th_sc_entry_s *previous; - struct th_sc_entry_s *next; + th_key_t key; + th_any_t value; + struct th_sc_entry_s *previous; + struct th_sc_entry_s *next; } th_sc_entry_t; bool th_sc_entry_add(th_sc_entry_t **root, th_key_t *key, th_any_t value); diff --git a/src/separate_chaining/table.c b/src/separate_chaining/table.c index 412dfeb..14924ec 100644 --- a/src/separate_chaining/table.c +++ b/src/separate_chaining/table.c @@ -1,197 +1,192 @@ +#include "../common/table.h" + #include #include #include #include #include "table.h" -#include "../common/table.h" static bool th_sc_table_put_with_key(th_sc_table_t *table, th_key_t *key, - th_any_t value); + th_any_t value); -void th_sc_table_init(th_sc_table_t *table) -{ - table->capacity = 0; - table->count = 0; - table->entries = NULL; +void th_sc_table_init(th_sc_table_t *table) { + table->capacity = 0; + table->count = 0; + table->entries = NULL; } -static th_sc_table_t *_th_sc_table_create() -{ - th_sc_table_t *table = malloc(sizeof(th_sc_table_t)); +static th_sc_table_t *_th_sc_table_create() { + th_sc_table_t *table = malloc(sizeof(th_sc_table_t)); - if (table == NULL) return NULL; + if (table == NULL) + return NULL; - th_sc_table_init(table); + th_sc_table_init(table); - return table; + return table; } -th_generic_table_t th_sc_table_create() -{ - return (th_generic_table_t) _th_sc_table_create(); +th_generic_table_t th_sc_table_create() { + return (th_generic_table_t)_th_sc_table_create(); } -static bool th_sc_table_copy(th_sc_table_t *dest, th_sc_table_t *src) -{ - bool success; +static bool th_sc_table_copy(th_sc_table_t *dest, th_sc_table_t *src) { + bool success; - for (int i = 0; i < src->capacity; i++) { - th_sc_entry_t *entry = src->entries[i]; + for (int i = 0; i < src->capacity; i++) { + th_sc_entry_t *entry = src->entries[i]; - while (entry != NULL) { - success = th_sc_table_put_with_key( - dest, - &entry->key, - entry->value - ); + while (entry != NULL) { + success = th_sc_table_put_with_key(dest, &entry->key, entry->value); - if (success == false) return false; + if (success == false) + return false; - entry = entry->next; - } + entry = entry->next; } + } - return true; + return true; } +static bool th_sc_table_increase(th_sc_table_t *table) { + th_sc_table_t new_table; + bool success; -static bool th_sc_table_increase(th_sc_table_t *table) -{ - th_sc_table_t new_table; - bool success; - - th_sc_table_init(&new_table); + th_sc_table_init(&new_table); - new_table.capacity = TH_TABLE_NEXT_CAPACITY(table->capacity); + new_table.capacity = TH_TABLE_NEXT_CAPACITY(table->capacity); - size_t size = sizeof(th_sc_entry_t *) * new_table.capacity; - new_table.entries = malloc(size); + size_t size = sizeof(th_sc_entry_t *) * new_table.capacity; + new_table.entries = malloc(size); - if (new_table.entries == NULL) return false; + if (new_table.entries == NULL) + return false; - memset(new_table.entries, 0, size); + memset(new_table.entries, 0, size); - success = th_sc_table_copy(&new_table, table); - if (success == false) return false; + success = th_sc_table_copy(&new_table, table); + if (success == false) + return false; - th_sc_table_free((th_generic_table_t) table); + th_sc_table_free((th_generic_table_t)table); - *table = new_table; + *table = new_table; - return true; + return true; } -static th_sc_entry_t *th_sc_table_find(th_sc_table_t *table, th_key_t *key) -{ - // Avoid division by 0 - if (table->capacity == 0) return NULL; - - int index = key->hash % table->capacity; - th_sc_entry_t *entry = table->entries[index]; +static th_sc_entry_t *th_sc_table_find(th_sc_table_t *table, th_key_t *key) { + // Avoid division by 0 + if (table->capacity == 0) + return NULL; - while (entry != NULL) { - if (th_key_is_equal(key, &entry->key)) { - return entry; - } + int index = key->hash % table->capacity; + th_sc_entry_t *entry = table->entries[index]; - entry = entry->next; + while (entry != NULL) { + if (th_key_is_equal(key, &entry->key)) { + return entry; } - return NULL; + entry = entry->next; + } + + return NULL; } th_any_t th_sc_table_get(th_generic_table_t generic_table, th_any_t data, - size_t data_size) -{ - th_sc_table_t *table = (th_sc_table_t *) generic_table; - th_key_t key = th_key_create(data, data_size); - - th_sc_entry_t *entry = th_sc_table_find(table, &key); - if (entry == NULL) return NULL; - - return entry->value; + size_t data_size) { + th_sc_table_t *table = (th_sc_table_t *)generic_table; + th_key_t key = th_key_create(data, data_size); + + th_sc_entry_t *entry = th_sc_table_find(table, &key); + if (entry == NULL) + return NULL; + + return entry->value; } static bool th_sc_table_put_with_key(th_sc_table_t *table, th_key_t *key, - th_any_t value) -{ - if (table->count >= table->capacity) { - if (th_sc_table_increase(table) == false) return false; - } + th_any_t value) { + if (table->count >= table->capacity) { + if (th_sc_table_increase(table) == false) + return false; + } - th_sc_entry_t *entry = th_sc_table_find(table, key); + th_sc_entry_t *entry = th_sc_table_find(table, key); - if (entry == NULL) { - int index = key->hash % table->capacity; - th_sc_entry_t **bucket = &table->entries[index]; + if (entry == NULL) { + int index = key->hash % table->capacity; + th_sc_entry_t **bucket = &table->entries[index]; - if (*bucket == NULL) table->count++; - if (th_sc_entry_add(bucket, key, value) == false) return false; - } else { - entry->value = value; - } + if (*bucket == NULL) + table->count++; + if (th_sc_entry_add(bucket, key, value) == false) + return false; + } else { + entry->value = value; + } - return true; + return true; } bool th_sc_table_put(th_generic_table_t generic_table, th_any_t data, - size_t data_size, th_any_t value) -{ - th_sc_table_t *table = (th_sc_table_t *) generic_table; - th_key_t key = th_key_create(data, data_size); + size_t data_size, th_any_t value) { + th_sc_table_t *table = (th_sc_table_t *)generic_table; + th_key_t key = th_key_create(data, data_size); - return th_sc_table_put_with_key(table, &key, value); + return th_sc_table_put_with_key(table, &key, value); } bool th_sc_table_delete(th_generic_table_t generic_table, th_any_t data, - size_t data_size) -{ - th_sc_table_t *table = (th_sc_table_t *) generic_table; - th_key_t key = th_key_create(data, data_size); - - th_sc_entry_t *entry = th_sc_table_find(table, &key); - if (entry == NULL) return false; - - int index = entry->key.hash % table->capacity; - th_sc_entry_t **bucket = &table->entries[index]; - - if (entry->next == NULL && entry->previous == NULL) { - *bucket = NULL; - table->count--; - } else if (entry->previous == NULL) { - *bucket = entry->next; - (*bucket)->previous = NULL; - } else if (entry->next == NULL) { - entry->previous->next = entry->next; - } else { - entry->previous->next = entry->next; - entry->next->previous = entry->previous; - } - - free(entry); - - return true; + size_t data_size) { + th_sc_table_t *table = (th_sc_table_t *)generic_table; + th_key_t key = th_key_create(data, data_size); + + th_sc_entry_t *entry = th_sc_table_find(table, &key); + if (entry == NULL) + return false; + + int index = entry->key.hash % table->capacity; + th_sc_entry_t **bucket = &table->entries[index]; + + if (entry->next == NULL && entry->previous == NULL) { + *bucket = NULL; + table->count--; + } else if (entry->previous == NULL) { + *bucket = entry->next; + (*bucket)->previous = NULL; + } else if (entry->next == NULL) { + entry->previous->next = entry->next; + } else { + entry->previous->next = entry->next; + entry->next->previous = entry->previous; + } + + free(entry); + + return true; } -void th_sc_table_free(th_generic_table_t generic_table) -{ - th_sc_table_t *table = (th_sc_table_t *) generic_table; - th_sc_entry_t *entry; - th_sc_entry_t *previous; +void th_sc_table_free(th_generic_table_t generic_table) { + th_sc_table_t *table = (th_sc_table_t *)generic_table; + th_sc_entry_t *entry; + th_sc_entry_t *previous; - for (int i = 0; i < table->capacity; i++) { - entry = table->entries[i]; + for (int i = 0; i < table->capacity; i++) { + entry = table->entries[i]; - while (entry != NULL) { - previous = entry; - entry = entry->next; + while (entry != NULL) { + previous = entry; + entry = entry->next; - free(previous); - } + free(previous); } + } - if (table->entries != NULL) { - free(table->entries); - } + if (table->entries != NULL) { + free(table->entries); + } } diff --git a/src/separate_chaining/table.h b/src/separate_chaining/table.h index f9fcca0..2c38c6e 100644 --- a/src/separate_chaining/table.h +++ b/src/separate_chaining/table.h @@ -1,17 +1,17 @@ #ifndef __TINYHASH_SC_TABLE_H__ #define __TINYHASH_SC_TABLE_H__ +#include #include #include -#include -#include "entry.h" #include "../common/types.h" +#include "entry.h" typedef struct { - uint32_t count; - uint32_t capacity; - th_sc_entry_t **entries; + uint32_t count; + uint32_t capacity; + th_sc_entry_t **entries; } th_sc_table_t; void th_sc_table_init(th_sc_table_t *table); @@ -19,14 +19,14 @@ void th_sc_table_init(th_sc_table_t *table); th_generic_table_t th_sc_table_create(); th_any_t th_sc_table_get(th_generic_table_t table, th_any_t data, - size_t data_size); + size_t data_size); -bool th_sc_table_put(th_generic_table_t table, th_any_t data, - size_t data_size, th_any_t value); +bool th_sc_table_put(th_generic_table_t table, th_any_t data, size_t data_size, + th_any_t value); void th_sc_table_free(th_generic_table_t table); bool th_sc_table_delete(th_generic_table_t table, th_any_t data, - size_t data_size); + size_t data_size); #endif diff --git a/src/tinyhash.c b/src/tinyhash.c index 83ef40f..66f5537 100644 --- a/src/tinyhash.c +++ b/src/tinyhash.c @@ -1,59 +1,54 @@ #include "tinyhash.h" -#include "./separate_chaining/table.h" + #include "./open_addressing/table.h" +#include "./separate_chaining/table.h" static th_funcs_t th_funcs[] = { - [TH_SEPARATE_CHAINING] = { - .create = th_sc_table_create, - .get = th_sc_table_get, - .put = th_sc_table_put, - ._delete = th_sc_table_delete, - ._free = th_sc_table_free, - }, - - [TH_OPEN_ADRESSING] = { - .create = th_oa_table_create, - .get = th_oa_table_get, - .put = th_oa_table_put, - ._delete = th_oa_table_delete, - ._free = th_oa_table_free, - }, + [TH_SEPARATE_CHAINING] = + { + .create = th_sc_table_create, + .get = th_sc_table_get, + .put = th_sc_table_put, + ._delete = th_sc_table_delete, + ._free = th_sc_table_free, + }, + + [TH_OPEN_ADRESSING] = + { + .create = th_oa_table_create, + .get = th_oa_table_get, + .put = th_oa_table_put, + ._delete = th_oa_table_delete, + ._free = th_oa_table_free, + }, }; -th_t th_create(th_method_t method) -{ - th_funcs_t funcs = th_funcs[method]; +th_t th_create(th_method_t method) { + th_funcs_t funcs = th_funcs[method]; - return (th_t) { - .method = method, - .funcs = funcs, - .table = funcs.create(), - }; + return (th_t){ + .method = method, + .funcs = funcs, + .table = funcs.create(), + }; } -th_t th_create_default() -{ - return th_create(TH_SEPARATE_CHAINING); -} +th_t th_create_default() { return th_create(TH_SEPARATE_CHAINING); } -th_any_t th_get(th_t *th, th_any_t data, size_t data_size) -{ - return th->funcs.get(th->table, data, data_size); +th_any_t th_get(th_t *th, th_any_t data, size_t data_size) { + return th->funcs.get(th->table, data, data_size); } -bool th_put(th_t *th, th_any_t data, size_t data_size, th_any_t value) -{ - return th->funcs.put(th->table, data, data_size, value); +bool th_put(th_t *th, th_any_t data, size_t data_size, th_any_t value) { + return th->funcs.put(th->table, data, data_size, value); } -bool th_delete(th_t *th, th_any_t data, size_t data_size) -{ - return th->funcs._delete(th->table, data, data_size); +bool th_delete(th_t *th, th_any_t data, size_t data_size) { + return th->funcs._delete(th->table, data, data_size); } -void th_free(th_t *th) -{ - th->funcs._free(th->table); +void th_free(th_t *th) { + th->funcs._free(th->table); - free(th->table); + free(th->table); } diff --git a/src/tinyhash.h b/src/tinyhash.h index 20dbcaf..7040f29 100644 --- a/src/tinyhash.h +++ b/src/tinyhash.h @@ -7,8 +7,8 @@ #include "./common/types.h" typedef enum { - TH_SEPARATE_CHAINING, - TH_OPEN_ADRESSING, + TH_SEPARATE_CHAINING, + TH_OPEN_ADRESSING, } th_method_t; typedef th_generic_table_t (*th_create_func_t)(void); @@ -22,17 +22,17 @@ typedef bool (*th_delete_func_t)(th_generic_table_t, th_any_t, size_t); typedef void (*th_free_func_t)(th_generic_table_t); typedef struct { - th_create_func_t create; - th_get_func_t get; - th_put_func_t put; - th_delete_func_t _delete; - th_free_func_t _free; + th_create_func_t create; + th_get_func_t get; + th_put_func_t put; + th_delete_func_t _delete; + th_free_func_t _free; } th_funcs_t; typedef struct { - th_method_t method; - th_funcs_t funcs; - th_generic_table_t table; + th_method_t method; + th_funcs_t funcs; + th_generic_table_t table; } th_t; th_t th_create(th_method_t method); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 78536e4..bd274e9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -3,10 +3,10 @@ include_directories("../src") project (tinyhash-tests) set (TINYHASH_SRC_TESTS - munit/munit.c - tests.c - test_hash.c - test_table.c + munit/munit.c + tests.c + test_hash.c + test_table.c ) add_executable (tests ${TINYHASH_SRC_TESTS}) diff --git a/tests/test_hash.c b/tests/test_hash.c index da4e7d4..4fa22d6 100644 --- a/tests/test_hash.c +++ b/tests/test_hash.c @@ -1,77 +1,68 @@ -#include "munit/munit.h" - -#include "../src/common/hash.h" #include #include -static struct { char *str; uint32_t hash;} values[] = { - {"hello", 1335831723 }, - {"world", 933488787 }, - {"14738", 672216534 }, - {"18013", 4041707876 }, - {"28502", 1698934288 }, - {"27", 2331153606 }, - {"22125", 3038097389 }, - {"13228", 617068255 }, - {"7269", 398476757 }, - {"32576", 342715562 }, - {"29098", 4228780613 }, - {"6986", 2934559306 }, - {"5484", 3905864472 }, - {"", 2166136261 }, +#include "../src/common/hash.h" +#include "munit/munit.h" + +static struct { + char *str; + uint32_t hash; +} values[] = { + {"hello", 1335831723}, {"world", 933488787}, {"14738", 672216534}, + {"18013", 4041707876}, {"28502", 1698934288}, {"27", 2331153606}, + {"22125", 3038097389}, {"13228", 617068255}, {"7269", 398476757}, + {"32576", 342715562}, {"29098", 4228780613}, {"6986", 2934559306}, + {"5484", 3905864472}, {"", 2166136261}, }; -MunitResult test_th_hash(const MunitParameter params[], void* data) -{ - (void) params; - (void) data; +MunitResult test_th_hash(const MunitParameter params[], void *data) { + (void)params; + (void)data; - for (int i = 0; i < 14; i++) { - uint32_t hash = th_hash((uint8_t *) values[i].str, strlen(values[i].str)); + for (int i = 0; i < 14; i++) { + uint32_t hash = th_hash((uint8_t *)values[i].str, strlen(values[i].str)); - munit_assert_uint(hash, ==, values[i].hash); - } + munit_assert_uint(hash, ==, values[i].hash); + } - return MUNIT_OK; + return MUNIT_OK; } -MunitResult test_th_hash_multiple_iteration(const MunitParameter params[], void* data) -{ - (void) params; - (void) data; +MunitResult test_th_hash_multiple_iteration(const MunitParameter params[], + void *data) { + (void)params; + (void)data; - for (int i = 0; i < 5; i++) { - uint32_t hash = th_hash((uint8_t *) values[0].str, strlen(values[i].str)); + for (int i = 0; i < 5; i++) { + uint32_t hash = th_hash((uint8_t *)values[0].str, strlen(values[i].str)); - munit_assert_uint(hash, ==, values[0].hash); - } + munit_assert_uint(hash, ==, values[0].hash); + } - return MUNIT_OK; + return MUNIT_OK; } -MunitResult test_th_hash_null(const MunitParameter params[], void* data) -{ - (void) params; - (void) data; +MunitResult test_th_hash_null(const MunitParameter params[], void *data) { + (void)params; + (void)data; - uint32_t hash = th_hash(NULL, 0); + uint32_t hash = th_hash(NULL, 0); - munit_assert_uint(hash, ==, 0); + munit_assert_uint(hash, ==, 0); - return MUNIT_OK; + return MUNIT_OK; } -MunitResult test_th_hash_with_int(const MunitParameter params[], void* data) -{ - (void) params; - (void) data; +MunitResult test_th_hash_with_int(const MunitParameter params[], void *data) { + (void)params; + (void)data; - int a = 123; + int a = 123; - uint32_t hash = th_hash((uint8_t *) &a, 4); + uint32_t hash = th_hash((uint8_t *)&a, 4); - munit_assert_uint(hash, ==, 442514334); + munit_assert_uint(hash, ==, 442514334); - return MUNIT_OK; + return MUNIT_OK; } diff --git a/tests/test_hash.h b/tests/test_hash.h index e189ec4..ca322b7 100644 --- a/tests/test_hash.h +++ b/tests/test_hash.h @@ -3,9 +3,10 @@ #include "munit/munit.h" -MunitResult test_th_hash(const MunitParameter params[], void* data); -MunitResult test_th_hash_multiple_iteration(const MunitParameter params[], void* data); -MunitResult test_th_hash_null(const MunitParameter params[], void* data); -MunitResult test_th_hash_with_int(const MunitParameter params[], void* data); +MunitResult test_th_hash(const MunitParameter params[], void *data); +MunitResult test_th_hash_multiple_iteration(const MunitParameter params[], + void *data); +MunitResult test_th_hash_null(const MunitParameter params[], void *data); +MunitResult test_th_hash_with_int(const MunitParameter params[], void *data); #endif diff --git a/tests/test_table.c b/tests/test_table.c index 33e3abe..05d1f60 100644 --- a/tests/test_table.c +++ b/tests/test_table.c @@ -1,229 +1,217 @@ #include #include +#include "../src/open_addressing/table.h" #include "../src/tinyhash.h" #include "munit/munit.h" -#include "../src/open_addressing/table.h" - typedef struct { - uint32_t a; - uint8_t b[22]; + uint32_t a; + uint8_t b[22]; } TestStruct; #define SET_GET_ITERATIONS 256 * 256 -static th_method_t str_to_method(const char *str) -{ - switch (*str) { - case 'o': return TH_OPEN_ADRESSING; - case 's': return TH_SEPARATE_CHAINING; - } - +static th_method_t str_to_method(const char *str) { + switch (*str) { + case 'o': + return TH_OPEN_ADRESSING; + case 's': return TH_SEPARATE_CHAINING; + } + + return TH_SEPARATE_CHAINING; } -MunitResult test_th_put_and_get(const MunitParameter params[], void* data) -{ - th_any_t value; - const char *method_str = munit_parameters_get(params, "method"); - th_method_t method = str_to_method(method_str); - th_t th = th_create(method); +MunitResult test_th_put_and_get(const MunitParameter params[], void *data) { + th_any_t value; + const char *method_str = munit_parameters_get(params, "method"); + th_method_t method = str_to_method(method_str); + th_t th = th_create(method); - th_put(&th, "hello", strlen("hello"), (th_any_t) 333); + th_put(&th, "hello", strlen("hello"), (th_any_t)333); - value = th_get(&th, "hello", strlen("hello")); + value = th_get(&th, "hello", strlen("hello")); - munit_assert_uint64((uint64_t) value, ==, 333); + munit_assert_uint64((uint64_t)value, ==, 333); - th_free(&th); + th_free(&th); - return MUNIT_OK; + return MUNIT_OK; } -MunitResult test_th_get_with_empty_table(const MunitParameter params[], void* data) -{ - th_any_t value; - const char *method_str = munit_parameters_get(params, "method"); - th_method_t method = str_to_method(method_str); - th_t th = th_create(method); +MunitResult test_th_get_with_empty_table(const MunitParameter params[], + void *data) { + th_any_t value; + const char *method_str = munit_parameters_get(params, "method"); + th_method_t method = str_to_method(method_str); + th_t th = th_create(method); - value = th_get(&th, "hello", strlen("hello")); - munit_assert_null(value); + value = th_get(&th, "hello", strlen("hello")); + munit_assert_null(value); - th_free(&th); + th_free(&th); - return MUNIT_OK; + return MUNIT_OK; } -MunitResult test_th_put_with_full_table(const MunitParameter params[], void* data) -{ - int *value; +MunitResult test_th_put_with_full_table(const MunitParameter params[], + void *data) { + int *value; - const char *method_str = munit_parameters_get(params, "method"); - th_method_t method = str_to_method(method_str); - th_t th = th_create(method); + const char *method_str = munit_parameters_get(params, "method"); + th_method_t method = str_to_method(method_str); + th_t th = th_create(method); - for (int i = 0; i < SET_GET_ITERATIONS; i++) { - int *j = malloc(sizeof(i)); - *j = i; + for (int i = 0; i < SET_GET_ITERATIONS; i++) { + int *j = malloc(sizeof(i)); + *j = i; - th_put(&th, j, sizeof(i), j); - } + th_put(&th, j, sizeof(i), j); + } - for (int i = 0; i < SET_GET_ITERATIONS; i++) { - value = (int *) th_get(&th, &i, sizeof(i)); - th_delete(&th, &i, sizeof(i)); + for (int i = 0; i < SET_GET_ITERATIONS; i++) { + value = (int *)th_get(&th, &i, sizeof(i)); + th_delete(&th, &i, sizeof(i)); - munit_assert_int(*value, ==, i); + munit_assert_int(*value, ==, i); - free(value); - } + free(value); + } - th_put(&th, "b", strlen("b"), (th_any_t) 1); - th_put(&th, "c", strlen("c"), (th_any_t) 1); - th_put(&th, "d", strlen("d"), (th_any_t) 1); - th_put(&th, "e", strlen("e"), (th_any_t) 1); - th_put(&th, "f", strlen("f"), (th_any_t) 1); - th_put(&th, "g", strlen("g"), (th_any_t) 1); - th_put(&th, "h", strlen("h"), (th_any_t) 1); - th_put(&th, "hva", strlen("hva"), (th_any_t) 1); - th_put(&th, "hb", strlen("hb"), (th_any_t) 1); + th_put(&th, "b", strlen("b"), (th_any_t)1); + th_put(&th, "c", strlen("c"), (th_any_t)1); + th_put(&th, "d", strlen("d"), (th_any_t)1); + th_put(&th, "e", strlen("e"), (th_any_t)1); + th_put(&th, "f", strlen("f"), (th_any_t)1); + th_put(&th, "g", strlen("g"), (th_any_t)1); + th_put(&th, "h", strlen("h"), (th_any_t)1); + th_put(&th, "hva", strlen("hva"), (th_any_t)1); + th_put(&th, "hb", strlen("hb"), (th_any_t)1); - th_put(&th, "azdaz", strlen("azdaz"), (th_any_t) 10); - value = th_get(&th, "azdaz", strlen("azdaz")); + th_put(&th, "azdaz", strlen("azdaz"), (th_any_t)10); + value = th_get(&th, "azdaz", strlen("azdaz")); - munit_assert_int((uint64_t) value, ==, 10); + munit_assert_int((uint64_t)value, ==, 10); - th_free(&th); + th_free(&th); - return MUNIT_OK; + return MUNIT_OK; } -MunitResult test_th_put_overwrite(const MunitParameter params[], void* data) -{ - th_any_t value; - const char *method_str = munit_parameters_get(params, "method"); - th_method_t method = str_to_method(method_str); - th_t th = th_create(method); +MunitResult test_th_put_overwrite(const MunitParameter params[], void *data) { + th_any_t value; + const char *method_str = munit_parameters_get(params, "method"); + th_method_t method = str_to_method(method_str); + th_t th = th_create(method); - th_put(&th, "a", strlen("a"), (th_any_t) 1); - th_put(&th, "b", strlen("b"), (th_any_t) 1); - th_put(&th, "a", strlen("a"), (th_any_t) 2); + th_put(&th, "a", strlen("a"), (th_any_t)1); + th_put(&th, "b", strlen("b"), (th_any_t)1); + th_put(&th, "a", strlen("a"), (th_any_t)2); - value = th_get(&th, "a", strlen("a")); + value = th_get(&th, "a", strlen("a")); - munit_assert_uint64((uint64_t) value, ==, 2); + munit_assert_uint64((uint64_t)value, ==, 2); - th_free(&th); + th_free(&th); - return MUNIT_OK; + return MUNIT_OK; } -MunitResult test_th_put_collision(const MunitParameter params[], void* data) -{ - th_any_t value; - const char *method_str = munit_parameters_get(params, "method"); - th_method_t method = str_to_method(method_str); - th_t th = th_create(method); +MunitResult test_th_put_collision(const MunitParameter params[], void *data) { + th_any_t value; + const char *method_str = munit_parameters_get(params, "method"); + th_method_t method = str_to_method(method_str); + th_t th = th_create(method); + + th_put(&th, "b", strlen("b"), (th_any_t)123); + th_put(&th, "ello", strlen("ello"), (th_any_t)456); - th_put(&th, "b", strlen("b"), (th_any_t) 123); - th_put(&th, "ello", strlen("ello"), (th_any_t) 456); - - value = th_get(&th, "b", strlen("b")); - munit_assert_uint64((uint64_t) value, ==, 123); + value = th_get(&th, "b", strlen("b")); + munit_assert_uint64((uint64_t)value, ==, 123); - value = th_get(&th, "ello", strlen("ello")); - munit_assert_uint64((uint64_t) value, ==, 456); + value = th_get(&th, "ello", strlen("ello")); + munit_assert_uint64((uint64_t)value, ==, 456); - th_free(&th); + th_free(&th); - return MUNIT_OK; + return MUNIT_OK; } -MunitResult test_th_put_struct_as_key(const MunitParameter params[], void* data) -{ - th_any_t value; - TestStruct test_struct; +MunitResult test_th_put_struct_as_key(const MunitParameter params[], + void *data) { + th_any_t value; + TestStruct test_struct; - memset(&test_struct, 0, sizeof(TestStruct)); + memset(&test_struct, 0, sizeof(TestStruct)); - test_struct.b[3] = 222; + test_struct.b[3] = 222; - const char *method_str = munit_parameters_get(params, "method"); - th_method_t method = str_to_method(method_str); - th_t th = th_create(method); + const char *method_str = munit_parameters_get(params, "method"); + th_method_t method = str_to_method(method_str); + th_t th = th_create(method); - th_put(&th, &test_struct, sizeof(TestStruct), (th_any_t) 123); - - value = th_get(&th, &test_struct, sizeof(TestStruct)); - munit_assert_uint64((uint64_t) value, ==, 123); + th_put(&th, &test_struct, sizeof(TestStruct), (th_any_t)123); - munit_assert_uint8(test_struct.b[3], ==, 222); + value = th_get(&th, &test_struct, sizeof(TestStruct)); + munit_assert_uint64((uint64_t)value, ==, 123); - th_free(&th); + munit_assert_uint8(test_struct.b[3], ==, 222); - return MUNIT_OK; + th_free(&th); + + return MUNIT_OK; } -MunitResult test_th_delete(const MunitParameter params[], void* data) -{ - th_any_t value; - bool ok; - - const char *method_str = munit_parameters_get(params, "method"); - th_method_t method = str_to_method(method_str); - th_t th = th_create(method); - - char *keys[] = { - "a", - "b", - "bb", - "bb", - "bbb", - "c", - "ello" - }; - - size_t keys_length = sizeof(keys) / sizeof(keys[0]); - - // Insert key value pair - for (int i = 0; i < keys_length; i++) { - th_put(&th, keys[i], strlen(keys[i]), (th_any_t) (uint64_t) i + 1); - } - - // Check everything exists - for (int i = 0; i < keys_length; i++) { - value = th_get(&th, keys[i], strlen(keys[i])); - munit_assert_not_null(value); - } - - ok = th_delete(&th, "a", strlen("a")); - munit_assert_true(ok); - - ok = th_delete(&th, "a", strlen("a")); - munit_assert_false(ok); - ok = th_delete(&th, "ello", strlen("ello")); - munit_assert_true(ok); - ok = th_delete(&th, "bb", strlen("bb")); - munit_assert_true(ok); - ok = th_delete(&th, "b", strlen("b")); - munit_assert_true(ok); - ok = th_delete(&th, "bbb", strlen("bbb")); - munit_assert_true(ok); - - value = th_get(&th, "a", strlen("a")); - munit_assert_null(value); +MunitResult test_th_delete(const MunitParameter params[], void *data) { + th_any_t value; + bool ok; - // Delete everything - for (int i = 0; i < keys_length; i++) { - th_delete(&th, keys[i], strlen(keys[i])); + const char *method_str = munit_parameters_get(params, "method"); + th_method_t method = str_to_method(method_str); + th_t th = th_create(method); - value = th_get(&th, keys[i], strlen(keys[i])); - munit_assert_null(value); - } + char *keys[] = {"a", "b", "bb", "bb", "bbb", "c", "ello"}; + + size_t keys_length = sizeof(keys) / sizeof(keys[0]); + + // Insert key value pair + for (int i = 0; i < keys_length; i++) { + th_put(&th, keys[i], strlen(keys[i]), (th_any_t)(uint64_t)i + 1); + } + + // Check everything exists + for (int i = 0; i < keys_length; i++) { + value = th_get(&th, keys[i], strlen(keys[i])); + munit_assert_not_null(value); + } + + ok = th_delete(&th, "a", strlen("a")); + munit_assert_true(ok); + + ok = th_delete(&th, "a", strlen("a")); + munit_assert_false(ok); + ok = th_delete(&th, "ello", strlen("ello")); + munit_assert_true(ok); + ok = th_delete(&th, "bb", strlen("bb")); + munit_assert_true(ok); + ok = th_delete(&th, "b", strlen("b")); + munit_assert_true(ok); + ok = th_delete(&th, "bbb", strlen("bbb")); + munit_assert_true(ok); + + value = th_get(&th, "a", strlen("a")); + munit_assert_null(value); + + // Delete everything + for (int i = 0; i < keys_length; i++) { + th_delete(&th, keys[i], strlen(keys[i])); + + value = th_get(&th, keys[i], strlen(keys[i])); + munit_assert_null(value); + } - th_free(&th); + th_free(&th); - return MUNIT_OK; + return MUNIT_OK; } diff --git a/tests/test_table.h b/tests/test_table.h index 3d8b8e0..856954f 100644 --- a/tests/test_table.h +++ b/tests/test_table.h @@ -3,12 +3,15 @@ #include "munit/munit.h" -MunitResult test_th_put_and_get(const MunitParameter params[], void* data); -MunitResult test_th_get_with_empty_table(const MunitParameter params[], void* data); -MunitResult test_th_put_with_full_table(const MunitParameter params[], void* data); -MunitResult test_th_put_overwrite(const MunitParameter params[], void* data); -MunitResult test_th_put_collision(const MunitParameter params[], void* data); -MunitResult test_th_put_struct_as_key(const MunitParameter params[], void* data); -MunitResult test_th_delete(const MunitParameter params[], void* data); +MunitResult test_th_put_and_get(const MunitParameter params[], void *data); +MunitResult test_th_get_with_empty_table(const MunitParameter params[], + void *data); +MunitResult test_th_put_with_full_table(const MunitParameter params[], + void *data); +MunitResult test_th_put_overwrite(const MunitParameter params[], void *data); +MunitResult test_th_put_collision(const MunitParameter params[], void *data); +MunitResult test_th_put_struct_as_key(const MunitParameter params[], + void *data); +MunitResult test_th_delete(const MunitParameter params[], void *data); #endif diff --git a/tests/tests.c b/tests/tests.c index 1b8ff41..1b7b06e 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -1,122 +1,44 @@ #include "munit/munit.h" - #include "test_hash.h" #include "test_table.h" -static char *th_methods[] = { - (char *) "separate_chaining", (char *) "open_adressing", NULL -}; +static char *th_methods[] = {(char *)"separate_chaining", + (char *)"open_adressing", NULL}; static MunitParameterEnum th_params[] = { - { "method", th_methods }, - { NULL, NULL }, + {"method", th_methods}, + {NULL, NULL}, }; static MunitTest test_th_suite_tests[] = { - { - "/th_hash_str", - test_th_hash, - NULL, - NULL, - MUNIT_TEST_OPTION_NONE, - NULL - }, - { - "/th_hash_str_multiple_iteration", - test_th_hash_multiple_iteration, - NULL, - NULL, - MUNIT_TEST_OPTION_NONE, - NULL - }, - { - "/th_hash_str_null", - test_th_hash_null, - NULL, - NULL, - MUNIT_TEST_OPTION_NONE, - NULL - }, - { - "/th_hash_str_with_int", - test_th_hash_with_int, - NULL, - NULL, - MUNIT_TEST_OPTION_NONE, - NULL - }, - { - "/th_put_and_get", - test_th_put_and_get, - NULL, - NULL, - MUNIT_TEST_OPTION_NONE, - th_params - }, - { - "/th_get_with_empty_table", - test_th_get_with_empty_table, - NULL, - NULL, - MUNIT_TEST_OPTION_NONE, - th_params - }, - { - "/th_put_with_full_table", - test_th_put_with_full_table, - NULL, - NULL, - MUNIT_TEST_OPTION_NONE, - th_params - }, - { - "/th_put_overwrite", - test_th_put_overwrite, - NULL, - NULL, - MUNIT_TEST_OPTION_NONE, - th_params - }, - { - "/th_put_collision", - test_th_put_collision, - NULL, - NULL, - MUNIT_TEST_OPTION_NONE, - th_params - }, - { - "/th_put_struct_as_key", - test_th_put_struct_as_key, - NULL, - NULL, - MUNIT_TEST_OPTION_NONE, - th_params - }, - { - "/th_delete", - test_th_delete, - NULL, - NULL, - MUNIT_TEST_OPTION_NONE, - th_params - }, - { NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL } -}; + {"/th_hash_str", test_th_hash, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL}, + {"/th_hash_str_multiple_iteration", test_th_hash_multiple_iteration, NULL, + NULL, MUNIT_TEST_OPTION_NONE, NULL}, + {"/th_hash_str_null", test_th_hash_null, NULL, NULL, MUNIT_TEST_OPTION_NONE, + NULL}, + {"/th_hash_str_with_int", test_th_hash_with_int, NULL, NULL, + MUNIT_TEST_OPTION_NONE, NULL}, + {"/th_put_and_get", test_th_put_and_get, NULL, NULL, MUNIT_TEST_OPTION_NONE, + th_params}, + {"/th_get_with_empty_table", test_th_get_with_empty_table, NULL, NULL, + MUNIT_TEST_OPTION_NONE, th_params}, + {"/th_put_with_full_table", test_th_put_with_full_table, NULL, NULL, + MUNIT_TEST_OPTION_NONE, th_params}, + {"/th_put_overwrite", test_th_put_overwrite, NULL, NULL, + MUNIT_TEST_OPTION_NONE, th_params}, + {"/th_put_collision", test_th_put_collision, NULL, NULL, + MUNIT_TEST_OPTION_NONE, th_params}, + {"/th_put_struct_as_key", test_th_put_struct_as_key, NULL, NULL, + MUNIT_TEST_OPTION_NONE, th_params}, + {"/th_delete", test_th_delete, NULL, NULL, MUNIT_TEST_OPTION_NONE, + th_params}, + {NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL}}; -static const MunitSuite test_th_suite = { - "tinyhash", - test_th_suite_tests, - NULL, - 0, +static const MunitSuite test_th_suite = {"tinyhash", test_th_suite_tests, NULL, + 0, - MUNIT_SUITE_OPTION_NONE -}; + MUNIT_SUITE_OPTION_NONE}; -int main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)]) -{ - return munit_suite_main( - &test_th_suite, - (void*) "", argc, argv - ); +int main(int argc, char *argv[MUNIT_ARRAY_PARAM(argc + 1)]) { + return munit_suite_main(&test_th_suite, (void *)"", argc, argv); }