// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef QUICHE_SPDY_CORE_HPACK_HPACK_HEADER_TABLE_H_
#define QUICHE_SPDY_CORE_HPACK_HPACK_HEADER_TABLE_H_

#include <cstddef>
#include <cstdint>
#include <deque>
#include <memory>

#include "absl/base/attributes.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/hash/hash.h"
#include "absl/strings/string_view.h"
#include "common/platform/api/quiche_export.h"
#include "spdy/core/hpack/hpack_entry.h"

// All section references below are to http://tools.ietf.org/html/rfc7541.

namespace spdy {

namespace test {
class HpackHeaderTablePeer;
}  // namespace test

// Return value of GetByName() and GetByNameAndValue() if matching entry is not
// found.  This value is never used in HPACK for indexing entries, see
// https://httpwg.org/specs/rfc7541.html#index.address.space.
constexpr size_t kHpackEntryNotFound = 0;

// A data structure for the static table (2.3.1) and the dynamic table (2.3.2).
class QUICHE_EXPORT_PRIVATE HpackHeaderTable {
 public:
  friend class test::HpackHeaderTablePeer;

  // Use a lightweight, memory efficient container for the static table, which
  // is initialized once and never changed after.
  using StaticEntryTable = std::vector<HpackEntry>;

  // HpackHeaderTable takes advantage of the deque property that references
  // remain valid, so long as insertions & deletions are at the head & tail.
  // This precludes the use of base::circular_deque.
  // TODO(b/182349990): Change to a more memory efficient container.
  using DynamicEntryTable = std::deque<HpackEntry>;

  using NameValueToEntryMap = absl::flat_hash_map<HpackLookupEntry, size_t>;
  using NameToEntryMap = absl::flat_hash_map<absl::string_view, size_t>;

  HpackHeaderTable();
  HpackHeaderTable(const HpackHeaderTable&) = delete;
  HpackHeaderTable& operator=(const HpackHeaderTable&) = delete;

  ~HpackHeaderTable();

  // Last-acknowledged value of SETTINGS_HEADER_TABLE_SIZE.
  size_t settings_size_bound() const { return settings_size_bound_; }

  // Current and maximum estimated byte size of the table, as described in
  // 4.1. Notably, this is /not/ the number of entries in the table.
  size_t size() const { return size_; }
  size_t max_size() const { return max_size_; }

  // The HPACK indexing scheme used by GetByName() and GetByNameAndValue() is
  // defined at https://httpwg.org/specs/rfc7541.html#index.address.space.

  // Returns the index of the lowest-index entry matching |name|,
  // or kHpackEntryNotFound if no matching entry is found.
  size_t GetByName(absl::string_view name);

  // Returns the index of the lowest-index entry matching |name| and |value|,
  // or kHpackEntryNotFound if no matching entry is found.
  size_t GetByNameAndValue(absl::string_view name, absl::string_view value);

  // Sets the maximum size of the header table, evicting entries if
  // necessary as described in 5.2.
  void SetMaxSize(size_t max_size);

  // Sets the SETTINGS_HEADER_TABLE_SIZE bound of the table. Will call
  // SetMaxSize() as needed to preserve max_size() <= settings_size_bound().
  void SetSettingsHeaderTableSize(size_t settings_size);

  // Determine the set of entries which would be evicted by the insertion
  // of |name| & |value| into the table, as per section 4.4. No eviction
  // actually occurs. The set is returned via range [begin_out, end_out).
  void EvictionSet(absl::string_view name,
                   absl::string_view value,
                   DynamicEntryTable::iterator* begin_out,
                   DynamicEntryTable::iterator* end_out);

  // Adds an entry for the representation, evicting entries as needed. |name|
  // and |value| must not point to an entry in |dynamic_entries_| which is about
  // to be evicted, but they may point to an entry which is not.
  // The added HpackEntry is returned, or NULL is returned if all entries were
  // evicted and the empty table is of insufficent size for the representation.
  const HpackEntry* TryAddEntry(absl::string_view name,
                                absl::string_view value);

 private:
  // Returns number of evictions required to enter |name| & |value|.
  size_t EvictionCountForEntry(absl::string_view name,
                               absl::string_view value) const;

  // Returns number of evictions required to reclaim |reclaim_size| table size.
  size_t EvictionCountToReclaim(size_t reclaim_size) const;

  // Evicts |count| oldest entries from the table.
  void Evict(size_t count);

  // |static_entries_|, |static_index_|, and |static_name_index_| are owned by
  // HpackStaticTable singleton.

  // Stores HpackEntries.
  const StaticEntryTable& static_entries_;
  DynamicEntryTable dynamic_entries_;

  // Tracks the index of the unique HpackEntry for a given header name and
  // value.  Keys consist of string_views that point to strings stored in
  // |static_entries_|.
  const NameValueToEntryMap& static_index_;

  // Tracks the index of the first static entry for each name in the static
  // table.  Each key is a string_view that points to a name string stored in
  // |static_entries_|.
  const NameToEntryMap& static_name_index_;

  // Tracks the index of the most recently inserted HpackEntry for a given
  // header name and value.  Keys consist of string_views that point to strings
  // stored in |dynamic_entries_|.
  NameValueToEntryMap dynamic_index_;

  // Tracks the index of the most recently inserted HpackEntry for a given
  // header name.  Each key is a string_view that points to a name string stored
  // in |dynamic_entries_|.
  NameToEntryMap dynamic_name_index_;

  // Last acknowledged value for SETTINGS_HEADER_TABLE_SIZE.
  size_t settings_size_bound_;

  // Estimated current and maximum byte size of the table.
  // |max_size_| <= |settings_size_bound_|
  size_t size_;
  size_t max_size_;

  // Total number of dynamic table insertions so far
  // (including entries that have been evicted).
  size_t dynamic_table_insertions_;
};

}  // namespace spdy

#endif  // QUICHE_SPDY_CORE_HPACK_HPACK_HEADER_TABLE_H_
