diff --git a/src/collection/_impl/_hashset_add_impl.scad b/src/collection/_impl/_hashset_add_impl.scad new file mode 100644 index 00000000..0cfa822d --- /dev/null +++ b/src/collection/_impl/_hashset_add_impl.scad @@ -0,0 +1,15 @@ +use <../../util/slice.scad>; +use <../../util/some.scad>; + +function _hashset_add(set, elem, eq, hash) = + let( + idx = hash(elem) % len(set), + bucket = set[idx] + ) + len(bucket) == 0 ? concat(slice(set, 0, idx), [[elem]], slice(set, idx + 1)) : + some(bucket, function(e) eq(e, elem)) ? set : + concat( + slice(set, 0, idx), + [concat(bucket, [elem])], + slice(set, idx + 1) + ); \ No newline at end of file diff --git a/src/collection/_impl/_hashset_impl.scad b/src/collection/_impl/_hashset_impl.scad index 0e8c6d04..625b70bd 100644 --- a/src/collection/_impl/_hashset_impl.scad +++ b/src/collection/_impl/_hashset_impl.scad @@ -1,23 +1,5 @@ -use <../../util/slice.scad>; -use <../../util/some.scad>; - -function _hashset_add(set, elem, eq, hash) = - let( - idx = hash(elem) % len(set), - bucket = set[idx] - ) - len(bucket) == 0 ? concat(slice(set, 0, idx), [[elem]], slice(set, idx + 1)) : - some(bucket, function(e) eq(e, elem)) ? set : - concat( - slice(set, 0, idx), - [concat(bucket, [elem])], - slice(set, idx + 1) - ); +use <_hashset_add_impl.scad>; function _hashset(elems, leng, buckets, eq, hash, i = 0) = i == leng ? buckets : - _hashset(elems, leng, _hashset_add(buckets, elems[i], eq, hash), eq, hash, i + 1); - -function _find(lt, elem, eq, leng, i = 0) = - i == leng ? -1 : - eq(lt[i], elem) ? i : _find(lt, elem, eq, leng, i + 1); \ No newline at end of file + _hashset(elems, leng, _hashset_add(buckets, elems[i], eq, hash), eq, hash, i + 1); \ No newline at end of file diff --git a/src/collection/hashset.scad b/src/collection/hashset.scad index f4a4ccc5..47c08575 100644 --- a/src/collection/hashset.scad +++ b/src/collection/hashset.scad @@ -1,14 +1,8 @@ use <__comm__/_str_hash.scad>; use <_impl/_hashset_impl.scad>; -use <../util/slice.scad>; -use <../util/some.scad>; - -// public functions: hashset, hashset_has, hashset_add, hashset_del, hashset_list - -df_hash = function(e) _str_hash(e); -df_eq = function(e1, e2) e1 == e2; +use <_impl/_hashset_add_impl.scad>; -function hashset(lt, eq = df_eq, hash = df_hash, bucket_numbers) = +function hashset(lt, eq = function(e1, e2) e1 == e2, hash = function(e) _str_hash(e), bucket_numbers) = let( lt_undef = is_undef(lt), bucket_numbers_undef = is_undef(bucket_numbers), @@ -16,25 +10,4 @@ function hashset(lt, eq = df_eq, hash = df_hash, bucket_numbers) = (lt_undef ? 16 : len(lt)) : bucket_numbers, buckets = [for(i = [0:b_numbers - 1]) []] ) - lt_undef ? buckets : _hashset(lt, len(lt), buckets, eq, hash); - -function hashset_has(set, elem, eq = df_eq, hash = df_hash) = - some(set[hash(elem) % len(set)], function(e) eq(e, elem)); - -function hashset_add(set, elem, eq = df_eq, hash = df_hash) = - _hashset_add(set, elem, eq, hash); - -function hashset_del(set, elem, eq = df_eq, hash = df_hash) = - let( - bidx = hash(elem) % len(set), - bucket = set[bidx], - leng = len(bucket) - ) - leng == 0 ? set : - let(i = _find(bucket, elem, eq, leng)) - i == -1 ? set : - concat( - slice(set, 0, bidx), - [concat(slice(bucket, 0, i), slice(bucket, i + 1))], - slice(set, bidx + 1) - ); \ No newline at end of file + lt_undef ? buckets : _hashset(lt, len(lt), buckets, eq, hash); \ No newline at end of file diff --git a/src/collection/hashset_add.scad b/src/collection/hashset_add.scad new file mode 100644 index 00000000..8897b8ae --- /dev/null +++ b/src/collection/hashset_add.scad @@ -0,0 +1,5 @@ +use <__comm__/_str_hash.scad>; +use <_impl/_hashset_add_impl.scad>; + +function hashset_add(set, elem, eq = function(e1, e2) e1 == e2, hash = function(e) _str_hash(e)) = + _hashset_add(set, elem, eq, hash); \ No newline at end of file diff --git a/src/collection/hashset_del.scad b/src/collection/hashset_del.scad new file mode 100644 index 00000000..0ee22c8c --- /dev/null +++ b/src/collection/hashset_del.scad @@ -0,0 +1,21 @@ +use <__comm__/_str_hash.scad>; +use <../util/slice.scad>; + +function _find(lt, elem, eq, leng, i = 0) = + i == leng ? -1 : + eq(lt[i], elem) ? i : _find(lt, elem, eq, leng, i + 1); + +function hashset_del(set, elem, eq = function(e1, e2) e1 == e2, hash = function(e) _str_hash(e)) = + let( + bidx = hash(elem) % len(set), + bucket = set[bidx], + leng = len(bucket) + ) + leng == 0 ? set : + let(i = _find(bucket, elem, eq, leng)) + i == -1 ? set : + concat( + slice(set, 0, bidx), + [concat(slice(bucket, 0, i), slice(bucket, i + 1))], + slice(set, bidx + 1) + ); \ No newline at end of file diff --git a/src/collection/hashset_has.scad b/src/collection/hashset_has.scad new file mode 100644 index 00000000..13b0bc16 --- /dev/null +++ b/src/collection/hashset_has.scad @@ -0,0 +1,5 @@ +use <__comm__/_str_hash.scad>; +use <../util/some.scad>; + +function hashset_has(set, elem, eq = function(e1, e2) e1 == e2, hash = function(e) _str_hash(e)) = + some(set[hash(elem) % len(set)], function(e) eq(e, elem)); \ No newline at end of file diff --git a/test/collection/test_hashset.scad b/test/collection/test_hashset.scad index d0fd5b1e..0bc076b1 100644 --- a/test/collection/test_hashset.scad +++ b/test/collection/test_hashset.scad @@ -1,6 +1,9 @@ use ; use ; use ; +use ; +use ; +use ; module test_hashset() { echo("==== test_hashset ====");