Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
6b30396
adding set
BrandonMFong May 14, 2025
eb5f797
Saving work
BrandonMFong May 15, 2025
d6dcc4c
Accepting a 0 object
BrandonMFong May 15, 2025
d2597b2
set size
BrandonMFong May 15, 2025
3e38e1f
documenting
BrandonMFong May 15, 2025
6023785
init
BrandonMFong May 15, 2025
ad64023
incorporate flags
BrandonMFong May 15, 2025
2fc1038
making sure I initialize correctly
BrandonMFong May 16, 2025
c0d2cd5
testing to allow duplicates
BrandonMFong May 16, 2025
65bd4a7
init
BrandonMFong May 16, 2025
5eccdf3
setting up hashset
BrandonMFong May 16, 2025
bc7f7ca
Hash set tests
BrandonMFong May 16, 2025
5ead2d7
clean up
BrandonMFong May 16, 2025
0b7c35c
adding todo
BrandonMFong May 16, 2025
4e75e68
using compare functor
BrandonMFong May 17, 2025
99c9892
good functor for compare
BrandonMFong May 17, 2025
7de9afd
using - operator
BrandonMFong May 17, 2025
0b85ae8
cleaning up
BrandonMFong May 17, 2025
a2e94c1
update todo
BrandonMFong May 19, 2025
a740ad9
init allocator
BrandonMFong May 19, 2025
6fc2200
save work
BrandonMFong May 21, 2025
52f6306
making sure the object is released when duplicate is found
BrandonMFong May 21, 2025
7d2b0a8
updating todo
BrandonMFong May 21, 2025
eb292c1
update
BrandonMFong May 22, 2025
24de497
can work
BrandonMFong May 22, 2025
7ad1541
cleaning up
BrandonMFong May 22, 2025
4d3f48b
compare method
BrandonMFong May 22, 2025
b59fc07
changing freq
BrandonMFong May 22, 2025
165bae2
clean up
BrandonMFong May 23, 2025
a365d87
using compare
BrandonMFong May 23, 2025
0288970
good implementation
BrandonMFong May 27, 2025
63c88bd
cleaning up
BrandonMFong May 27, 2025
57bd667
moving allocator
BrandonMFong May 27, 2025
ed99ee9
init Set and HashSet
BrandonMFong May 27, 2025
7df64ec
update todo
BrandonMFong May 27, 2025
9301a2e
adding set tests
BrandonMFong May 27, 2025
65b23aa
update todo
BrandonMFong May 27, 2025
105f777
hashset tests
BrandonMFong May 27, 2025
f1314af
update
BrandonMFong May 27, 2025
9998386
clean up
BrandonMFong May 28, 2025
90f5091
adding remove pointer
BrandonMFong May 28, 2025
ede2d9c
clean up
BrandonMFong May 28, 2025
ac3ec59
update todo
BrandonMFong May 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ on:
push:
branches: [ "dev" ]
paths-ignore:
- '**.md'
- '*.md'
pull_request:
branches: [ "dev" ]
paths-ignore:
- '**.md'
- '*.md'

jobs:
unit-tests-linux:
Expand Down
2 changes: 1 addition & 1 deletion bflibc/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ filesystem coreutils stringutils \
bftime thread bfmath \
lock filewriter hash \
rand map tree internal/tree \
hashmap
hashmap set hashset

### Release settings
ifeq ($(CONFIG),release) # release
Expand Down
103 changes: 103 additions & 0 deletions bflibc/src/hashset.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/**
* author: brando
* date: 5/14/25
*/

#include "hashset.h"
#include "hashmap.h"
#include "free.h"

typedef struct _BFHashSet {
/**
* we will use a hash map with this schema:
* <key>:<value> -> <hash set value>:<hash set object>
*/
BFHashMap map;

void (*release)(BFHashSetValue value);
} _BFHashSet;

/**
* value: hashset object
* key: hashset value
*/
void _BFHashSetReleaseHashMap(BFHashSetValue value, BFHashSet _set) {
_BFHashSet * set = (_BFHashSet *) _set;
if (!set && !set->release) return;

set->release(value);
}

BFHashSet BFHashSetCreate() {
_BFHashSet * res = (_BFHashSet *) malloc(sizeof(_BFHashSet));
if (!res) return NULL;

res->release = NULL;

res->map = BFHashMapCreate();
if (!res->map) {
return NULL;
}

BFHashMapSetRelease(res->map, _BFHashSetReleaseHashMap);

return (BFHashSet) res;
}

void BFHashSetSetCompare(BFHashSet _set, int (*compare)(BFHashSetValue a, BFHashSetValue b)) {
_BFHashSet * set = (_BFHashSet *) _set;
if (!set) return;

BFHashMapSetCompare(set->map, compare);
}

void BFHashSetSetHashFunction(BFHashSet _set, unsigned long (*hash)(BFHashSetValue value)) {
_BFHashSet * set = (_BFHashSet *) _set;
if (!set) return;

BFHashMapSetHashFunction(set->map, hash);
}

void BFHashSetSetRelease(BFHashSet _set, void (*release)(BFHashSetValue value)) {
_BFHashSet * set = (_BFHashSet *) _set;
if (!set) return;

set->release = release;
}

void BFHashSetRelease(BFHashSet _set) {
_BFHashSet * set = (_BFHashSet *) _set;
if (!set) return;

BFHashMapRelease(set->map);
BFFree(set);
}

int BFHashSetInsert(BFHashSet _set, BFHashSetValue value) {
_BFHashSet * set = (_BFHashSet *) _set;
if (!set) return -1;

return BFHashMapInsert(set->map, value, set);
}

int BFHashSetRemove(BFHashSet _set, BFHashSetValue value) {
_BFHashSet * set = (_BFHashSet *) _set;
if (!set) return -1;

return BFHashMapRemove(set->map, value);
}

bool BFHashSetContains(BFHashSet _set, BFHashSetValue value) {
_BFHashSet * set = (_BFHashSet *) _set;
if (!set) return false;

return BFHashMapContains(set->map, value);
}

size_t BFHashSetGetSize(BFHashSet _set) {
_BFHashSet * set = (_BFHashSet *) _set;
if (!set) return 0;

return BFHashMapGetSize(set->map);
}

63 changes: 63 additions & 0 deletions bflibc/src/hashset.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* author: brando
* date: 5/14/25
*/

#ifndef HASHSET_H
#define HASHSET_H

#include <stdbool.h>
#include <stddef.h>

typedef void * BFHashSet;
typedef void * BFHashSetValue;

/**
* creates set
*
* caller owns memory
*/
BFHashSet BFHashSetCreate();

/**
* sets how the values are compared to one another
*/
void BFHashSetSetCompare(BFHashSet set, int (*compare)(BFHashSetValue a, BFHashSetValue b));

/**
* how each value memory is handled once set is released
*/
void BFHashSetSetRelease(BFHashSet set, void (*release)(BFHashSetValue value));

/**
* sets the hash function
*/
void BFHashSetSetHashFunction(BFHashSet set, unsigned long (*hash)(BFHashSetValue key));

/**
* releases set from memory
*/
void BFHashSetRelease(BFHashSet set);

/**
* inserts value into set
*/
int BFHashSetInsert(BFHashSet set, BFHashSetValue value);

/**
* removes value from set
*/
int BFHashSetRemove(BFHashSet set, BFHashSetValue value);

/**
* checks if value is in set
*/
bool BFHashSetContains(BFHashSet set, BFHashSetValue value);

/**
* returns the current size of set
*/
size_t BFHashSetGetSize(BFHashSet set);

#endif // HASHSET_H

48 changes: 35 additions & 13 deletions bflibc/src/internal/tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ _BFTreeNode * _BFTreeNodeCreate() {
res->right = NULL;
res->object = NULL;
res->height = 1;
res->count = 0;
return res;
}

Expand Down Expand Up @@ -87,6 +88,8 @@ _BFTreeNode * _BFTreeNodeInsert(
_BFTreeNode * node,
BFTreeObject object,
int (*compare)(BFTreeObject a, BFTreeObject b),
void (*release)(BFTreeObject object),
unsigned char flags,
int * error
) {
// 1. Perform the normal BST insertion
Expand All @@ -96,16 +99,24 @@ _BFTreeNode * _BFTreeNodeInsert(
return node;
}

if (compare(object, node->object) < 0) {
int cmpval = compare(object, node->object);
if (cmpval < 0) {
node->left = _BFTreeNodeInsert(
node->left, object, compare, error
node->left, object, compare, release, flags, error
);
} else if (compare(object, node->object) > 0) {
} else if (cmpval > 0) {
node->right = _BFTreeNodeInsert(
node->right, object, compare, error
node->right, object, compare, release, flags, error
);
} else { // Equal keys are not allowed in BST
if (error) *error = -1;
if ((flags & (0x01 << _BFTREE_FLAG_ALLOW_DUPLICATES)) != 0) {
node->count++;
if (release) {
release(object);
}
} else {
if (error) *error = -11;
}
return node;
}

Expand Down Expand Up @@ -170,7 +181,8 @@ _BFTreeNode * _BFTreeNodeRemove(
_BFTreeNode * root,
BFTreeObject object,
int (*compare)(BFTreeObject a, BFTreeObject b),
void (*release)(BFTreeObject object)
void (*release)(BFTreeObject object),
unsigned char flags
) {
// STEP 1: PERFORM STANDARD BST DELETE

Expand All @@ -180,19 +192,29 @@ _BFTreeNode * _BFTreeNodeRemove(

// If the key to be deleted is smaller than the
// root's key, then it lies in left subtree
if (compare(object, root->object) < 0) {
int cmpval = compare(object, root->object);
if (cmpval < 0) {
root->left = _BFTreeNodeRemove(
root->left, object, compare, release
root->left, object, compare, release, flags
);
// If the key to be deleted is greater than the
// root's key, then it lies in right subtree
} else if (compare(object, root->object) > 0) {
} else if (cmpval > 0) {
root->right = _BFTreeNodeRemove(
root->right, object, compare, release
root->right, object, compare, release, flags
);
// if key is same as root's key, then This is
// the node to be deleted
//
// unless duplicates are allowed
} else {
if (flags & (0x01 << _BFTREE_FLAG_ALLOW_DUPLICATES)) {
if (root->count > 0) {
root->count--;
return root;
}
}

// node with only one child or no child
if (root->left == NULL || root->right == NULL) {
_BFTreeNode * temp = root->left ? root->left : root->right;
Expand Down Expand Up @@ -223,7 +245,7 @@ _BFTreeNode * _BFTreeNodeRemove(

// Delete the inorder successor
root->right = _BFTreeNodeRemove(
root->right, temp->object, compare, NULL
root->right, temp->object, compare, NULL, flags
);
}
}
Expand Down Expand Up @@ -275,8 +297,8 @@ bool _BFTreeNodeSearch(
) {
if (!node) {
return false;
} else if (!obj) {
return false;
//} else if (!obj) {
// return false;
}

int comp = compare(obj, node->object);
Expand Down
28 changes: 27 additions & 1 deletion bflibc/src/internal/tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ typedef struct _BFTreeNode {
struct _BFTreeNode * right;
size_t height;
BFTreeObject object;

/**
* IIF duplicates are allowed this will hold the count of
* instances of object in the tree
*/
size_t count;
} _BFTreeNode;

_BFTreeNode * _BFTreeNodeCreate();
Expand All @@ -35,29 +41,49 @@ typedef struct _BFTree {
* BFTreeRelease() is called
*/
void (*release)(BFTreeObject object);

/**
* |x|x|x|x|x|x|x|<allow duplicates>|
*
* <allow duplicates>: default value == 0. 0: not allow. 1: allow
*/
unsigned char flags;
} _BFTree;

#define _BFTREE_FLAG_ALLOW_DUPLICATES 0

/**
* error: will nonzero if object couldn't be inserted.
* one reason is there may be a duplicate
*
* object: pointer or integer value. value=0 is allowed. If this tree
* is allowed to have duplicates, any duplicates found will be counted
* and released using its release callback

* flags: _BFTree::flags
*
* returns node
*/
_BFTreeNode * _BFTreeNodeInsert(
_BFTreeNode * node,
BFTreeObject object,
int (*compare)(BFTreeObject a, BFTreeObject b),
void (*release)(BFTreeObject object),
unsigned char flags,
int * error
);

/**
* flags: _BFTree::flags
*
* returns node
*/
_BFTreeNode * _BFTreeNodeRemove(
_BFTreeNode * node,
BFTreeObject object,
int (*compare)(BFTreeObject a, BFTreeObject b),
void (*release)(BFTreeObject object)
void (*release)(BFTreeObject object),
unsigned char flags
);

/**
Expand Down
Loading
Loading