aa
UQNodes.java
Go to the documentation of this file.
1 package com.cliffc.aa.tvar;
2 
3 import com.cliffc.aa.node.Node;
4 import com.cliffc.aa.util.*;
5 import java.util.HashMap;
6 
7 // Unique immutable lazy-defined sets of Nodes.
8 public class UQNodes extends NonBlockingHashMapLong<Node> {
10  private static UQNodes KEY = new UQNodes();
11  private int _hash;
12 
13 
14  private static UQNodes intern() {
15  KEY.setHash();
16  UQNodes uqset = UQSETS.get(KEY);
17  if( uqset==null ) {
18  UQSETS.put(uqset=KEY,KEY);
19  KEY=new UQNodes();
20  } else {
21  KEY.clear();
22  KEY._hash=0;
23  }
24  return uqset;
25  }
26 
27  // Make a unique set of 1 node
28  public static UQNodes make( Node tn ) {
29  assert !tn.is_dead();
30  assert KEY.isEmpty();
31  KEY.put(tn._uid,tn);
32  return intern();
33  }
34 
35  // Add a node to a unique-set: copy, insert key, re-hash/intern.
36  public UQNodes add( Node tn ) {
37  assert KEY.isEmpty();
38  assert !tn.is_dead();
39  if( get(tn._uid)!=null ) return this; // Already in there
40  // Fold them together
41  for( Node n : values() ) if( !n.is_dead() ) KEY.put(n._uid,n);
42  KEY.put(tn._uid,tn);
43  return intern();
44  }
45 
46  // Combine two unique-sets & return the result. Lazy remove dead nodes.
47  public UQNodes addAll( UQNodes uq ) {
48  assert KEY.isEmpty();
49  if( uq==null ) return this;
50 
51  // Get smaller in uq0
52  UQNodes uq0 = this;
53  UQNodes uq1 = uq;
54  if( uq1.size() < uq0.size() ) { uq0=uq; uq1=this; }
55  // See if all of smaller is in larger
56  boolean progress=false;
57  for( Node n : uq0.values() )
58  if( !n.is_dead() && uq1.get(n._uid)!=n )
59  { progress = true; break; }
60  if( !progress ) return uq1;
61 
62  // Fold them together
63  for( Node n : uq0.values() ) if( !n.is_dead() ) KEY.put(n._uid,n);
64  for( Node n : uq1.values() ) if( !n.is_dead() ) KEY.put(n._uid,n);
65 
66  return intern();
67  }
68 
69  // Replace via the map
70  public UQNodes rename(HashMap<Node,Node> map) {
71  assert KEY.isEmpty();
72  for( Node n : values() )
73  if( !n.is_dead() ) {
74  Node c = map.get(n);
75  if( c==null ) c = n;
76  KEY.put(c._uid,c);
77  }
78  return intern();
79  }
80 
81  private void setHash() {
82  long hash=0;
83  for( Node n : values() )
84  hash = hash^System.identityHashCode(n);
85  if( hash==0 ) hash=1;
86  _hash = (int)hash;
87  }
88  @Override public int hashCode() { assert _hash!=0; return _hash; }
89  @Override public boolean equals( Object o ) {
90  if( !(o instanceof UQNodes) ) return false;
91  UQNodes uq = (UQNodes)o;
92  assert _hash!=0 && uq._hash!=0;
93  if( _hash!=uq._hash ) return false;
94  if( size() != uq.size() ) return false;
95  for( Node n : values() )
96  if( n!=uq.get(n._uid) )
97  return false;
98  return true;
99  }
100 
101 }
102 
com.cliffc.aa.tvar.UQNodes.equals
boolean equals(Object o)
Definition: UQNodes.java:89
com.cliffc.aa.tvar.UQNodes.KEY
static UQNodes KEY
Definition: UQNodes.java:10
com.cliffc.aa.util.NonBlockingHashMap
A lock-free alternate implementation of java.util.concurrent.ConcurrentHashMap with better scaling pr...
Definition: NonBlockingHashMap.java:75
com.cliffc
com.cliffc.aa.node.Node
Definition: Node.java:16
com.cliffc.aa.util
Definition: AbstractEntry.java:1
com.cliffc.aa.util.NonBlockingHashMapLong.clear
void clear()
Removes all of the mappings from this map.
Definition: NonBlockingHashMapLong.java:332
com.cliffc.aa.tvar.UQNodes.addAll
UQNodes addAll(UQNodes uq)
Definition: UQNodes.java:47
com.cliffc.aa.util.NonBlockingHashMapLong.size
int size()
Returns the number of key-value mappings in this map.
Definition: NonBlockingHashMapLong.java:255
com.cliffc.aa.util.NonBlockingHashMapLong.get
final TypeV get(long key)
Returns the value to which the specified key is mapped, or.
Definition: NonBlockingHashMapLong.java:368
com.cliffc.aa.node.Node.is_dead
boolean is_dead()
Definition: Node.java:820
com.cliffc.aa.tvar.UQNodes.make
static UQNodes make(Node tn)
Definition: UQNodes.java:28
com.cliffc.aa.tvar.UQNodes.rename
UQNodes rename(HashMap< Node, Node > map)
Definition: UQNodes.java:70
HashMap
com.cliffc.aa.util.NonBlockingHashMapLong< Node >::hash
static final int hash(long h)
Definition: NonBlockingHashMapLong.java:416
com.cliffc.aa.tvar.UQNodes.add
UQNodes add(Node tn)
Definition: UQNodes.java:36
com.cliffc.aa.tvar.UQNodes.intern
static UQNodes intern()
Definition: UQNodes.java:14
com.cliffc.aa
Definition: AA.java:1
com.cliffc.aa.tvar.UQNodes
Definition: UQNodes.java:8
com.cliffc.aa.tvar.UQNodes.setHash
void setHash()
Definition: UQNodes.java:81
com.cliffc.aa.util.NonBlockingHashMapLong
A lock-free alternate implementation of java.util.concurrent.ConcurrentHashMap with primitive long ke...
Definition: NonBlockingHashMapLong.java:91
com.cliffc.aa.util.NonBlockingHashMapLong.put
TypeV put(long key, TypeV val)
Maps the specified key to the specified value in the table.
Definition: NonBlockingHashMapLong.java:278
com.cliffc.aa.node.Node._uid
int _uid
Definition: Node.java:84
com.cliffc.aa.tvar.UQNodes._hash
int _hash
Definition: UQNodes.java:11
com
com.cliffc.aa.util.NonBlockingHashMapLong< Node >::values
Collection< TypeV > values()
Returns a Collection view of the values contained in this map.
Definition: NonBlockingHashMapLong.java:1118
com.cliffc.aa.tvar.UQNodes.hashCode
int hashCode()
Definition: UQNodes.java:88
com.cliffc.aa.node
Definition: AssertNode.java:1
com.cliffc.aa.tvar.UQNodes.UQSETS
static final NonBlockingHashMap< UQNodes, UQNodes > UQSETS
Definition: UQNodes.java:9