<commit_before>package de.lmu.ifi.dbs.elki.database;

import de.lmu.ifi.dbs.elki.data.DatabaseObject;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
import de.lmu.ifi.dbs.elki.utilities.ExceptionMessages;
import de.lmu.ifi.dbs.elki.utilities.UnableToComplyException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizable;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

/**
 * Provides a mapping for associations based on a Hashtable and functions to get
 * the next usable ID for insertion, making IDs reusable after deletion of the
 * entry.
 * 
 * @author <NAME>
 * @param <O> the type of DatabaseObject as element of the database
 */
public abstract class AbstractDatabase<O extends DatabaseObject> extends AbstractParameterizable implements Database<O> {
  /**
   * Map to hold global associations.
   */
  private final Associations globalAssociations;

  /**
   * Map to hold association maps.
   */
  private final AssociationMaps associations;

  /**
   * Counter to provide a new Integer id.
   */
  private int counter;

  /**
   * Provides a list of reusable ids.
   */
  private List<Integer> reusableIDs;

  /**
   * Map to hold the objects of the database.
   */
  private Map<Integer, O> content;

  /**
   * Holds the listener of this database.
   */
  protected List<DatabaseListener> listenerList = new ArrayList<DatabaseListener>();

  /**
   * Provides an abstract database including a mapping for associations based on
   * a Hashtable and functions to get the next usable ID for insertion, making
   * IDs reusable after deletion of the entry. Make sure to delete any
   * associations when deleting an entry (e.g. by calling
   * {@link #deleteAssociations(Integer) deleteAssociations(id)}).
   */
  protected AbstractDatabase() {
    super();
    content = new Hashtable<Integer, O>();
    associations = new AssociationMaps();
    globalAssociations = new Associations();
    counter = 0;
    reusableIDs = new ArrayList<Integer>();
  }

  public void insert(List<Pair<O, Associations>> objectsAndAssociationsList) throws UnableToComplyException {
    for(Pair<O, Associations> objectAndAssociations : objectsAndAssociationsList) {
      insert(objectAndAssociations);
    }
  }

  /**
   * @throws UnableToComplyException if database reached limit of storage
   *         capacity
   */
  public Integer insert(Pair<O, Associations> objectAndAssociations) throws UnableToComplyException {
    O object = objectAndAssociations.getFirst();
    // insert object
    Integer id = setNewID(object);
    content.put(id, object);
    // insert associations
    Associations associations = objectAndAssociations.getSecond();
    setAssociations(id, associations);
    // notify listeners
    fireObjectInserted(id);

    return id;
  }

  public void delete(O object) {
    for(Integer id : content.keySet()) {
      if(content.get(id).equals(object)) {
        delete(id);
      }
    }
  }

  public O delete(Integer id) {
    O object = content.remove(id);
    restoreID(id);
    deleteAssociations(id);
    // notify listeners
    fireObjectRemoved(id);

    return object;
  }

  public final int size() {
    return content.size();
  }

  public final O get(Integer id) {
    return content.get(id);
  }

  /**
   * Returns an iterator iterating over all keys of the database.
   * 
   * @return an iterator iterating over all keys of the database
   */
  public final Iterator<Integer> iterator() {
    return content.keySet().iterator();
  }

  public <T> void associate(final AssociationID<T> associationID, final Integer objectID, final T association) {
    try {
      associationID.getType().cast(association);<commit_msg>Rethrow exception in a more helpful manner when Database.get(null) was called.<commit_after>package de.lmu.ifi.dbs.elki.database;

import de.lmu.ifi.dbs.elki.data.DatabaseObject;
import de.lmu.ifi.dbs.elki.data.NumberVector;
import de.lmu.ifi.dbs.elki.utilities.ClassGenericsUtil;
import de.lmu.ifi.dbs.elki.utilities.ExceptionMessages;
import de.lmu.ifi.dbs.elki.utilities.UnableToComplyException;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizable;
import de.lmu.ifi.dbs.elki.utilities.optionhandling.ParameterException;
import de.lmu.ifi.dbs.elki.utilities.pairs.Pair;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

/**
 * Provides a mapping for associations based on a Hashtable and functions to get
 * the next usable ID for insertion, making IDs reusable after deletion of the
 * entry.
 * 
 * @author <NAME>
 * @param <O> the type of DatabaseObject as element of the database
 */
public abstract class AbstractDatabase<O extends DatabaseObject> extends AbstractParameterizable implements Database<O> {
  /**
   * Map to hold global associations.
   */
  private final Associations globalAssociations;

  /**
   * Map to hold association maps.
   */
  private final AssociationMaps associations;

  /**
   * Counter to provide a new Integer id.
   */
  private int counter;

  /**
   * Provides a list of reusable ids.
   */
  private List<Integer> reusableIDs;

  /**
   * Map to hold the objects of the database.
   */
  private Map<Integer, O> content;

  /**
   * Holds the listener of this database.
   */
  protected List<DatabaseListener> listenerList = new ArrayList<DatabaseListener>();

  /**
   * Provides an abstract database including a mapping for associations based on
   * a Hashtable and functions to get the next usable ID for insertion, making
   * IDs reusable after deletion of the entry. Make sure to delete any
   * associations when deleting an entry (e.g. by calling
   * {@link #deleteAssociations(Integer) deleteAssociations(id)}).
   */
  protected AbstractDatabase() {
    super();
    content = new Hashtable<Integer, O>();
    associations = new AssociationMaps();
    globalAssociations = new Associations();
    counter = 0;
    reusableIDs = new ArrayList<Integer>();
  }

  public void insert(List<Pair<O, Associations>> objectsAndAssociationsList) throws UnableToComplyException {
    for(Pair<O, Associations> objectAndAssociations : objectsAndAssociationsList) {
      insert(objectAndAssociations);
    }
  }

  /**
   * @throws UnableToComplyException if database reached limit of storage
   *         capacity
   */
  public Integer insert(Pair<O, Associations> objectAndAssociations) throws UnableToComplyException {
    O object = objectAndAssociations.getFirst();
    // insert object
    Integer id = setNewID(object);
    content.put(id, object);
    // insert associations
    Associations associations = objectAndAssociations.getSecond();
    setAssociations(id, associations);
    // notify listeners
    fireObjectInserted(id);

    return id;
  }

  public void delete(O object) {
    for(Integer id : content.keySet()) {
      if(content.get(id).equals(object)) {
        delete(id);
      }
    }
  }

  public O delete(Integer id) {
    O object = content.remove(id);
    restoreID(id);
    deleteAssociations(id);
    // notify listeners
    fireObjectRemoved(id);

    return object;
  }

  public final int size() {
    return content.size();
  }

  public final O get(Integer id) {
    try {
      return content.get(id);
    } catch (RuntimeException e) {
      if (id == null) {
        throw new UnsupportedOperationException("AbstractDatabase.get(null) called!");
      }
      // throw e upwards.
      throw e;
    }
  }

  /**
   * Returns an iterator iterating over all keys of the database.
   * 
   * @return an iterator iterating over all keys of the database
   */
  public final Iterator<Integer> iterator() {
    return content.keySet().iterator();
  }

  public <T> void associate(final AssociationID<T> associationID, final Integer objectID, final T association) {
    try {
      associationID.getType().cast(association);
{'fraction_non_alphanumeric': 0.10033565092304003, 'fraction_numerical': 0.0002397506593143131, 'mean_word_length': 3.551554828150573, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 37, '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': '412272', 'n_tokens_mistral': 2474, 'n_tokens_neox': 2402, 'n_words': 699}