• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15declare function requireNapi(s: string): any;
16interface ArkPrivate {
17  LightWeightSet: number;
18  Load(key: number): Object;
19}
20let flag: boolean = false;
21let fastLightWeightSet: Object = undefined;
22let arkPritvate: ArkPrivate = globalThis['ArkPrivate'] || undefined;
23if (arkPritvate !== undefined) {
24  fastLightWeightSet = arkPritvate.Load(arkPritvate.LightWeightSet);
25} else {
26  flag = true;
27}
28if (flag || fastLightWeightSet === undefined) {
29  const lightWeightAbility = requireNapi('util.struct');
30  const errorUtil = lightWeightAbility.errorUtil;
31  interface IterableIterator<T> {
32    next: () => {
33      value: T | undefined;
34      done: boolean;
35    };
36  }
37  class HandlerLightWeightSet<T> {
38    set(target: LightWeightSet<T>, p: string, value: string): boolean {
39      if (p in target) {
40        target[p] = value;
41        return true;
42      }
43      return false;
44    }
45    defineProperty(): boolean {
46      throw new Error(`Can't define Property on LightWeightSet Object`);
47    }
48    deleteProperty(): boolean {
49      throw new Error(`Can't delete Property on LightWeightSet Object`);
50    }
51    setPrototypeOf(): boolean {
52      throw new Error(`Can't set Prototype on LightWeightSet Object`);
53    }
54  }
55  class LightWeightSet<T> extends lightWeightAbility.LightWeightClass<T, T> {
56    constructor() {
57      errorUtil.checkNewTargetIsNullError('LightWeightSet', !new.target);
58      super();
59      return new Proxy(this, new HandlerLightWeightSet());
60    }
61    get length(): number {
62      return this.memberNumber;
63    }
64    add(obj: T): boolean {
65      errorUtil.checkBindError('add', LightWeightSet, this);
66      if (this.members.keys.indexOf(obj) > 0) {
67        return false;
68      }
69      this.addmember(obj);
70      return true;
71    }
72    addAll(set: LightWeightSet<T>): boolean {
73      errorUtil.checkBindError('addAll', LightWeightSet, this);
74      errorUtil.checkTypeError('set', 'LightWeightSet', set);
75      if (!(set instanceof LightWeightSet)) {
76        throw new TypeError('Incoming object is not JSAPILightWeightSet');
77      }
78      let change: boolean = false;
79      if (set.memberNumber === 0) {
80        change = false;
81      } else {
82        for (let i: number = 0; i < set.memberNumber; i++) {
83          change = this.add(set.members.keys[i]) || change;
84        }
85      }
86      return change;
87    }
88    hasAll(set: LightWeightSet<T>): boolean {
89      errorUtil.checkBindError('hasAll', LightWeightSet, this);
90      errorUtil.checkTypeError('set', 'LightWeightSet', set);
91      if (set.memberNumber > this.memberNumber) {
92        return false;
93      }
94      if (lightWeightAbility.isIncludeToArray(this.members.keys, set.members.keys)) {
95        return true;
96      }
97      return false;
98    }
99    has(key: T): boolean {
100      errorUtil.checkBindError('has', LightWeightSet, this);
101      return this.members.keys.indexOf(key) > -1;
102    }
103    equal(obj: Object): boolean {
104      errorUtil.checkBindError('equal', LightWeightSet, this);
105      if (this.memberNumber === 0) {
106        return false;
107      }
108      if (obj instanceof LightWeightSet) {
109        return JSON.stringify(obj.members.keys) === JSON.stringify(this.members.keys);
110      }
111      if (JSON.stringify(obj) === JSON.stringify(this.members.keys)) {
112        return true;
113      }
114      return false;
115    }
116    increaseCapacityTo(minimumCapacity: number): void {
117      errorUtil.checkBindError('increaseCapacityTo', LightWeightSet, this);
118      errorUtil.checkTypeError('minimumCapacity', 'Integer', minimumCapacity);
119      errorUtil.checkRangeError('minimumCapacity', minimumCapacity, this.capacity,
120        undefined, '!=min');
121      super.ensureCapacity(minimumCapacity);
122    }
123    getIndexOf(key: T): number {
124      errorUtil.checkBindError('getIndexOf', LightWeightSet, this);
125      return super.getIndexByKey(key);
126    }
127    isEmpty(): boolean {
128      errorUtil.checkBindError('isEmpty', LightWeightSet, this);
129      return this.memberNumber === 0;
130    }
131    remove(key: T): T {
132      errorUtil.checkBindError('remove', LightWeightSet, this);
133      return super.deletemember(key);
134    }
135    removeAt(index: number): boolean {
136      errorUtil.checkBindError('removeAt', LightWeightSet, this);
137      errorUtil.checkTypeError('index', 'Integer', index);
138      if (index > this.memberNumber--) {
139        return false;
140      }
141      this.members.hashs.splice(index, 1);
142      this.members.values.splice(index, 1);
143      this.members.keys.splice(index, 1);
144      this.memberNumber--;
145      return true;
146    }
147    clear(): void {
148      errorUtil.checkBindError('clear', LightWeightSet, this);
149      if (this.memberNumber !== 0 || this.capacity > 8) { // 8 : means number
150        this.members.hashs = [];
151        this.members.keys = [];
152        this.members.values = [];
153        this.memberNumber = 0;
154        this.capacity = 8; // 8 : means number
155      }
156    }
157    forEach(callbackfn: (value?: T, key?: T, set?: LightWeightSet<T>) => void,
158      thisArg?: Object): void {
159      errorUtil.checkBindError('forEach', LightWeightSet, this);
160      errorUtil.checkTypeError('callbackfn', 'callable', callbackfn);
161      let data: LightWeightSet<T> = this;
162      for (let i: number = 0; i < data.memberNumber; i++) {
163        callbackfn.call(thisArg, data.members.keys[i], data.members.keys[i], data);
164      }
165    }
166    [Symbol.iterator](): IterableIterator<T> {
167      errorUtil.checkBindError('Symbol.iterator', LightWeightSet, this);
168      let data: LightWeightSet<T> = this;
169      let count: number = 0;
170      return {
171        next: function (): { done: boolean, value: T } {
172          let done: boolean = false;
173          let value: T = undefined;
174          done = count >= data.memberNumber;
175          value = done ? undefined : data.members.keys[count];
176          count++;
177          return {
178            done: done,
179            value: value,
180          };
181        },
182      };
183    }
184    toString(): string {
185      errorUtil.checkBindError('toString', LightWeightSet, this);
186      return this.members.keys.join(',');
187    }
188    toArray(): Array<T> {
189      errorUtil.checkBindError('toArray', LightWeightSet, this);
190      return this.members.keys.slice();
191    }
192    getValueAt(index: number): T {
193      errorUtil.checkBindError('getValueAt', LightWeightSet, this);
194      errorUtil.checkTypeError('index', 'Integer', index);
195      return this.members.keys[index];
196    }
197    values(): IterableIterator<T> {
198      errorUtil.checkBindError('values', LightWeightSet, this);
199      return this.members.keys.values() as IterableIterator<T>;
200    }
201    entries(): IterableIterator<[T, T]> {
202      errorUtil.checkBindError('entries', LightWeightSet, this);
203      let data: LightWeightSet<T> = this;
204      let count: number = 0;
205      return {
206        next: function (): { done: boolean, value: [T, T] } {
207          let done: boolean = false;
208          let value: [T, T] = undefined;
209          let tempValue: T = undefined;
210          done = count >= data.memberNumber;
211          tempValue = data.members.keys[count];
212          value = done ? undefined : ([tempValue, tempValue] as [T, T]);
213          count++;
214          return {
215            done: done,
216            value: value,
217          };
218        },
219      };
220    }
221  }
222  Object.freeze(LightWeightSet);
223  fastLightWeightSet = LightWeightSet;
224}
225export default fastLightWeightSet;
226