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 the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Scala tags/keywords

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

The Scala MethodCache.scala source code

/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2002-2011, LAMP/EPFL             **
**  __\ \/ /__/ __ |/ /__/ __ |    http:///               **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
\*                                                                      */



package scala.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 */
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
}

final class EmptyMethodCache extends MethodCache {

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

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
  
}

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 examples (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.