// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

part of dart._vmservice;

/// Set like contains which automatically generated String ids for its items
class NamedLookup<E extends Object> extends Iterable<E> {
  final IdGenerator _generator;
  final _elements = <String, E>{};
  final _ids = <E, String>{};

  NamedLookup({String prologue = ''})
    : _generator = IdGenerator(prologue: prologue);

  void add(E e) {
    final id = _generator.newId();
    _elements[id] = e;
    _ids[e] = id;
  }

  void remove(E e) {
    final id = _ids.remove(e)!;
    _elements.remove(id);
    _generator.release(id);
  }

  E operator [](String id) => _elements[id]!;
  String keyOf(E e) => _ids[e]!;

  Iterator<E> get iterator => _ids.keys.iterator;
}

/// Generator for unique ids which recycles expired ones
class IdGenerator {
  /// Fixed initial part of the id
  final String prologue;
  // Ids in use
  final _used = <String>{};

  /// Ids that has been released (use these before generate new ones)
  final _free = <String>{};

  /// Next id to generate if no one can be recycled (first use _free);
  int _next = 0;

  IdGenerator({this.prologue = ''});

  /// Returns a new Id (possibly recycled)
  String newId() {
    String id;
    if (_free.isEmpty) {
      id = prologue + (_next++).toString();
    } else {
      id = _free.first;
    }
    _free.remove(id);
    _used.add(id);
    return id;
  }

  /// Releases the id and mark it for recycle
  void release(String id) {
    if (_used.remove(id)) {
      _free.add(id);
    }
  }
}
