//===-- sanitizer_chained_origin_depot.cpp --------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// A storage for chained origins.
//===----------------------------------------------------------------------===//

#include "sanitizer_chained_origin_depot.h"

namespace __sanitizer {

bool ChainedOriginDepot::ChainedOriginDepotNode::eq(
    hash_type hash, const args_type &args) const {
  return here_id == args.here_id && prev_id == args.prev_id;
}

uptr ChainedOriginDepot::ChainedOriginDepotNode::storage_size(
    const args_type &args) {
  return sizeof(ChainedOriginDepotNode);
}

/* This is murmur2 hash for the 64->32 bit case.
   It does not behave all that well because the keys have a very biased
   distribution (I've seen 7-element buckets with the table only 14% full).

   here_id is built of
   * (1 bits) Reserved, zero.
   * (8 bits) Part id = bits 13..20 of the hash value of here_id's key.
   * (23 bits) Sequential number (each part has each own sequence).

   prev_id has either the same distribution as here_id (but with 3:8:21)
   split, or one of two reserved values (-1) or (-2). Either case can
   dominate depending on the workload.
*/
ChainedOriginDepot::ChainedOriginDepotNode::hash_type
ChainedOriginDepot::ChainedOriginDepotNode::hash(const args_type &args) {
  const u32 m = 0x5bd1e995;
  const u32 seed = 0x9747b28c;
  const u32 r = 24;
  u32 h = seed;
  u32 k = args.here_id;
  k *= m;
  k ^= k >> r;
  k *= m;
  h *= m;
  h ^= k;

  k = args.prev_id;
  k *= m;
  k ^= k >> r;
  k *= m;
  h *= m;
  h ^= k;

  h ^= h >> 13;
  h *= m;
  h ^= h >> 15;
  return h;
}

bool ChainedOriginDepot::ChainedOriginDepotNode::is_valid(
    const args_type &args) {
  return true;
}

void ChainedOriginDepot::ChainedOriginDepotNode::store(const args_type &args,
                                                       hash_type other_hash) {
  here_id = args.here_id;
  prev_id = args.prev_id;
}

ChainedOriginDepot::ChainedOriginDepotNode::args_type
ChainedOriginDepot::ChainedOriginDepotNode::load() const {
  args_type ret = {here_id, prev_id};
  return ret;
}

ChainedOriginDepot::ChainedOriginDepotNode::Handle
ChainedOriginDepot::ChainedOriginDepotNode::get_handle() {
  return Handle(this);
}

ChainedOriginDepot::ChainedOriginDepot() {}

StackDepotStats ChainedOriginDepot::GetStats() const {
  return depot.GetStats();
}

bool ChainedOriginDepot::Put(u32 here_id, u32 prev_id, u32 *new_id) {
  ChainedOriginDepotDesc desc = {here_id, prev_id};
  bool inserted;
  ChainedOriginDepotNode::Handle h = depot.Put(desc, &inserted);
  *new_id = h.valid() ? h.id() : 0;
  return inserted;
}

u32 ChainedOriginDepot::Get(u32 id, u32 *other) {
  ChainedOriginDepotDesc desc = depot.Get(id);
  *other = desc.prev_id;
  return desc.here_id;
}

void ChainedOriginDepot::LockAll() { depot.LockAll(); }

void ChainedOriginDepot::UnlockAll() { depot.UnlockAll(); }

}  // namespace __sanitizer
