addons/isl/src/dag/set.tsblame
View source
b69ab311/**
b69ab312 * Copyright (c) Meta Platforms, Inc. and affiliates.
b69ab313 *
b69ab314 * This source code is licensed under the MIT license found in the
b69ab315 * LICENSE file in the root directory of this source tree.
b69ab316 */
b69ab317
b69ab318import type {List, Seq} from 'immutable';
b69ab319import type {Hash} from '../types';
b69ab3110
b69ab3111import {OrderedSet as ImSet} from 'immutable';
b69ab3112import {SelfUpdate} from 'shared/immutableExt';
b69ab3113
b69ab3114/**
b69ab3115 * Set of commit hashes, with extra methods.
b69ab3116 * Internally maintains the order of the hashes information.
b69ab3117 */
b69ab3118export class HashSet extends SelfUpdate<ImSet<Hash>> {
b69ab3119 constructor(set?: ImSet<Hash>) {
b69ab3120 super(set ?? ImSet());
b69ab3121 }
b69ab3122
b69ab3123 static fromHashes(hashes: SetLike): HashSet {
b69ab3124 if (hashes == null) {
b69ab3125 return new HashSet(ImSet());
b69ab3126 } else if (hashes instanceof HashSet) {
b69ab3127 return hashes;
b69ab3128 } else if (typeof hashes === 'string') {
b69ab3129 return new HashSet(ImSet([hashes]));
b69ab3130 } else if (ImSet.isOrderedSet(hashes)) {
b69ab3131 return new HashSet(hashes as ImSet<Hash>);
b69ab3132 } else {
b69ab3133 return new HashSet(ImSet(hashes));
b69ab3134 }
b69ab3135 }
b69ab3136
b69ab3137 toHashes(): ImSet<Hash> {
b69ab3138 return this.set;
b69ab3139 }
b69ab3140
b69ab3141 toSeq(): Seq.Set<Hash> {
b69ab3142 return this.set.toSeq();
b69ab3143 }
b69ab3144
b69ab3145 toList(): List<Hash> {
b69ab3146 return this.set.toList();
b69ab3147 }
b69ab3148
b69ab3149 toArray(): Array<Hash> {
b69ab3150 return this.set.toArray();
b69ab3151 }
b69ab3152
b69ab3153 /** Union with another set. Preserves the order: this, then other without the overlapping subset. */
b69ab3154 union(other: SetLike): HashSet {
b69ab3155 const set = this.set.union(HashSet.fromHashes(other).set);
b69ab3156 return new HashSet(set);
b69ab3157 }
b69ab3158
b69ab3159 /** Interset with another set. Preserves the order of `this` set. */
b69ab3160 intersect(other: SetLike): HashSet {
b69ab3161 const set = this.set.intersect(HashSet.fromHashes(other).set);
b69ab3162 return new HashSet(set);
b69ab3163 }
b69ab3164
b69ab3165 /** Remove items that exist in another set. Preserves the order of the `this` set. */
b69ab3166 subtract(other: SetLike): HashSet {
b69ab3167 const set = this.set.subtract(HashSet.fromHashes(other).set);
b69ab3168 return new HashSet(set);
b69ab3169 }
b69ab3170
b69ab3171 /** Test if this set contains the given hash. */
b69ab3172 contains(hash: Hash): boolean {
b69ab3173 return this.set.has(hash);
b69ab3174 }
b69ab3175
b69ab3176 /** Reverse the order of the set. */
b69ab3177 reverse(): HashSet {
b69ab3178 return new HashSet(this.inner.reverse());
b69ab3179 }
b69ab3180
b69ab3181 /** Convert to sorted array. Mainly for testing. */
b69ab3182 toSortedArray(): Array<Hash> {
b69ab3183 return this.set.toArray().sort();
b69ab3184 }
b69ab3185
b69ab3186 [Symbol.iterator](): IterableIterator<Hash> {
b69ab3187 return this.set[Symbol.iterator]();
b69ab3188 }
b69ab3189
b69ab3190 get size(): number {
b69ab3191 return this.set.size;
b69ab3192 }
b69ab3193
b69ab3194 private get set(): ImSet<Hash> {
b69ab3195 return this.inner;
b69ab3196 }
b69ab3197}
b69ab3198
b69ab3199export function arrayFromHashes(hashes: SetLike): Array<Hash> {
b69ab31100 if (hashes == null) {
b69ab31101 return [];
b69ab31102 } else if (hashes instanceof HashSet) {
b69ab31103 return hashes.toArray();
b69ab31104 } else if (typeof hashes === 'string') {
b69ab31105 return [hashes];
b69ab31106 } else {
b69ab31107 return [...hashes];
b69ab31108 }
b69ab31109}
b69ab31110
b69ab31111/** A convenient type that converts to HashSet. `null` converts to an empty set. */
b69ab31112export type SetLike = HashSet | ImSet<Hash> | Iterable<Hash> | Hash | null | undefined;