SharedObject.java revision 836e6b40a94ec3fb7545a76cb072960442b7eee9
12ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* GENERATED SOURCE. DO NOT MODIFY. */ 22ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* 32ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller******************************************************************************* 42ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* Copyright (C) 2013-2014, International Business Machines 52ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* Corporation and others. All Rights Reserved. 62ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller******************************************************************************* 72ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* SharedObject.java, ported from sharedobject.h/.cpp 82ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* 92ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* C++ version created on: 2013dec19 102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* created by: Markus W. Scherer 112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller*/ 122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpackage android.icu.impl.coll; 142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.concurrent.atomic.AtomicInteger; 162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.ICUCloneNotSupportedException; 182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/** 202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Base class for shared, reference-counted, auto-deleted objects. 212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Java subclasses are mutable and must implement clone(). 222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>In C++, the SharedObject base class is used for both memory and ownership management. 242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * In Java, memory management (deletion after last reference is gone) 252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * is up to the garbage collector, 262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * but the reference counter is still used to see whether the referent is the sole owner. 272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>Usage: 292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <pre> 302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * class S extends SharedObject { 312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * public clone() { ... } 322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * } 332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // Either use the nest class Reference (which costs an extra allocation), 352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // or duplicate its code in the class that uses S 362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // (which duplicates code and is more error-prone). 372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * class U { 382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // For read-only access, use s.readOnly(). 392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // For writable access, use S ownedS = s.copyOnWrite(); 402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * private SharedObject.Reference<S> s; 412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // Returns a writable version of s. 422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // If there is exactly one owner, then s itself is returned. 432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // If there are multiple owners, then s is replaced with a clone, 442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // and that is returned. 452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * private S getOwnedS() { 462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * return s.copyOnWrite(); 472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * } 482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * public U clone() { 492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * ... 502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * c.s = s.clone(); 512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * ... 522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * } 532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * } 542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * class V { 562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // For read-only access, use s directly. 572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // For writable access, use S ownedS = getOwnedS(); 582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * private S s; 592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // Returns a writable version of s. 602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // If there is exactly one owner, then s itself is returned. 612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // If there are multiple owners, then s is replaced with a clone, 622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // and that is returned. 632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * private S getOwnedS() { 642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * if(s.getRefCount() > 1) { 652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * S ownedS = s.clone(); 662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * s.removeRef(); 672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * s = ownedS; 682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * ownedS.addRef(); 692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * } 702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * return s; 712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * } 722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * public U clone() { 732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * ... 742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * s.addRef(); 752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * ... 762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * } 772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * protected void finalize() { 782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * ... 792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * if(s != null) { 802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * s.removeRef(); 812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * s = null; 822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * } 832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * ... 842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * } 852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * } 862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </pre> 872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Either use only Java memory management, or use addRef()/removeRef(). 892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Sharing requires reference-counting. 902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * TODO: Consider making this more widely available inside ICU, 922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * or else adopting a different model. 93836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide Only a subset of ICU is exposed in Android 94704056c96cc5de08c2425fa1679a5c0a92c5a88eNeil Fuller * @hide All android.icu classes are currently hidden 952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpublic class SharedObject implements Cloneable { 972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Similar to a smart pointer, basically a port of the static methods of C++ SharedObject. 992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static final class Reference<T extends SharedObject> implements Cloneable { 1012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private T ref; 1022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Reference(T r) { 1042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ref = r; 1052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(r != null) { 1062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r.addRef(); 1072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @SuppressWarnings("unchecked") 1112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @Override 1122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Reference<T> clone() { 1132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Reference<T> c; 1142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller try { 1152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller c = (Reference<T>)super.clone(); 1162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } catch (CloneNotSupportedException e) { 1172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Should never happen. 1182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new ICUCloneNotSupportedException(e); 1192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(ref != null) { 1212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ref.addRef(); 1222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return c; 1242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public T readOnly() { return ref; } 1272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns a writable version of the reference. 1302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If there is exactly one owner, then the reference itself is returned. 1312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If there are multiple owners, then the reference is replaced with a clone, 1322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * and that is returned. 1332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public T copyOnWrite() { 1352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller T r = ref; 1362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(r.getRefCount() <= 1) { return r; } 1372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @SuppressWarnings("unchecked") 1382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller T r2 = (T)r.clone(); 1392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r.removeRef(); 1402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ref = r2; 1412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller r2.addRef(); 1422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return r2; 1432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void clear() { 1462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(ref != null) { 1472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ref.removeRef(); 1482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ref = null; 1492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @Override 1532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected void finalize() throws Throwable { 1542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller super.finalize(); 1552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller clear(); 1562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** Initializes refCount to 0. */ 1602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public SharedObject() {} 1612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** Initializes refCount to 0. */ 1632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @Override 1642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public SharedObject clone() { 1652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller SharedObject c; 1662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller try { 1672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller c = (SharedObject)super.clone(); 1682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } catch (CloneNotSupportedException e) { 1692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Should never happen. 1702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new ICUCloneNotSupportedException(e); 1712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller c.refCount = new AtomicInteger(); 1732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return c; 1742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Increments the number of references to this object. Thread-safe. 1782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final void addRef() { refCount.incrementAndGet(); } 1802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Decrements the number of references to this object, 1822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * and auto-deletes "this" if the number becomes 0. Thread-safe. 1832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final void removeRef() { 1852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Deletion in Java is up to the garbage collector. 1862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller refCount.decrementAndGet(); 1872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the reference counter. Uses a memory barrier. 1912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final int getRefCount() { return refCount.get(); } 1932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final void deleteIfZeroRefCount() { 1952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Deletion in Java is up to the garbage collector. 1962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private AtomicInteger refCount = new AtomicInteger(); 1992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller} 200