// Copyright (c) 2014, 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.

library dart2js.util.maplet;

import 'dart:collection' show MapBase, IterableBase;

class Maplet<K, V> extends MapBase<K, V> {
  static const _MARKER = const _MapletMarker();
  static const CAPACITY = 8;

// The maplet can be in one of four states:
  //
  //   * Empty          (extra: null,   key: marker, value: null)
  //   * Single element (extra: null,   key: key,    value: value)
  //   * List-backed    (extra: length, key: list,   value: null)
  //   * Map-backed     (extra: marker, key: map,    value: null)
  //
  // When the maplet is list-backed, the list has two sections: One
  // for keys and one for values. The first [CAPACITY] entries are
  // the keys and they may contain markers for deleted elements. After
  // the keys there are [CAPACITY] entries for the values.

  var _key = _MARKER;
  var _value;
  var _extra;

  Maplet();

  Maplet.from(Maplet<K, V> other) {
    other.forEach((K key, V value) {
      this[key] = value;
    });
  }

  bool get isEmpty {
    if (_extra == null) {
      return _MARKER == _key;
    } else if (_MARKER == _extra) {
      return _key.isEmpty;
    } else {
      return _extra == 0;
    }
  }

  int get length {
    if (_extra == null) {
      return (_MARKER == _key) ? 0 : 1;
    } else if (_MARKER == _extra) {
      return _key.length;
    } else {
      return _extra;
    }
  }

  bool containsKey(K key) {
    if (_extra == null) {
      return _key == key;
    } else if (_MARKER == _extra) {
      return _key.containsKey(key);
    } else {
      for (int remaining = _extra, i = 0; remaining > 0 && i < CAPACITY; i++) {
        var candidate = _key[i];
        if (_MARKER == candidate) continue;
        if (candidate == key) return true;
        remaining--;
      }
      return false;
    }
  }

  V operator [](K key) {
    if (_extra == null) {
      return (_key == key) ? _value : null;
    } else if (_MARKER == _extra) {
      return _key[key];
    } else {
      for (int remaining = _extra, i = 0; remaining > 0 && i < CAPACITY; i++) {
        var candidate = _key[i];
        if (_MARKER == candidate) continue;
        if (candidate == key) return _key[i + CAPACITY];
        remaining--;
      }
      return null;
    }
  }

  void operator []=(K key, V value) {
    if (_extra == null) {
      if (_MARKER == _key) {
        _key = key;
        _value = value;
      } else if (_key == key) {
        _value = value;
      } else {
        List list = new List(CAPACITY * 2);
        list[0] = _key;
        list[1] = key;
        list[CAPACITY] = _value;
        list[CAPACITY + 1] = value;
        _key = list;
        _value = null;
        _extra = 2;  // Two elements.
      }
    } else if (_MARKER == _extra) {
      _key[key] = value;
    } else {
      int remaining = _extra;
      int index = 0;
      int copyTo, copyFrom;
      while (remaining > 0 && index < CAPACITY) {
        var candidate = _key[index];
        if (_MARKER == candidate) {
          // Keep track of the last range of empty slots in the
          // list. When we're done we'll move all the elements
          // after those empty slots down, so that adding an element
          // after that will preserve the insertion order.
          if (copyFrom == index) {
            copyFrom++;
          } else {
            copyTo = index;
            copyFrom = index + 1;
          }
        } else if (candidate == key) {
          _key[CAPACITY + index] = value;
          return;
        } else {
          // Skipped an element that didn't match.
          remaining--;
        }
        index++;
      }
      if (index < CAPACITY) {
        _key[index] = key;
        _key[CAPACITY + index] = value;
        _extra++;
      } else if (_extra < CAPACITY) {
        // Move the last elements down into the last empty slots
        // so that we have empty slots after the last element.
        while (copyFrom < CAPACITY) {
          _key[copyTo] = _key[copyFrom];
          _key[CAPACITY + copyTo] = _key[CAPACITY + copyFrom];
          copyTo++;
          copyFrom++;
        }
        // Insert the new element as the last element.
        _key[copyTo] = key;
        _key[CAPACITY + copyTo] = value;
        copyTo++;
        // Add one to the length encoded in the extra field.
        _extra++;
        // Clear all elements after the new last elements to
        // make sure we don't keep extra stuff alive.
        while (copyTo < CAPACITY) {
          _key[copyTo] = _key[CAPACITY + copyTo] = null;
          copyTo++;
        }
      } else {
        Map map = new Map();
        forEach((eachKey, eachValue) => map[eachKey] = eachValue);
        map[key] = value;
        _key = map;
        _extra = _MARKER;
      }
    }
  }

  V remove(K key) {
    if (_extra == null) {
      if (_key != key) return null;
      _key = _MARKER;
      V result = _value;
      _value = null;
      return result;
    } else if (_MARKER == _extra) {
      return _key.remove(key);
    } else {
      for (int remaining = _extra, i = 0; remaining > 0 && i < CAPACITY; i++) {
        var candidate = _key[i];
        if (_MARKER == candidate) continue;
        if (candidate == key) {
          int valueIndex = CAPACITY + i;
          var result = _key[valueIndex];
          _key[i] = _MARKER;
          _key[valueIndex] = null;
          _extra--;
          return result;
        }
        remaining--;
      }
      return null;
    }
  }

  void forEach(void action(K key, V value)) {
    if (_extra == null) {
      if (_MARKER != _key) action(_key, _value);
    } else if (_MARKER == _extra) {
      _key.forEach(action);
    } else {
      for (int remaining = _extra, i = 0; remaining > 0 && i < CAPACITY; i++) {
        var candidate = _key[i];
        if (_MARKER == candidate) continue;
        action(candidate, _key[CAPACITY + i]);
        remaining--;
      }
    }
  }

  void clear() {
    _key = _MARKER;
    _value = _extra = null;
  }

  Iterable<K> get keys => new _MapletKeyIterable<K>(this);
}

class _MapletMarker {
  const _MapletMarker();
}

class _MapletKeyIterable<K> extends IterableBase<K> {
  final Maplet<K, dynamic> maplet;

  _MapletKeyIterable(this.maplet);

  Iterator<K> get iterator {
    if (maplet._extra == null) {
      return new _MapletSingleIterator<K>(maplet._key);
    } else if (Maplet._MARKER == maplet._extra) {
      return maplet._key.keys.iterator;
    } else {
      return new _MapletListIterator<K>(maplet._key, maplet._extra);
    }
  }
}

class _MapletSingleIterator<K> implements Iterator<K> {
  var _element;
  K _current;

  _MapletSingleIterator(this._element);

  K get current => _current;

  bool moveNext() {
    if (Maplet._MARKER == _element) {
      _current = null;
      return false;
    }
    _current = _element;
    _element = Maplet._MARKER;
    return true;
  }
}

class _MapletListIterator<K> implements Iterator<K> {
  final List _list;
  int _remaining;
  int _index = 0;
  K _current;

  _MapletListIterator(this._list, this._remaining);

  K get current => _current;

  bool moveNext() {
    while (_remaining > 0) {
      var candidate = _list[_index++];
      if (Maplet._MARKER != candidate) {
        _current = candidate;
        _remaining--;
        return true;
      }
    }
    _current = null;
    return false;
  }
}