<commit_before>package org.neo4j.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;

import org.neo4j.api.core.Direction;
import org.neo4j.api.core.NeoService;
import org.neo4j.api.core.Node;
import org.neo4j.api.core.Relationship;
import org.neo4j.api.core.Transaction;
import org.neo4j.util.btree.BTree.RelTypes;
import org.neo4j.util.sortedtree.SortedTree;

public class IndexedNeoCollection<T extends NodeWrapper>
	extends AbstractNeoSet<T>
{
	private NeoService neo;
	private Node rootNode;
	private Class<T> instanceClass;
	private Comparator<T> comparator;
	private SortedTree index;
	
	public IndexedNeoCollection( NeoService neo, Node rootNode,
		Comparator<T> comparator, Class<T> instanceClass )
	{
		this.neo = neo;
		this.rootNode = rootNode;
		this.instanceClass = instanceClass;
		this.comparator = comparator;
		instantiateIndex();
	}
	
	private Node ensureTheresARoot()
	{
		Transaction tx = neo().beginTx();
		try
		{
			Node result = null;
			Relationship relationship = rootNode.getSingleRelationship(
				RelTypes.TREE_ROOT, Direction.OUTGOING );
			if ( relationship != null )
			{
				result = relationship.getOtherNode( rootNode );
			}
			else
			{
				result = neo.createNode();
				rootNode.createRelationshipTo( result, RelTypes.TREE_ROOT );
			}
			tx.success();
			return result;
		}
		finally
		{
			tx.finish();
		}
	}
	
	private void instantiateIndex()
	{
		Transaction tx = neo().beginTx();
		try
		{
			Node treeRootNode = ensureTheresARoot();
			this.index = new SortedTree( neo(), treeRootNode,
				new ComparatorWrapper( this.comparator ) );
			tx.success();
		}
		finally
		{
			tx.finish();
		}
	}
	
	protected NeoService neo()
	{
		return this.neo;
	}
	
	protected Node rootNode()
	{
		return this.rootNode;
	}
	
	protected SortedTree index()
	{
		return this.index;
	}
	
	protected T instantiateItem( Node itemNode )
	{
		return NodeWrapperImpl.newInstance( instanceClass, itemNode );
	}
	
	public boolean add( T item )
	{
		return index().addNode( item.getUnderlyingNode() );
	}

	public void clear()
	{
		Transaction tx = neo().beginTx();
		try
		{
			index().delete();
			instantiateIndex();
			tx.success();
		}
		finally
		{
			tx.finish();
		}
	}

	public boolean contains( Object item )
	{
		T nodeItem = ( T ) item;
		return index().containsNode( nodeItem.getUnderlyingNode() );
	}

	public boolean isEmpty()
	{
		return index().getSortedNodes().iterator().hasNext();
	}

	public Iterator<T> iterator()
	{
		Iterator<T> iterator = new IterableWrapper<T, Node>(
			index().getSortedNodes() )
		{
			@Override
			protected T underlyingObjectToObject( Node node )
			{
				return instantiateItem( node );
			}
		}.iterator();
		return new TxIterator<T>( neo(), iterator );
	}

	public boolean remove( Object item )
	{
		T nodeItem = ( T ) item;
		return index().removeNode( nodeItem.getUnderlyingNode() );
	}

	public boolean retainAll( Collection<?> items )
	{
		throw new UnsupportedOperationException( "Not implemented yet" );
	}

	public int size()
	{
		return toArray().length;
	}
	
	private <R> Collection<R> toCollection()
	{
		Transaction tx = neo().beginTx();
		try
		{
			Collection<R> result = new ArrayList<R>();
			for ( Node node : index().getSortedNodes() )
			{
				result.add( ( R ) instantiateItem( node ) );
			}
			tx.success();
			return result;
		}
		finally
		{
			tx.finish();
		}
	}

	public Object[] toArray()
	{
		return toCollection().toArray();
	}

	public <R> R[] toArray( R[] array )
	{
		return toCollection().toArray( array );
	}
	
	public void delete()
	{
		Transaction tx = neo().beginTx();
		try
		{
			index().delete();<commit_msg>Added javadoc for the delete method<commit_after>package org.neo4j.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;

import org.neo4j.api.core.Direction;
import org.neo4j.api.core.NeoService;
import org.neo4j.api.core.Node;
import org.neo4j.api.core.Relationship;
import org.neo4j.api.core.Transaction;
import org.neo4j.util.btree.BTree.RelTypes;
import org.neo4j.util.sortedtree.SortedTree;

public class IndexedNeoCollection<T extends NodeWrapper>
	extends AbstractNeoSet<T>
{
	private NeoService neo;
	private Node rootNode;
	private Class<T> instanceClass;
	private Comparator<T> comparator;
	private SortedTree index;
	
	public IndexedNeoCollection( NeoService neo, Node rootNode,
		Comparator<T> comparator, Class<T> instanceClass )
	{
		this.neo = neo;
		this.rootNode = rootNode;
		this.instanceClass = instanceClass;
		this.comparator = comparator;
		instantiateIndex();
	}
	
	private Node ensureTheresARoot()
	{
		Transaction tx = neo().beginTx();
		try
		{
			Node result = null;
			Relationship relationship = rootNode.getSingleRelationship(
				RelTypes.TREE_ROOT, Direction.OUTGOING );
			if ( relationship != null )
			{
				result = relationship.getOtherNode( rootNode );
			}
			else
			{
				result = neo.createNode();
				rootNode.createRelationshipTo( result, RelTypes.TREE_ROOT );
			}
			tx.success();
			return result;
		}
		finally
		{
			tx.finish();
		}
	}
	
	private void instantiateIndex()
	{
		Transaction tx = neo().beginTx();
		try
		{
			Node treeRootNode = ensureTheresARoot();
			this.index = new SortedTree( neo(), treeRootNode,
				new ComparatorWrapper( this.comparator ) );
			tx.success();
		}
		finally
		{
			tx.finish();
		}
	}
	
	protected NeoService neo()
	{
		return this.neo;
	}
	
	protected Node rootNode()
	{
		return this.rootNode;
	}
	
	protected SortedTree index()
	{
		return this.index;
	}
	
	protected T instantiateItem( Node itemNode )
	{
		return NodeWrapperImpl.newInstance( instanceClass, itemNode );
	}
	
	public boolean add( T item )
	{
		return index().addNode( item.getUnderlyingNode() );
	}

	public void clear()
	{
		Transaction tx = neo().beginTx();
		try
		{
			index().delete();
			instantiateIndex();
			tx.success();
		}
		finally
		{
			tx.finish();
		}
	}

	public boolean contains( Object item )
	{
		T nodeItem = ( T ) item;
		return index().containsNode( nodeItem.getUnderlyingNode() );
	}

	public boolean isEmpty()
	{
		return index().getSortedNodes().iterator().hasNext();
	}

	public Iterator<T> iterator()
	{
		Iterator<T> iterator = new IterableWrapper<T, Node>(
			index().getSortedNodes() )
		{
			@Override
			protected T underlyingObjectToObject( Node node )
			{
				return instantiateItem( node );
			}
		}.iterator();
		return new TxIterator<T>( neo(), iterator );
	}

	public boolean remove( Object item )
	{
		T nodeItem = ( T ) item;
		return index().removeNode( nodeItem.getUnderlyingNode() );
	}

	public boolean retainAll( Collection<?> items )
	{
		throw new UnsupportedOperationException( "Not implemented yet" );
	}

	public int size()
	{
		return toArray().length;
	}
	
	private <R> Collection<R> toCollection()
	{
		Transaction tx = neo().beginTx();
		try
		{
			Collection<R> result = new ArrayList<R>();
			for ( Node node : index().getSortedNodes() )
			{
				result.add( ( R ) instantiateItem( node ) );
			}
			tx.success();
			return result;
		}
		finally
		{
			tx.finish();
		}
	}

	public Object[] toArray()
	{
		return toCollection().toArray();
	}

	public <R> R[] toArray( R[] array )
	{
		return toCollection().toArray( array );
	}
	
	/**
	 * Since this collection creates a sub-root to the supplied collection
	 * root node, it will have to be explicitly deleted from outside when
	 * you don't want this collection to exist anymore.
	 */
	public void delete()
	{
		Transaction tx = neo().beginTx();
		try
		{
			index().delete();
{'fraction_non_alphanumeric': 0.12611901000526593, 'fraction_numerical': 0.00210637177461822, 'mean_word_length': 3.532816229116945, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 35, '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': '3745797', 'n_tokens_mistral': 2906, 'n_tokens_neox': 2522, 'n_words': 590}