<commit_before>#pragma once

#include "gc.hh"
#include "spinlock.h"
#include "refcache.hh"

template<class K, class V, u64 (*Hash)(const K&), size_t Buckets>
class weakcache
{
private:
  struct bucket;

  class item : public rcu_freed
  {
  public:
    const K key_;
    const refcache::weakref<V> weakref_;
    bucket* const parent_;
    islink<item> link_;

    item(const K& k, V* v, bucket* b)
      : rcu_freed("weakcache::item"), key_(k), weakref_(v), parent_(b) {}
    void do_gc() override { delete this; }
    NEW_DELETE_OPS(item)
  };

  class bucket
  {
  private:
    spinlock writelock_;
    islist<item, &item::link_> chain_;

  public:
    sref<V>
    lookup(const K& k) const
    {
      scoped_gc_epoch reader;
      for (auto &i: chain_) {
        if (i.key_ != k)
          continue;
        return i.weakref_.get();
      }
      return sref<V>();
    }

    bool
    insert(const K& k, V* v)
    {
      scoped_acquire l(&writelock_);
      for (auto &i: chain_)
        if (i.key_ == k)
          return false;

      chain_.push_front(new item(k, v, this));<commit_msg>weakcache: make do without operator!= on keys<commit_after>#pragma once

#include "gc.hh"
#include "spinlock.h"
#include "refcache.hh"

template<class K, class V, u64 (*Hash)(const K&), size_t Buckets>
class weakcache
{
private:
  struct bucket;

  class item : public rcu_freed
  {
  public:
    const K key_;
    const refcache::weakref<V> weakref_;
    bucket* const parent_;
    islink<item> link_;

    item(const K& k, V* v, bucket* b)
      : rcu_freed("weakcache::item"), key_(k), weakref_(v), parent_(b) {}
    void do_gc() override { delete this; }
    NEW_DELETE_OPS(item)
  };

  class bucket
  {
  private:
    spinlock writelock_;
    islist<item, &item::link_> chain_;

  public:
    sref<V>
    lookup(const K& k) const
    {
      scoped_gc_epoch reader;
      for (auto &i: chain_) {
        if (!(i.key_ == k))
          continue;
        return i.weakref_.get();
      }
      return sref<V>();
    }

    bool
    insert(const K& k, V* v)
    {
      scoped_acquire l(&writelock_);
      for (auto &i: chain_)
        if (i.key_ == k)
          return false;

      chain_.push_front(new item(k, v, this));
{'fraction_non_alphanumeric': 0.135196034249662, 'fraction_numerical': 0.0018026137899954935, 'mean_word_length': 2.552, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5354784', 'n_tokens_mistral': 816, 'n_tokens_neox': 799, 'n_words': 213}