<commit_before>/* scala-stm - (c) 2009-2011, Stanford University, PPL */

package stmbench7.scalastm

import scala.collection.immutable.TreeMap
import scala.collection.JavaConversions
import scala.concurrent.stm._
import stmbench7.backend.Index

object IndexImpl {
  class BoxedImmutable[A <: Comparable[A], B] extends Index[A,B] {
    // needed for 2.8, harmless in 2.9
    implicit val order = new Ordering[A] {
      def compare(lhs: A, rhs: A) = lhs compareTo rhs
    }

    val underlying = Ref(TreeMap.empty[A,B]).single

    def get(key: A) = underlying().getOrElse(key, null.asInstanceOf[B])

    def put(key: A, value: B) { underlying.transform(_ + (key -> value)) }

    def putIfAbsent(key: A, value: B): B = {
      underlying.getAndTransform({ m => if (m.contains(key)) m else m + (key -> value) }).getOrElse(key, null.asInstanceOf[B])
    }

    def remove(key: A) = underlying transformIfDefined {
      case m if m.contains(key) => m - key
    }

    def iterator = JavaConversions.asIterator(underlying().valuesIterator)

    def getKeys = JavaConversions.asSet(underlying().keySet)

    def getRange(minKey: A, maxKey: A) = JavaConversions.asIterable(underlying().range(minKey, maxKey).values)
  }
}<commit_msg>custom TreeMap iterator to reduce GC load<commit_after>/* scala-stm - (c) 2009-2011, Stanford University, PPL */

package stmbench7.scalastm

import scala.annotation._
import scala.collection.immutable.{RedBlack, TreeMap}
import scala.collection.mutable.ArrayStack
import scala.collection.JavaConversions
import scala.concurrent.stm._
import stmbench7.backend.Index

object IndexImpl {
  class BoxedImmutable[A <: Comparable[A], B] extends Index[A,B] {
    // needed for 2.8, harmless in 2.9
    implicit val order = new Ordering[A] {
      def compare(lhs: A, rhs: A) = lhs compareTo rhs
    }

    val underlying = Ref(TreeMap.empty[A,B]).single

    def get(key: A) = underlying().getOrElse(key, null.asInstanceOf[B])

    def put(key: A, value: B) { underlying.transform(_ + (key -> value)) }

    def putIfAbsent(key: A, value: B): B = {
      underlying.getAndTransform({ m => if (m.contains(key)) m else m + (key -> value) }).getOrElse(key, null.asInstanceOf[B])
    }

    def remove(key: A) = underlying transformIfDefined {
      case m if m.contains(key) => m - key
    }

    def iterator = makeValuesIterator(underlying())

    def getKeys = JavaConversions.asSet(underlying().keySet)

    def getRange(minKey: A, maxKey: A) = new java.lang.Iterable[B] {
      val range = underlying().range(minKey, maxKey)
      def iterator = makeValuesIterator(range)
    }

    // <hack>We implement our own iterator because the Scala one generates
    // a large quantity of garbage.</hack>
    private def makeValuesIterator(m: TreeMap[A, B]) = {
      val root = treeMapTreeField.get(m).asInstanceOf[RedBlack[A]#Tree[B]]
      new java.util.Iterator[B] {
        val avail = ArrayStack.empty[RedBlack[A]#NonEmpty[B]] // ready to return
        pushAll(root)

        @tailrec final def pushAll(n: RedBlack[A]#Tree[B]) {
          n match {
            case ne: RedBlack[A]#NonEmpty[B] => {
              avail.push(ne)
              pushAll(ne.left)
            }
            case _ =>
          }
        }

        def hasNext = !avail.isEmpty

        def next(): B = {
          val n = avail.pop()
          pushAll(n.right)
          n.value
        }

        def remove() = throw new UnsupportedOperationException
      }
    }
  }

  private val treeMapTreeField = {
    val f = classOf[TreeMap[String, String]].getDeclaredField("tree")
    f.setAccessible(true)
    f
  }
}
{'fraction_non_alphanumeric': 0.1277654867256637, 'fraction_numerical': 0.007743362831858407, 'mean_word_length': 2.974725274725275, 'pattern_counts': {'":': 0, '<': 7, '<?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': '3011975', 'n_tokens_mistral': 1227, 'n_tokens_neox': 1180, 'n_words': 290}