14d6c458bSopenharmony_ci/*
24d6c458bSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
34d6c458bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44d6c458bSopenharmony_ci * you may not use this file except in compliance with the License.
54d6c458bSopenharmony_ci * You may obtain a copy of the License at
64d6c458bSopenharmony_ci *
74d6c458bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84d6c458bSopenharmony_ci *
94d6c458bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104d6c458bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114d6c458bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124d6c458bSopenharmony_ci * See the License for the specific language governing permissions and
134d6c458bSopenharmony_ci * limitations under the License.
144d6c458bSopenharmony_ci */
154d6c458bSopenharmony_cideclare function requireNapi(s: string): any;
164d6c458bSopenharmony_ciinterface ArkPrivate {
174d6c458bSopenharmony_ci  LightWeightSet: number;
184d6c458bSopenharmony_ci  Load(key: number): Object;
194d6c458bSopenharmony_ci}
204d6c458bSopenharmony_cilet flag: boolean = false;
214d6c458bSopenharmony_cilet fastLightWeightSet: Object = undefined;
224d6c458bSopenharmony_cilet arkPritvate: ArkPrivate = globalThis.ArkPrivate || undefined;
234d6c458bSopenharmony_ciif (arkPritvate !== undefined) {
244d6c458bSopenharmony_ci  fastLightWeightSet = arkPritvate.Load(arkPritvate.LightWeightSet);
254d6c458bSopenharmony_ci} else {
264d6c458bSopenharmony_ci  flag = true;
274d6c458bSopenharmony_ci}
284d6c458bSopenharmony_ciif (flag || fastLightWeightSet === undefined) {
294d6c458bSopenharmony_ci  const lightWeightAbility = requireNapi('util.struct');
304d6c458bSopenharmony_ci  const errorUtil = lightWeightAbility.errorUtil;
314d6c458bSopenharmony_ci  interface IterableIterator<T> {
324d6c458bSopenharmony_ci    next: () => {
334d6c458bSopenharmony_ci      value: T | undefined;
344d6c458bSopenharmony_ci      done: boolean;
354d6c458bSopenharmony_ci    };
364d6c458bSopenharmony_ci  }
374d6c458bSopenharmony_ci  class HandlerLightWeightSet<T> {
384d6c458bSopenharmony_ci    set(target: LightWeightSet<T>, p: string, value: string): boolean {
394d6c458bSopenharmony_ci      if (p in target) {
404d6c458bSopenharmony_ci        target[p] = value;
414d6c458bSopenharmony_ci        return true;
424d6c458bSopenharmony_ci      }
434d6c458bSopenharmony_ci      return false;
444d6c458bSopenharmony_ci    }
454d6c458bSopenharmony_ci    defineProperty(): boolean {
464d6c458bSopenharmony_ci      throw new Error(`Can't define Property on LightWeightSet Object`);
474d6c458bSopenharmony_ci    }
484d6c458bSopenharmony_ci    deleteProperty(): boolean {
494d6c458bSopenharmony_ci      throw new Error(`Can't delete Property on LightWeightSet Object`);
504d6c458bSopenharmony_ci    }
514d6c458bSopenharmony_ci    setPrototypeOf(): boolean {
524d6c458bSopenharmony_ci      throw new Error(`Can't set Prototype on LightWeightSet Object`);
534d6c458bSopenharmony_ci    }
544d6c458bSopenharmony_ci  }
554d6c458bSopenharmony_ci  class LightWeightSet<T> extends lightWeightAbility.LightWeightClass<T, T> {
564d6c458bSopenharmony_ci    constructor() {
574d6c458bSopenharmony_ci      errorUtil.checkNewTargetIsNullError('LightWeightSet', !new.target);
584d6c458bSopenharmony_ci      super();
594d6c458bSopenharmony_ci      return new Proxy(this, new HandlerLightWeightSet());
604d6c458bSopenharmony_ci    }
614d6c458bSopenharmony_ci    get length(): number {
624d6c458bSopenharmony_ci      return this.memberNumber;
634d6c458bSopenharmony_ci    }
644d6c458bSopenharmony_ci    add(obj: T): boolean {
654d6c458bSopenharmony_ci      errorUtil.checkBindError('add', LightWeightSet, this);
664d6c458bSopenharmony_ci      if (this.members.keys.indexOf(obj) > 0) {
674d6c458bSopenharmony_ci        return false;
684d6c458bSopenharmony_ci      }
694d6c458bSopenharmony_ci      this.addmember(obj);
704d6c458bSopenharmony_ci      return true;
714d6c458bSopenharmony_ci    }
724d6c458bSopenharmony_ci    addAll(set: LightWeightSet<T>): boolean {
734d6c458bSopenharmony_ci      errorUtil.checkBindError('addAll', LightWeightSet, this);
744d6c458bSopenharmony_ci      errorUtil.checkTypeError('set', 'LightWeightSet', set);
754d6c458bSopenharmony_ci      if (!(set instanceof LightWeightSet)) {
764d6c458bSopenharmony_ci        throw new TypeError('Incoming object is not JSAPILightWeightSet');
774d6c458bSopenharmony_ci      }
784d6c458bSopenharmony_ci      let change: boolean = false;
794d6c458bSopenharmony_ci      if (set.memberNumber === 0) {
804d6c458bSopenharmony_ci        change = false;
814d6c458bSopenharmony_ci      } else {
824d6c458bSopenharmony_ci        for (let i: number = 0; i < set.memberNumber; i++) {
834d6c458bSopenharmony_ci          change = this.add(set.members.keys[i]) || change;
844d6c458bSopenharmony_ci        }
854d6c458bSopenharmony_ci      }
864d6c458bSopenharmony_ci      return change;
874d6c458bSopenharmony_ci    }
884d6c458bSopenharmony_ci    hasAll(set: LightWeightSet<T>): boolean {
894d6c458bSopenharmony_ci      errorUtil.checkBindError('hasAll', LightWeightSet, this);
904d6c458bSopenharmony_ci      errorUtil.checkTypeError('set', 'LightWeightSet', set);
914d6c458bSopenharmony_ci      if (set.memberNumber > this.memberNumber) {
924d6c458bSopenharmony_ci        return false;
934d6c458bSopenharmony_ci      }
944d6c458bSopenharmony_ci      if (lightWeightAbility.isIncludeToArray(this.members.keys, set.members.keys)) {
954d6c458bSopenharmony_ci        return true;
964d6c458bSopenharmony_ci      }
974d6c458bSopenharmony_ci      return false;
984d6c458bSopenharmony_ci    }
994d6c458bSopenharmony_ci    has(key: T): boolean {
1004d6c458bSopenharmony_ci      errorUtil.checkBindError('has', LightWeightSet, this);
1014d6c458bSopenharmony_ci      return this.members.keys.indexOf(key) > -1;
1024d6c458bSopenharmony_ci    }
1034d6c458bSopenharmony_ci    equal(obj: Object): boolean {
1044d6c458bSopenharmony_ci      errorUtil.checkBindError('equal', LightWeightSet, this);
1054d6c458bSopenharmony_ci      if (this.memberNumber === 0) {
1064d6c458bSopenharmony_ci        return false;
1074d6c458bSopenharmony_ci      }
1084d6c458bSopenharmony_ci      if (obj instanceof LightWeightSet) {
1094d6c458bSopenharmony_ci        return JSON.stringify(obj.members.keys) === JSON.stringify(this.members.keys);
1104d6c458bSopenharmony_ci      }
1114d6c458bSopenharmony_ci      if (JSON.stringify(obj) === JSON.stringify(this.members.keys)) {
1124d6c458bSopenharmony_ci        return true;
1134d6c458bSopenharmony_ci      }
1144d6c458bSopenharmony_ci      return false;
1154d6c458bSopenharmony_ci    }
1164d6c458bSopenharmony_ci    increaseCapacityTo(minimumCapacity: number): void {
1174d6c458bSopenharmony_ci      errorUtil.checkBindError('increaseCapacityTo', LightWeightSet, this);
1184d6c458bSopenharmony_ci      errorUtil.checkTypeError('minimumCapacity', 'Integer', minimumCapacity);
1194d6c458bSopenharmony_ci      errorUtil.checkRangeError('minimumCapacity', minimumCapacity, this.capacity,
1204d6c458bSopenharmony_ci        undefined, '!=min');
1214d6c458bSopenharmony_ci      super.ensureCapacity(minimumCapacity);
1224d6c458bSopenharmony_ci    }
1234d6c458bSopenharmony_ci    getIndexOf(key: T): number {
1244d6c458bSopenharmony_ci      errorUtil.checkBindError('getIndexOf', LightWeightSet, this);
1254d6c458bSopenharmony_ci      return super.getIndexByKey(key);
1264d6c458bSopenharmony_ci    }
1274d6c458bSopenharmony_ci    isEmpty(): boolean {
1284d6c458bSopenharmony_ci      errorUtil.checkBindError('isEmpty', LightWeightSet, this);
1294d6c458bSopenharmony_ci      return this.memberNumber === 0;
1304d6c458bSopenharmony_ci    }
1314d6c458bSopenharmony_ci    remove(key: T): T {
1324d6c458bSopenharmony_ci      errorUtil.checkBindError('remove', LightWeightSet, this);
1334d6c458bSopenharmony_ci      return super.deletemember(key);
1344d6c458bSopenharmony_ci    }
1354d6c458bSopenharmony_ci    removeAt(index: number): boolean {
1364d6c458bSopenharmony_ci      errorUtil.checkBindError('removeAt', LightWeightSet, this);
1374d6c458bSopenharmony_ci      errorUtil.checkTypeError('index', 'Integer', index);
1384d6c458bSopenharmony_ci      if (index > this.memberNumber--) {
1394d6c458bSopenharmony_ci        return false;
1404d6c458bSopenharmony_ci      }
1414d6c458bSopenharmony_ci      this.members.hashs.splice(index, 1);
1424d6c458bSopenharmony_ci      this.members.values.splice(index, 1);
1434d6c458bSopenharmony_ci      this.members.keys.splice(index, 1);
1444d6c458bSopenharmony_ci      this.memberNumber--;
1454d6c458bSopenharmony_ci      return true;
1464d6c458bSopenharmony_ci    }
1474d6c458bSopenharmony_ci    clear(): void {
1484d6c458bSopenharmony_ci      errorUtil.checkBindError('clear', LightWeightSet, this);
1494d6c458bSopenharmony_ci      if (this.memberNumber !== 0 || this.capacity > 8) { // 8 : means number
1504d6c458bSopenharmony_ci        this.members.hashs = [];
1514d6c458bSopenharmony_ci        this.members.keys = [];
1524d6c458bSopenharmony_ci        this.members.values = [];
1534d6c458bSopenharmony_ci        this.memberNumber = 0;
1544d6c458bSopenharmony_ci        this.capacity = 8; // 8 : means number
1554d6c458bSopenharmony_ci      }
1564d6c458bSopenharmony_ci    }
1574d6c458bSopenharmony_ci    forEach(callbackfn: (value?: T, key?: T, set?: LightWeightSet<T>) => void,
1584d6c458bSopenharmony_ci      thisArg?: Object): void {
1594d6c458bSopenharmony_ci      errorUtil.checkBindError('forEach', LightWeightSet, this);
1604d6c458bSopenharmony_ci      errorUtil.checkTypeError('callbackfn', 'callable', callbackfn);
1614d6c458bSopenharmony_ci      for (let i: number = 0; i < this.memberNumber; i++) {
1624d6c458bSopenharmony_ci        callbackfn.call(thisArg, this.members.keys[i], this.members.keys[i], this);
1634d6c458bSopenharmony_ci      }
1644d6c458bSopenharmony_ci    }
1654d6c458bSopenharmony_ci    [Symbol.iterator](): IterableIterator<T> {
1664d6c458bSopenharmony_ci      errorUtil.checkBindError('Symbol.iterator', LightWeightSet, this);
1674d6c458bSopenharmony_ci      let count: number = 0;
1684d6c458bSopenharmony_ci      return {
1694d6c458bSopenharmony_ci        next: function (): { done: boolean, value: T } {
1704d6c458bSopenharmony_ci          let done: boolean = false;
1714d6c458bSopenharmony_ci          let value: T = undefined;
1724d6c458bSopenharmony_ci          done = count >= this.memberNumber;
1734d6c458bSopenharmony_ci          value = done ? undefined : this.members.keys[count];
1744d6c458bSopenharmony_ci          count++;
1754d6c458bSopenharmony_ci          return {
1764d6c458bSopenharmony_ci            done: done,
1774d6c458bSopenharmony_ci            value: value,
1784d6c458bSopenharmony_ci          };
1794d6c458bSopenharmony_ci        },
1804d6c458bSopenharmony_ci      };
1814d6c458bSopenharmony_ci    }
1824d6c458bSopenharmony_ci    toString(): string {
1834d6c458bSopenharmony_ci      errorUtil.checkBindError('toString', LightWeightSet, this);
1844d6c458bSopenharmony_ci      return this.members.keys.join(',');
1854d6c458bSopenharmony_ci    }
1864d6c458bSopenharmony_ci    toArray(): Array<T> {
1874d6c458bSopenharmony_ci      errorUtil.checkBindError('toArray', LightWeightSet, this);
1884d6c458bSopenharmony_ci      return this.members.keys.slice();
1894d6c458bSopenharmony_ci    }
1904d6c458bSopenharmony_ci    getValueAt(index: number): T {
1914d6c458bSopenharmony_ci      errorUtil.checkBindError('getValueAt', LightWeightSet, this);
1924d6c458bSopenharmony_ci      errorUtil.checkTypeError('index', 'Integer', index);
1934d6c458bSopenharmony_ci      return this.members.keys[index];
1944d6c458bSopenharmony_ci    }
1954d6c458bSopenharmony_ci    values(): IterableIterator<T> {
1964d6c458bSopenharmony_ci      errorUtil.checkBindError('values', LightWeightSet, this);
1974d6c458bSopenharmony_ci      return this.members.keys.values() as IterableIterator<T>;
1984d6c458bSopenharmony_ci    }
1994d6c458bSopenharmony_ci    entries(): IterableIterator<[T, T]> {
2004d6c458bSopenharmony_ci      errorUtil.checkBindError('entries', LightWeightSet, this);
2014d6c458bSopenharmony_ci      let count: number = 0;
2024d6c458bSopenharmony_ci      return {
2034d6c458bSopenharmony_ci        next: function (): { done: boolean, value: [T, T] } {
2044d6c458bSopenharmony_ci          let done: boolean = false;
2054d6c458bSopenharmony_ci          let value: [T, T] = undefined;
2064d6c458bSopenharmony_ci          let tempValue: T = undefined;
2074d6c458bSopenharmony_ci          done = count >= this.memberNumber;
2084d6c458bSopenharmony_ci          tempValue = this.members.keys[count];
2094d6c458bSopenharmony_ci          value = done ? undefined : ([tempValue, tempValue] as [T, T]);
2104d6c458bSopenharmony_ci          count++;
2114d6c458bSopenharmony_ci          return {
2124d6c458bSopenharmony_ci            done: done,
2134d6c458bSopenharmony_ci            value: value,
2144d6c458bSopenharmony_ci          };
2154d6c458bSopenharmony_ci        },
2164d6c458bSopenharmony_ci      };
2174d6c458bSopenharmony_ci    }
2184d6c458bSopenharmony_ci  }
2194d6c458bSopenharmony_ci  Object.freeze(LightWeightSet);
2204d6c458bSopenharmony_ci  fastLightWeightSet = LightWeightSet;
2214d6c458bSopenharmony_ci}
2224d6c458bSopenharmony_ciexport default fastLightWeightSet;
223