Archivos por Etiqueta: dynamic

Java: Agnostic Cache with Dynamic Proxies and Reflection

Hace tiempo usé un modulo de Perl muy interesante, Memoize. La idea era muy sencilla, tienes una funcion X, si para una entrada A, hay una salida B constantes y ese cálculo es lento, puede usar un caché.

La idea es esa, calcular una vez, usar muchas; sin tener que tener una implementación con cache de cada implementación original.

Aquí está la implementación en Java usando Reflexión:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;

public class ReflectMemoizer implements InvocationHandler {
  private final Object object;
  private final HashMap<Method, ConcurrentHashMap<List<Object>, Object>> caches;

  /**
   * Memoize object
   * @param object source
   * @return proxied object
   */
  public static Object memoize(final Object object) 
        throws InstantiationException, IllegalAccessException {
    final Class<?> clazz = object.getClass();
    final ReflectMemoizer memoizer = new ReflectMemoizer(object);
    return Proxy.newProxyInstance(clazz.getClassLoader(), 
        clazz.getInterfaces(), memoizer);
  }

  private ReflectMemoizer(final Object object) {
    this.object = object;
    this.caches = new HashMap<Method, ConcurrentHashMap<List<Object>, Object>>();
  }

  public Object invoke(final Object proxy, final Method method, 
        final Object[] args) throws Throwable {
    if (method.getReturnType().equals(Void.TYPE)) {
      // Don't cache void methods
      return invoke(method, args);
    } else {
      final Map<List<Object>, Object> cache = getCache(method);
      final List<Object> key = Arrays.asList(args);
      Object value = cache.get(key);
      if ((value == null) && !cache.containsKey(key)) {
        value = invoke(method, args);
        cache.put(key, value);
      }
      return value;
    }
  }

  private synchronized Map<List<Object>, Object> getCache(final Method m) {
    ConcurrentHashMap<List<Object>, Object> cache = caches.get(m);
    if (cache == null) {
      cache = new ConcurrentHashMap<List<Object>, Object>();
      caches.put(m, cache);
    }
    return cache;
  }

  private Object invoke(final Method method, final Object[] args) 
        throws Throwable {
    try {
      return method.invoke(object, args);
    } catch (InvocationTargetException e) {
      throw e.getTargetException();
    }
  }
}

Leer más de esta entrada

Anuncios

Windows: Dynamic Port Range

Si tienes que hacer pruebas de carga (Windows Vista, 7 y Server 2008) esto puede serte de utilidad para aumentar el numero de puertos dinamicos disponibles:

netsh int ipv4 set dynamicport tcp start=10000 num=50000
netsh int ipv4 set dynamicport udp start=10000 num=50000
netsh int ipv6 set dynamicport tcp start=10000 num=50000
netsh int ipv6 set dynamicport udp start=10000 num=50000

* Con esto tendras disponibles los puertos entre el 10000 y el 60000

Normally, short-lived ports are allocated in the range from 1025 through 65535. The port range is now truly a range with a starting point and with an endpoint. The new default start port is 49152, and the default end port is 65535. This range is in addition to well-known ports that are used by services and by applications.

# The port range that is used by the server:

netsh int <ipv4|ipv6> show dynamicport <tcp|udp>

# You can adjust this range by using the netsh command as follows:

netsh int <ipv4|ipv6> set dynamicport <tcp|udp> start=number num=range

# The start port is number, and the total number of ports in range.

Si tienes un XP (el rango por defecto es 1025-5000), para cambiarlo (a 1025-19999) tendras que tocarlo en el registro:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]
“MaxUserPort”=dword:00004e1f

Referencias:
KB-929851: Dynamic port range for TCP/IP (Windows Vista, 7, Server 2008)

Java: Dynamic Compiling

Un ejemplo de uso del API de Compilacion de Java, en este caso generaremos una clase “HelloWorld” dinamicamente desde un String:

import java.net.URI;
import java.util.Arrays;

import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;

public class StringCompiler {
	public static final void compile(String className, String sourceCode, 
			String outputDir) {
		long ts = System.currentTimeMillis();
		SimpleJavaFileObject fileObject = new JavaSourceFromString(className, 
			sourceCode);
		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
		Iterable<? extends JavaFileObject> compilationUnits = Arrays
			.asList(fileObject);
		Iterable<String> compilationOptionss = Arrays.asList( //
				"-source", "1.6", // Source version
				"-target", "1.6", // Target version
				"-d", outputDir // Output Directory
				);
		DiagnosticCollector<JavaFileObject> diagnostics = new 
			DiagnosticCollector<JavaFileObject>();
		CompilationTask compilerTask = compiler.getTask(null, null, 
			diagnostics, compilationOptionss, null, compilationUnits);
		System.out.format("Compiling %s ", className);
		if (!compilerTask.call()) { // Error compiling
			for (Diagnostic<?> diagnostic : diagnostics.getDiagnostics()) {
				System.out.format("Error on line %d in %s ", 
					diagnostic.getLineNumber(), diagnostic);
			}
		}
		System.out.format("time=%d (ms)\n", (System.currentTimeMillis() - ts));
	}

	/**
	 * Simple HelloWorld Compilation
	 */
	public static void main(final String[] args) {
		final StringBuilder sb = new StringBuilder();
		final String tmpDir = System.getProperty("java.io.tmpdir");
		sb.append("package com.acme;").append('\n');
		sb.append("public class Test {").append('\n');
		sb.append("  public static void main(String[] args) {").append('\n');
		sb.append("    System.out.println(\"hello world\");").append('\n');
		sb.append("  }").append('\n');
		sb.append("}").append('\n');
		compile("com.acme.Test", sb.toString(), tmpDir);
	}

	public static class JavaSourceFromString extends SimpleJavaFileObject {
		final String code;

		JavaSourceFromString(final String name, final String code) {
			super(URI.create("string:///" + name.replace('.', '/') + 
				Kind.SOURCE.extension), Kind.SOURCE);
			this.code = code;
		}

		@Override
		public CharSequence getCharContent(boolean ignoreEncodingErrors) {
			return code;
		}
	}
}

Fuentes:
javax.tools.JavaCompiler

Alternativas:
Apache Commons JCI || Sample
Janino || Sample
Eclipse Compiler for Java || Sample

A %d blogueros les gusta esto: