1/* 2 * Copyright (c) 2024 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 */ 15 16type FetchId = number; 17type ItemIndex = number; 18 19// eslint-disable-next-line @typescript-eslint/no-unused-vars 20class FetchingRegistry { 21 private readonly fetches = new Map<FetchId, ItemIndex>(); 22 private fetching = new Map<ItemIndex, FetchId>(); 23 private readonly fetchesBefore = new Map<ItemIndex, number>(); 24 25 private fetchCounter = 0; 26 27 registerFetch(index: ItemIndex): FetchId { 28 let fetchId = this.fetching.get(index); 29 if (fetchId !== undefined) { 30 return fetchId; 31 } 32 33 fetchId = ++this.fetchCounter; 34 this.fetching.set(index, fetchId); 35 this.fetches.set(fetchId, index); 36 this.fetchesBefore.set(index, this.fetches.size); 37 38 return fetchId; 39 } 40 41 getItem(fetchId: FetchId): ItemIndex { 42 return this.fetches.get(fetchId); 43 } 44 45 deleteFetch(fetchId: FetchId): void { 46 const index = this.fetches.get(fetchId); 47 if (index !== undefined) { 48 this.fetching.delete(index); 49 this.fetches.delete(fetchId); 50 } 51 } 52 53 deleteFetchByItem(index: ItemIndex): void { 54 const fetchId = this.fetching.get(index); 55 if (fetchId !== undefined) { 56 this.fetching.delete(index); 57 this.fetches.delete(fetchId); 58 } 59 } 60 61 isFetchingItem(index: ItemIndex): boolean { 62 return this.fetching.has(index); 63 } 64 65 incrementAllIndexesGreaterThen(value: number): void { 66 this.offsetAllIndexesGreaterThen(value, 1); 67 } 68 69 getAllIndexes(): Set<number> { 70 const set = new Set<number>(); 71 this.fetching.forEach((fetchId, itemIndex) => set.add(itemIndex)); 72 return set; 73 } 74 75 getFetchesCount(): number { 76 return this.fetches.size; 77 } 78 79 isFetchLatecomer(index: ItemIndex, threshold: number): boolean { 80 return this.fetchesBefore.get(index) > threshold; 81 } 82 83 private offsetAllIndexesGreaterThen(value: number, offset: number): void { 84 const newFetching = new Map<ItemIndex, FetchId>(); 85 this.fetches.forEach((index, fetchId) => { 86 const toSet = index > value ? index + offset : index; 87 newFetching.set(toSet, fetchId); 88 this.fetches.set(fetchId, toSet); 89 }); 90 this.fetching = newFetching; 91 } 92 93 decrementAllIndexesGreaterThen(value: number): void { 94 this.offsetAllIndexesGreaterThen(value, -1); 95 } 96} 97