<commit_before>const entries = new WeakMap();
export function getEntry(target, key) {
  let targetMap = entries.get(target);
  if (!targetMap) {
    targetMap = new Map();
    entries.set(target, targetMap);
  }

  let entry = targetMap.get(key);

  if (!entry) {
    entry = {
      target,
      key,
      value: undefined,
      deps: new Set(),
      state: 1,
      checksum: 0,
    };
    targetMap.set(key, entry);
  }

  return entry;
}

function calculateChecksum({ state, deps }) {
  let checksum = state;
  deps.forEach((entry) => {
    if (!entry.checksum) {
      // eslint-disable-next-line no-unused-expressions
      entry.target[entry.key];
    }
    checksum += entry.state;
  });

  return checksum;
}

let context = null;
export function get(target, key, getter) {
  const entry = getEntry(target, key);

  if (context === entry) {
    context = null;
    throw Error(`[cache] Circular '${key}' get invocation in '${target}'`);
  }

  if (context) {
    context.deps.add(entry);
  }

  const parentContext = context;
  context = entry;

  if (entry.checksum && entry.checksum === calculateChecksum(entry)) {
    context = parentContext;
    return entry.value;
  }

  entry.deps.clear();

  try {
    const nextValue = getter(target, entry.value);

    if (nextValue !== entry.value) {
      entry.state += 1;
      entry.value = nextValue;
    }

    entry.checksum = calculateChecksum(entry);
    context = parentContext;
  } catch (e) {
    context = null;
    throw e;
  }

  return entry.value;
}

export function set(target, key, setter, value, callback) {
  if (context) {
    context = null;
    throw Error(`[cache] Try to set '${key}' of '${target}' in get call`);
  }

  const entry = getEntry(target, key);
  const newValue = setter(target, value, entry.value);

  if (newValue !== entry.value) {
    entry.state += 1;
    entry.value = newValue;

    callback();
  }
}

export function invalidate(target, key, clearValue) {
  if (context) {
    context = null;
    throw Error(`[cache] Try to invalidate '${key}' in '${target}' get call`);
  }

  const entry = getEntry(target, key);

  entry.checksum = 0;

  if (clearValue) {
    entry.value = undefined;
  }
}<commit_msg>fix(cache): stringify target with tag name in error messages<commit_after>import { stringifyElement } from './utils';

const entries = new WeakMap();
export function getEntry(target, key) {
  let targetMap = entries.get(target);
  if (!targetMap) {
    targetMap = new Map();
    entries.set(target, targetMap);
  }

  let entry = targetMap.get(key);

  if (!entry) {
    entry = {
      target,
      key,
      value: undefined,
      deps: new Set(),
      state: 1,
      checksum: 0,
    };
    targetMap.set(key, entry);
  }

  return entry;
}

function calculateChecksum({ state, deps }) {
  let checksum = state;
  deps.forEach((entry) => {
    if (!entry.checksum) {
      // eslint-disable-next-line no-unused-expressions
      entry.target[entry.key];
    }
    checksum += entry.state;
  });

  return checksum;
}

let context = null;
export function get(target, key, getter) {
  const entry = getEntry(target, key);

  if (context === entry) {
    context = null;
    throw Error(`[cache] Circular '${key}' get invocation in '${stringifyElement(target)}'`);
  }

  if (context) {
    context.deps.add(entry);
  }

  const parentContext = context;
  context = entry;

  if (entry.checksum && entry.checksum === calculateChecksum(entry)) {
    context = parentContext;
    return entry.value;
  }

  entry.deps.clear();

  try {
    const nextValue = getter(target, entry.value);

    if (nextValue !== entry.value) {
      entry.state += 1;
      entry.value = nextValue;
    }

    entry.checksum = calculateChecksum(entry);
    context = parentContext;
  } catch (e) {
    context = null;
    throw e;
  }

  return entry.value;
}

export function set(target, key, setter, value, callback) {
  if (context) {
    context = null;
    throw Error(`[cache] Try to set '${key}' of '${stringifyElement(target)}' in get call`);
  }

  const entry = getEntry(target, key);
  const newValue = setter(target, value, entry.value);

  if (newValue !== entry.value) {
    entry.state += 1;
    entry.value = newValue;

    callback();
  }
}

export function invalidate(target, key, clearValue) {
  if (context) {
    context = null;
    throw Error(`[cache] Try to invalidate '${key}' in '${stringifyElement(target)}' get call`);
  }

  const entry = getEntry(target, key);

  entry.checksum = 0;

  if (clearValue) {
    entry.value = undefined;
  }
}
{'fraction_non_alphanumeric': 0.1451117930732135, 'fraction_numerical': 0.0021920210434020165, 'mean_word_length': 2.9472318339100347, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '50803', 'n_tokens_mistral': 1531, 'n_tokens_neox': 1491, 'n_words': 392}