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

#ifndef RUNTIME_VM_WEAK_TABLE_H_
#define RUNTIME_VM_WEAK_TABLE_H_

#include "vm/globals.h"

#include "platform/assert.h"
#include "vm/raw_object.h"

namespace dart {

class WeakTable {
 public:
  WeakTable() : size_(kMinSize), used_(0), count_(0) {
    ASSERT(Utils::IsPowerOfTwo(size_));
    data_ = reinterpret_cast<intptr_t*>(calloc(size_, kEntrySize * kWordSize));
  }
  explicit WeakTable(intptr_t size) : used_(0), count_(0) {
    ASSERT(size >= 0);
    ASSERT(Utils::IsPowerOfTwo(kMinSize));
    if (size < kMinSize) {
      size = kMinSize;
    }
    // Get a max size that avoids overflows.
    const intptr_t kMaxSize =
      (kIntptrOne << (kBitsPerWord - 2)) / (kEntrySize * kWordSize);
    ASSERT(Utils::IsPowerOfTwo(kMaxSize));
    if (size > kMaxSize) {
      size = kMaxSize;
    }
    size_ = size;
    ASSERT(Utils::IsPowerOfTwo(size_));
    data_ = reinterpret_cast<intptr_t*>(calloc(size_, kEntrySize * kWordSize));
  }

  ~WeakTable() {
    free(data_);
  }

  static WeakTable* NewFrom(WeakTable* original) {
    return new WeakTable(SizeFor(original->count(), original->size()));
  }

  intptr_t size() const { return size_; }
  intptr_t used() const { return used_; }
  intptr_t count() const { return count_; }

  bool IsValidEntryAt(intptr_t i) const {
    ASSERT(((ValueAt(i) == 0) &&
            ((ObjectAt(i) == NULL) ||
             (data_[ObjectIndex(i)] == kDeletedEntry))) ||
           ((ValueAt(i) != 0) &&
            (ObjectAt(i) != NULL) &&
            (data_[ObjectIndex(i)] != kDeletedEntry)));
    return (data_[ValueIndex(i)] != 0);
  }

  void InvalidateAt(intptr_t i) {
    ASSERT(IsValidEntryAt(i));
    SetValueAt(i, 0);
  }

  RawObject* ObjectAt(intptr_t i) const {
    ASSERT(i >= 0);
    ASSERT(i < size());
    return reinterpret_cast<RawObject*>(data_[ObjectIndex(i)]);
  }

  intptr_t ValueAt(intptr_t i) const {
    ASSERT(i >= 0);
    ASSERT(i < size());
    return data_[ValueIndex(i)];
  }

  void SetValue(RawObject* key, intptr_t val);

  intptr_t GetValue(RawObject* key) const {
    intptr_t mask = size() - 1;
    intptr_t idx = Hash(key) & mask;
    RawObject* obj = ObjectAt(idx);
    while (obj != NULL) {
      if (obj == key) {
        return ValueAt(idx);
      }
      idx = (idx + 1) & mask;
      obj = ObjectAt(idx);
    }
    ASSERT(ValueAt(idx) == 0);
    return 0;
  }

  void Reset();

 private:
  enum {
    kObjectOffset = 0,
    kValueOffset,
    kEntrySize,
  };

  static const intptr_t kDeletedEntry = 1;  // Equivalent to a tagged NULL.
  static const intptr_t kMinSize = 8;

  static intptr_t SizeFor(intptr_t count, intptr_t size);
  static intptr_t LimitFor(intptr_t size) {
    // Maintain a maximum of 75% fill rate.
    return 3 * (size / 4);
  }
  intptr_t limit() const { return LimitFor(size()); }

  intptr_t index(intptr_t i) const {
    return i * kEntrySize;
  }

  void set_used(intptr_t val) {
    ASSERT(val <= limit());
    used_ = val;
  }

  void set_count(intptr_t val) {
    ASSERT(val <= limit());
    ASSERT(val <= used());
    count_ = val;
  }

  intptr_t ObjectIndex(intptr_t i) const {
    return index(i) + kObjectOffset;
  }

  intptr_t ValueIndex(intptr_t i) const {
    return index(i) + kValueOffset;
  }

  void SetObjectAt(intptr_t i, RawObject* key) {
    ASSERT(i >= 0);
    ASSERT(i < size());
    data_[ObjectIndex(i)] = reinterpret_cast<intptr_t>(key);
  }

  void SetValueAt(intptr_t i, intptr_t val) {
    ASSERT(i >= 0);
    ASSERT(i < size());
    // Setting a value of 0 is equivalent to invalidating the entry.
    if (val == 0) {
      data_[ObjectIndex(i)] = kDeletedEntry;
      set_count(count() - 1);
    }
    data_[ValueIndex(i)] = val;
  }

  void Rehash();

  static intptr_t Hash(RawObject* key) {
    return reinterpret_cast<uintptr_t>(key) * 92821;
  }

  // data_ contains size_ tuples of key/value.
  intptr_t* data_;
  // size_ keeps the number of entries in data_. used_ maintains the number of
  // non-NULL entries and will trigger rehashing if needed. count_ stores the
  // number valid entries, and will determine the size_ after rehashing.
  intptr_t size_;
  intptr_t used_;
  intptr_t count_;

  DISALLOW_COPY_AND_ASSIGN(WeakTable);
};

}  // namespace dart

#endif  // RUNTIME_VM_WEAK_TABLE_H_
