alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Scala example source code file (MethodCache.scala)

This example Scala source code file (MethodCache.scala) is included in my "Source Code Warehouse" project. The intent of this project is to help you more easily find Scala source code examples by using tags.

All credit for the original source code belongs to scala-lang.org; I'm just trying to make examples easier to find. (For my Scala work, see my Scala examples and tutorials.)

Scala tags/keywords

annotation, array, emptymethodcache, int, jclass, jmethod, maxcomplexity, megamethodcache, methodcache, polymethodcache, string

The MethodCache.scala Scala example source code

/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2002-2013, LAMP/EPFL             **
**  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
\*                                                                      */

package scala
package runtime


import java.lang.reflect.{ Method => JMethod }
import java.lang.{ Class => JClass }

import scala.annotation.tailrec

/** An element of a polymorphic object cache.
 *  This class is refered to by the `CleanUp` phase. Each `PolyMethodCache` chain
 *  must only relate to one method as `PolyMethodCache` does not identify
 *  the method name and argument types. In practice, one variable will be
 *  generated per call point, and will uniquely relate to the method called
 *  at that point, making the method name and argument types irrelevant. */
/* TODO: if performance is acceptable, PolyMethodCache should be made generic on the method type */
private[scala] sealed abstract class MethodCache {
  /** Searches for a cached method in the `MethodCache` chain that
   *  is compatible with receiver class `forReceiver`. If none is cached,
   *  `null` is returned. If `null` is returned, find's caller should look-
   *  up the right method using whichever means it prefers, and add it to
   *  the cache for later use. */
  def find(forReceiver: JClass[_]): JMethod
  def add(forReceiver: JClass[_], forMethod: JMethod): MethodCache
}

private[scala] final class EmptyMethodCache extends MethodCache {

  def find(forReceiver: JClass[_]): JMethod = null

  def add(forReceiver: JClass[_], forMethod: JMethod): MethodCache =
    new PolyMethodCache(this, forReceiver, forMethod, 1)

}

private[scala] final class MegaMethodCache(
  private[this] val forName: String,
  private[this] val forParameterTypes: Array[JClass[_]]
) extends MethodCache {

  def find(forReceiver: JClass[_]): JMethod =
    forReceiver.getMethod(forName, forParameterTypes:_*)

  def add(forReceiver: JClass[_], forMethod: JMethod): MethodCache = this

}

private[scala] final class PolyMethodCache(
  private[this] val next: MethodCache,
  private[this] val receiver: JClass[_],
  private[this] val method: JMethod,
  private[this] val complexity: Int
) extends MethodCache {

  /** To achieve tail recursion this must be a separate method
   *  from `find`, because the type of next is not `PolyMethodCache`.
   */
  @tailrec private def findInternal(forReceiver: JClass[_]): JMethod =
    if (forReceiver eq receiver) method
    else next match {
      case x: PolyMethodCache => x findInternal forReceiver
      case _                  => next find forReceiver
    }

  def find(forReceiver: JClass[_]): JMethod = findInternal(forReceiver)

  // TODO: come up with a more realistic number
  final private val MaxComplexity = 160

  def add(forReceiver: JClass[_], forMethod: JMethod): MethodCache =
    if (complexity < MaxComplexity)
      new PolyMethodCache(this, forReceiver, forMethod, complexity + 1)
    else
      new MegaMethodCache(forMethod.getName, forMethod.getParameterTypes)
}

Other Scala source code examples

Here is a short list of links related to this Scala MethodCache.scala source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.