Home | History | Annotate | Download | only in data
      1 /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
      2  *
      3  * This program and the accompanying materials are made available under
      4  * the terms of the Common Public License v1.0 which accompanies this distribution,
      5  * and is available at http://www.eclipse.org/legal/cpl-v10.html
      6  *
      7  * $Id: CoverageData.java,v 1.1.1.1 2004/05/09 16:57:31 vlad_r Exp $
      8  */
      9 package com.vladium.emma.data;
     10 
     11 import java.io.DataInput;
     12 import java.io.DataOutput;
     13 import java.io.IOException;
     14 import java.util.HashMap;
     15 import java.util.Iterator;
     16 import java.util.Map;
     17 
     18 import com.vladium.util.asserts.$assert;
     19 
     20 // ----------------------------------------------------------------------------
     21 /**
     22  * @author Vlad Roubtsov, (C) 2003
     23  */
     24 final class CoverageData implements ICoverageData, Cloneable
     25 {
     26     // public: ................................................................
     27 
     28     // TODO: duplicate issue
     29 
     30     public Object lock ()
     31     {
     32         return m_coverageMap;
     33     }
     34 
     35     public ICoverageData shallowCopy ()
     36     {
     37         final CoverageData _clone;
     38         try
     39         {
     40             _clone = (CoverageData) super.clone ();
     41         }
     42         catch (CloneNotSupportedException cnse)
     43         {
     44             throw new Error (cnse.toString ());
     45         }
     46 
     47         final HashMap _coverageMap;
     48 
     49         synchronized (lock ())
     50         {
     51             _coverageMap = (HashMap) m_coverageMap.clone ();
     52         }
     53 
     54         _clone.m_coverageMap = _coverageMap;
     55 
     56         return _clone;
     57     }
     58 
     59     public int size ()
     60     {
     61         return m_coverageMap.size ();
     62     }
     63 
     64     public DataHolder getCoverage (final ClassDescriptor cls)
     65     {
     66         if (cls == null) throw new IllegalArgumentException ("null input: cls");
     67 
     68         return (DataHolder) m_coverageMap.get (cls.getClassVMName ());
     69     }
     70 
     71     public void addClass (final boolean [][] coverage, final String classVMName, final long stamp)
     72     {
     73         m_coverageMap.put (classVMName, new DataHolder (coverage, stamp));
     74     }
     75 
     76     // IMergeable:
     77 
     78     public boolean isEmpty ()
     79     {
     80         return m_coverageMap.isEmpty ();
     81     }
     82 
     83     /*
     84      * This method is not MT-safe wrt addClass() etc.
     85      *
     86      * note: rhs entries override current entries if they have different stamps;
     87      * otherwise, the data is merged
     88      */
     89     public IMergeable merge (final IMergeable rhs)
     90     {
     91         if ((rhs == null) || rhs.isEmpty () || (rhs == this))
     92             return this;
     93         else
     94         {
     95             final CoverageData rhscdata = (CoverageData) rhs; // TODO: redesign so that the cast is not necessary
     96             final Map rhscoverageData = rhscdata.m_coverageMap;
     97 
     98             for (Iterator entries = rhscoverageData.entrySet ().iterator (); entries.hasNext (); )
     99             {
    100                 final Map.Entry entry = (Map.Entry) entries.next ();
    101                 final String classVMName = (String) entry.getKey ();
    102 
    103                 final DataHolder rhsdata = (DataHolder) entry.getValue ();
    104                 // [assertion: rhsdata != null]
    105 
    106                 final DataHolder data = (DataHolder) m_coverageMap.get (classVMName);
    107 
    108                 if (data == null)
    109                     m_coverageMap.put (classVMName, rhsdata);
    110                 else
    111                 {
    112                     if (rhsdata.m_stamp != data.m_stamp)
    113                         m_coverageMap.put (classVMName, rhsdata);
    114                     else // merge two runtime profiles
    115                     {
    116                         final boolean [][] rhscoverage = rhsdata.m_coverage;
    117                         final boolean [][] coverage = data.m_coverage;
    118 
    119                         // [assertion: both coverage and rhscoverage aren't null]
    120 
    121                         if ($assert.ENABLED) $assert.ASSERT (coverage.length == rhscoverage.length, "coverage.length [" + coverage.length + "] != rhscoverage.length [" + rhscoverage.length + "]");
    122                         for (int m = 0, mLimit = coverage.length; m < mLimit; ++ m)
    123                         {
    124                             final boolean [] rhsmcoverage = rhscoverage [m];
    125                             final boolean [] mcoverage = coverage [m];
    126 
    127                             if (mcoverage == null)
    128                             {
    129                                 if ($assert.ENABLED) $assert.ASSERT (rhsmcoverage == null, "mcoverage == null but rhsmcoverage != null");
    130 
    131                                 // [nothing to merge]
    132                             }
    133                             else
    134                             {
    135                                 if ($assert.ENABLED) $assert.ASSERT (rhsmcoverage != null, "mcoverage != null but rhsmcoverage == null");
    136                                 if ($assert.ENABLED) $assert.ASSERT (mcoverage.length == rhsmcoverage.length, "mcoverage.length [" + mcoverage.length + "] != rhsmcoverage.length [" + rhsmcoverage.length + "]");
    137 
    138                                 for (int b = 0, bLimit = mcoverage.length; b < bLimit; ++ b)
    139                                 {
    140                                     if (rhsmcoverage [b]) mcoverage [b] = true;
    141                                 }
    142                             }
    143                         }
    144                     }
    145                 }
    146             }
    147 
    148             return this;
    149         }
    150     }
    151 
    152     // protected: .............................................................
    153 
    154     // package: ...............................................................
    155 
    156 
    157     CoverageData ()
    158     {
    159         m_coverageMap = new HashMap ();
    160     }
    161 
    162 
    163     static CoverageData readExternal (final DataInput in)
    164         throws IOException
    165     {
    166         final int size = in.readInt ();
    167         final HashMap coverageMap = new HashMap (size);
    168 
    169         for (int i = 0; i < size; ++ i)
    170         {
    171             final String classVMName = in.readUTF ();
    172             final long stamp = in.readLong ();
    173 
    174             final int length = in.readInt ();
    175             final boolean [][] coverage = new boolean [length][];
    176             for (int c = 0; c < length; ++ c)
    177             {
    178                 coverage [c] = DataFactory.readBooleanArray (in);
    179             }
    180 
    181             coverageMap.put (classVMName, new DataHolder (coverage, stamp));
    182         }
    183 
    184         return new CoverageData (coverageMap);
    185     }
    186 
    187     static void writeExternal (final CoverageData cdata, final DataOutput out)
    188         throws IOException
    189     {
    190         final Map coverageMap = cdata.m_coverageMap;
    191 
    192         final int size = coverageMap.size ();
    193         out.writeInt (size);
    194 
    195         final Iterator entries = coverageMap.entrySet ().iterator ();
    196         for (int i = 0; i < size; ++ i)
    197         {
    198             final Map.Entry entry = (Map.Entry) entries.next ();
    199 
    200             final String classVMName = (String) entry.getKey ();
    201             final DataHolder data = (DataHolder) entry.getValue ();
    202 
    203             final boolean [][] coverage = data.m_coverage;
    204 
    205             out.writeUTF (classVMName);
    206             out.writeLong (data.m_stamp);
    207 
    208             final int length = coverage.length;
    209             out.writeInt (length);
    210             for (int c = 0; c < length; ++ c)
    211             {
    212                 DataFactory.writeBooleanArray (coverage [c], out);
    213             }
    214         }
    215     }
    216 
    217     // private: ...............................................................
    218 
    219 
    220     private CoverageData (final HashMap coverageMap)
    221     {
    222         if ($assert.ENABLED) $assert.ASSERT (coverageMap != null, "coverageMap is null");
    223         m_coverageMap = coverageMap;
    224     }
    225 
    226 
    227     private /*final*/ HashMap /* String(classVMName) -> DataHolder */ m_coverageMap; // never null
    228 
    229 } // end of class
    230 // ----------------------------------------------------------------------------