1// Copyright 2020 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5export class Group {
6  constructor(key, id, parentTotal, entries) {
7    this.key = key;
8    this.id = id;
9    this.entries = entries;
10    this.length = entries.length;
11    this.parentTotal = parentTotal;
12  }
13
14  get percent() {
15    return this.length / this.parentTotal * 100;
16  }
17
18  add() {
19    this.length++;
20  }
21
22  addEntry(entry) {
23    this.length++;
24    this.entries.push(entry);
25  }
26}
27
28export function groupBy(array, keyFunction, collect = false) {
29  if (array.length === 0) return [];
30  if (keyFunction === undefined) keyFunction = each => each;
31  const keyToGroup = new Map();
32  const groups = [];
33  const sharedEmptyArray = [];
34  let id = 0;
35  // This is performance critical, resorting to for-loop
36  for (let each of array) {
37    const key = keyFunction(each);
38    let group = keyToGroup.get(key);
39    if (group !== undefined) {
40      collect ? group.addEntry(each) : group.add();
41      continue;
42    }
43    let entries = collect ? [each] : sharedEmptyArray;
44    group = new Group(key, id++, array.length, entries);
45    groups.push(group);
46    keyToGroup.set(key, group);
47  }
48  // Sort by length
49  return groups.sort((a, b) => b.length - a.length);
50}
51
52export function arrayEquals(left, right) {
53  if (left == right) return true;
54  if (left.length != right.length) return false;
55  for (let i = 0; i < left.length; i++) {
56    if (left[i] != right[i]) return false;
57  }
58  return true;
59}
60
61export function entriesEquals(left, right) {
62  if (left == right) return true;
63  if (left == undefined) return right == undefined;
64  const leftEntries = Object.entries(left);
65  const rightEntries = Object.entries(right);
66  if (leftEntries.length !== rightEntries.length) return false;
67  for (let i = 0; i < leftEntries.length; i++) {
68    const l = leftEntries[i];
69    const r = rightEntries[i];
70    if (l[0] != r[0]) return false;
71    if (l[1] != r[1]) return false;
72  }
73  return true;
74}
75
76export function keysEquals(left, right) {
77  if (left == right) return true;
78  if (left == undefined) return right == undefined;
79  return arrayEquals(Object.keys(left), Object.keys(right));
80}
81
82export * from '../js/helper.mjs'
83