/** * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.waveprotocol.wave.client.common.util; import org.waveprotocol.wave.model.util.ReadableNumberMap.ProcV; import java.util.HashMap; import java.util.Map; /** * A super fast and memory efficient map (directly uses a js object as the map, * and requires only 1 object). Only allows double keys, thus taking advantage * of the "perfect hashing" of doubles with respect to javascript. * * NOTE(danilatos): Does not use hasOwnProperty semantics. So it's possible for * spurious entries to appear in the map if we're not careful. Easily fixable, * but would incur a slight performance hit (I'm now just handwaving). * * TODO(dan): Use a different version from the GWT team once it is available * * @author danilatos@google.com (Daniel Danilatos) * @param <T> Type of values in the map. Keys are always doubles. * * @deprecated use {@link org.waveprotocol.wave.model.util.NumberMap} or * {@link JsoView} instead, depending on use case */ @Deprecated public final class NumberMapJsoView<T> extends JsoMapBase { /** * A function that accepts an accumulated value, a key and the corresponding * item from the map and returns the new accumulated value. * * @see NumberMapJsoView#reduce(Object, NumberMapJsoView.Reduce) * @param <E> * double map's type parameter * @param <R> * The type of the value being accumulated */ public interface Reduce<E, R> { /** The function */ public R apply(R soFar, double key, E item); } /** Construct an empty NumberMap */ public static native <T> NumberMapJsoView<T> create() /*-{ return {}; }-*/; /** Construct a NumberMap from a java Map */ public static <T> NumberMapJsoView<T> fromMap(Map<Double, T> map) { NumberMapJsoView<T> doubleMap = create(); for (double key : map.keySet()) { doubleMap.put(key, map.get(key)); } return doubleMap; } protected NumberMapJsoView() { } /** * @param key * @return true if a value indexed by the given key is in the map */ public native boolean has(double key) /*-{ return this[key] !== undefined; }-*/; /** * @param key * @return The value with the given key, or null if not present */ public native T get(double key) /*-{ return this[key]; }-*/; /** * Put the value in the map at the given key. Note: Does not return the old * value. * * @param key * @param value */ public native void put(double key, T value) /*-{ this[key] = value; }-*/; /** * Remove the value with the given key from the map. Note: does not return the * old value. * * @param key */ public native void remove(double key) /*-{ delete this[key]; }-*/; /** * Same as {@link #remove(double)}, but returns what was previously there, if * anything. * * @param key * @return what was previously there or null */ public final T removeAndReturn(double key) { T val = get(key); remove(key); return val; } /** * Ruby/prototype.js style iterating idiom, using a callbak. Equivalent to a * for-each loop. TODO(danilatos): Implement break and through a la * prototype.js if needed. * * @param proc */ public final native void each(ProcV<? super T> proc) /*-{ for (var k in this) { proc. @org.waveprotocol.wave.model.util.ReadableNumberMap.ProcV::apply(DLjava/lang/Object;) (parseFloat(k), this[k]); } }-*/; /** * Same as ruby/prototype reduce. Same as functional foldl. Apply a function * to an accumulator and key/value in the map. The function returns the new * accumulated value. TODO(danilatos): Implement break and through a la * prototype.js if needed. * * @param initial * @param proc * @return The accumulated value * @param <R> * The accumulating type */ public final native <R> R reduce(R initial, Reduce<T, R> proc) /*-{ var reduction = initial; for (var k in this) { reduction = proc. @org.waveprotocol.wave.client.common.util.NumberMapJsoView.Reduce::apply(Ljava/lang/Object;DLjava/lang/Object;) (reduction, parseFloat(k), this[k]); } return reduction; }-*/; /** * Convert to a java Map */ public final Map<Double, T> toMap() { return addToMap(new HashMap<Double, T>()); } /** * Add all values to a java map. * * @param map * The map to add values to * @return The same map, for convenience. */ public final Map<Double, T> addToMap(final Map<Double, T> map) { each(new ProcV<T>() { public void apply(double key, T item) { map.put(key, item); } }); return map; } /** * Add all values to a NumberMap. * * @param map * The map to add values to * @return The same map, for convenience. */ public final NumberMapJsoView<T> addToMap(final NumberMapJsoView<T> map) { each(new ProcV<T>() { public void apply(double key, T item) { map.put(key, item); } }); return map; } }