gb_sets(3erl)

✨ gb_sets β€” like, ordered sets but make it balanced πŸ’…

okay so this is the gb_sets module from Erlang's stdlib, and bestie, it's the ordered set module. Yes it's a manual page, no it's not boring, stay with me 🫢


🌸 NAME 🌸

gb_sets β€” sets represented by general balanced trees. That's it, that's the vibe 🌳✨


πŸ’– DESCRIPTION πŸ’–

so this module gives you ordered sets using Prof. Arne Andersson's General Balanced Trees. For larger sets, ordered sets can be so much more efficient than ordered lists β€” but ngl, it depends on the application. it's giving "situationship with your use case" 😭

the data representing a set is to be regarded as opaque by other modules. in abstract terms the representation is a composite type of existing Erlang terms β€” see the note on data types. any code that assumes knowledge of the format is running on thin ice, and not in a cute way πŸ’€

this module considers two elements as different if and only if they do not compare equal (==). periodt.


πŸ”₯ COMPLEXITY NOTE πŸ”₯

the complexity on set operations is bounded by either O(|S|) or O(|T| * log(|S|)), where S is the largest given set β€” whichever is fastest for any particular function call, iykyk.

for operating on sets of almost equal size, this implementation is about 3 times slower than using ordered-list sets directly πŸ™ˆ

for sets of very different sizes though? this solution can be arbitrarily much faster β€” in practical cases, often 10-100 times πŸ”₯ not me being dramatic, the manpage said it.

this implementation is particularly suited for accumulating elements a few at a time, building up a large set (> 100-200 elements), and repeatedly testing for membership in the current set. main character energy fr fr πŸ‘‘

and as with normal tree structures, lookup (membership testing), insertion, and deletion have logarithmic complexity. slay.


πŸŽ€ COMPATIBILITY πŸŽ€

the following functions also exist in the sets(3erl) and ordsets(3erl) modules and provide the same functionality. so by only changing the module name for each call, you can try out different set representations β€” like trying on outfits but for data structures πŸ’…

  • add_element/2
  • del_element/2
  • filter/2
  • fold/3
  • from_list/1
  • intersection/1
  • intersection/2
  • is_element/2
  • is_empty/1
  • is_set/1
  • is_subset/2
  • new/0
  • size/1
  • subtract/2
  • to_list/1
  • union/1
  • union/2

πŸ¦‹ DATA TYPES πŸ¦‹

set(Element)

a general balanced set. that's the whole description, she's mysterious πŸ’œ

set() = set(term())

yep, that's the type alias. iconic.

iter(Element)

a general balanced set iterator 🧚

iter() = iter(term())

the alias. again. we love consistency ✨


🌈 EXPORTS 🌈

add(Element, Set1) -> Set2

add_element(Element, Set1) -> Set2

Types:

Set1 = Set2 = set(Element)

returns a new set formed from Set1 with Element inserted. if Element is already an element in Set1, nothing is changed β€” no double dipping, she's not like that πŸ™…


balance(Set1) -> Set2

Types:

Set1 = Set2 = set(Element)

rebalances the tree representation of Set1. okay so this is rarely necessary β€” but it can be motivated when a large number of elements have been deleted from the tree without further insertions. rebalancing can then be forced to minimise lookup times, because deletion does not rebalance the tree. it's giving "self-care for your tree" 🌸


del_element(Element, Set1) -> Set2

Types:

Set1 = Set2 = set(Element)

returns a new set formed from Set1 with Element removed. if Element is not an element in Set1, nothing is changed. no drama, no error πŸ’…


delete(Element, Set1) -> Set2

Types:

Set1 = Set2 = set(Element)

returns a new set formed from Set1 with Element removed. assumes that Element is present in Set1 β€” so like, don't be messy about it ⚠️


delete_any(Element, Set1) -> Set2

Types:

Set1 = Set2 = set(Element)

returns a new set formed from Set1 with Element removed. if Element is not an element in Set1, nothing is changed. the chill version of delete, honestly 🫢


difference(Set1, Set2) -> Set3

Types:

Set1 = Set2 = Set3 = set(Element)

returns only the elements of Set1 that are not also elements of Set2. it's the "we're not mutuals anymore" of set operations ✨


empty() -> Set

Types:

Set = set()

returns a new empty set. blank slate, fresh start, main character era πŸŽ€


filter(Pred, Set1) -> Set2

Types:

Pred = fun((Element) -> boolean())
Set1 = Set2 = set(Element)

filters elements in Set1 using predicate function Pred. only the ones that pass the vibe check stay 🌈


fold(Function, Acc0, Set) -> Acc1

Types:

Function = fun((Element, AccIn) -> AccOut)
Acc0 = Acc1 = AccIn = AccOut = Acc
Set = set(Element)

folds Function over every element in Set, returning the final value of the accumulator. it's literally reduce but the Erlang girlies call it fold πŸ’œ


from_list(List) -> Set

Types:

List = [Element]
Set = set(Element)

returns a set of the elements in List, where List can be unordered and contain duplicates. chaotic input, tidy output β€” we love a glow-up 😌


from_ordset(List) -> Set

Types:

List = [Element]
Set = set(Element)

turns an ordered-set list List into a set. the list must not contain duplicates β€” read it and weep, no dupes allowed ⚠️


insert(Element, Set1) -> Set2

Types:

Set1 = Set2 = set(Element)

returns a new set formed from Set1 with Element inserted. assumes that Element is not present in Set1 β€” like, it's trusting you on this one πŸ™ˆ


intersection(SetList) -> Set

Types:

SetList = [set(Element), ...]
Set = set(Element)

returns the intersection of the non-empty list of sets. shared vibes only πŸ’…


intersection(Set1, Set2) -> Set3

Types:

Set1 = Set2 = Set3 = set(Element)

returns the intersection of Set1 and Set2. the two-set version, for when you're not doing the whole list thing 🫢


is_disjoint(Set1, Set2) -> boolean()

Types:

Set1 = Set2 = set(Element)

returns true if Set1 and Set2 are disjoint (have no elements in common), otherwise false. they don't know each other, they've never met, no mutuals 🌸


is_element(Element, Set) -> boolean()

Types:

Set = set(Element)

returns true if Element is an element of Set, otherwise false. the membership test, the classic ✨


is_empty(Set) -> boolean()

Types:

Set = set()

returns true if Set is an empty set, otherwise false. vibe check on the emptiness πŸ’€


is_member(Element, Set) -> boolean()

Types:

Set = set(Element)

returns true if Element is an element of Set, otherwise false. yes bestie it's the same description as is_element β€” they're twins, let them live πŸ‘―


is_set(Term) -> boolean()

Types:

Term = term()

returns true if Term appears to be a set, otherwise false. heads up 🚨 this function will return true for any term that coincides with the representation of a gb_set while not really being a gb_set, so it might return false positive results. see also note on data types. it's giving "looks like a set, might not be a set" πŸ™ˆ


is_subset(Set1, Set2) -> boolean()

Types:

Set1 = Set2 = set(Element)

returns true when every element of Set1 is also a member of Set2, otherwise false. Set1 is in Set2's orbit πŸͺ


iterator(Set) -> Iter

Types:

Set = set(Element)
Iter = iter(Element)

returns an iterator that can be used for traversing the entries of Set; see next/1. the implementation is very efficient β€” traversing the whole set using next/1 is only slightly slower than getting the list of all elements using to_list/1 and traversing that. the main advantage of the iterator approach is that it does not require the complete list of all elements to be built in memory at one time. memory-conscious queen πŸ‘‘


iterator_from(Element, Set) -> Iter

Types:

Set = set(Element)
Iter = iter(Element)

returns an iterator that can be used for traversing the entries of Set; see next/1. the difference as compared to the iterator returned by iterator/1 is that the first element greater than or equal to Element is returned. start where you want, honestly πŸ’œ


largest(Set) -> Element

Types:

Set = set(Element)

returns the largest element in Set. assumes that Set is not empty β€” don't come at her with an empty set bestie 😭


new() -> Set

Types:

Set = set()

returns a new empty set. basically empty/0's twin, and yes both exist πŸ’…


next(Iter1) -> {Element, Iter2} | none

Types:

Iter1 = Iter2 = iter(Element)

returns {Element, Iter2}, where Element is the smallest element referred to by iterator Iter1, and Iter2 is the new iterator to be used for traversing the remaining elements β€” or the atom none if no elements remain. none is the "we're done here" of iterators πŸŒ™


singleton(Element) -> set(Element)

returns a set containing only element Element. one single element, living her best solo life πŸŽ€


size(Set) -> integer() >= 0

Types:

Set = set()

returns the number of elements in Set. the headcount, the census, the roll call πŸ’…


smallest(Set) -> Element

Types:

Set = set(Element)

returns the smallest element in Set. assumes that Set is not empty β€” again with the empty set warning, respect it ⚠️


subtract(Set1, Set2) -> Set3

Types:

Set1 = Set2 = Set3 = set(Element)

returns only the elements of Set1 that are not also elements of Set2. lowkey the same as difference/2, and honestly? we respect the consistency 🫢


take_largest(Set1) -> {Element, Set2}

Types:

Set1 = Set2 = set(Element)

returns {Element, Set2}, where Element is the largest element in Set1, and Set2 is this set with Element deleted. assumes that Set1 is not empty. grab the big one and yeet it ✨


take_smallest(Set1) -> {Element, Set2}

Types:

Set1 = Set2 = set(Element)

returns {Element, Set2}, where Element is the smallest element in Set1, and Set2 is this set with Element deleted. assumes that Set1 is not empty. the tiny one this time 🐣


to_list(Set) -> List

Types:

Set = set(Element)
List = [Element]

returns the elements of Set as a list. converting back to list-core, no judgement 🌸


union(SetList) -> Set

Types:

SetList = [set(Element), ...]
Set = set(Element)

returns the merged (union) set of the list of sets. everyone's invited to the group chat πŸ’Œ


union(Set1, Set2) -> Set3

Types:

Set1 = Set2 = Set3 = set(Element)

returns the merged (union) set of Set1 and Set2. just the two of them, a duo 🫢


🌟 SEE ALSO 🌟

gb_trees(3erl), ordsets(3erl), sets(3erl) β€” go read those too bestie, they're literally in the same friend group πŸ’–


and that's the whole page!! brought to you by Ericsson AB, stdlib 4.3.1.3 β€” mwah, go build something iconic πŸ’…βœ¨πŸŽ€

πŸ“¦ where this page comes from