| 1 package com.quadcap.sql.lock; 2 3 40 41 import com.quadcap.util.collections.ArrayQueue; 42 43 import com.quadcap.util.Debug; 44 45 50 public class Lock implements Comparable { 51 static Lock tombstone = new Lock(); 52 53 String name; 54 final int[] heldCount = new int[LockMode.MAX]; 55 int refCount = 0; 56 private Lock parent = null; 57 ArrayQueue waitQueue = null; 58 Object sync = new Object (); 59 60 63 protected Lock() {} 64 65 68 public void init(Lock parent, String name) { 69 this.parent = parent; 70 this.name = name; 71 } 72 73 76 final String getName() { return name; } 77 78 final int getHeldCount(int mode) { 79 return heldCount[mode]; 80 } 81 82 final int incrHeldCount(int mode) { 83 return ++heldCount[mode]; 84 } 85 final int decrHeldCount(int mode) { 86 return --heldCount[mode]; 87 } 88 89 final int getHeldCount() { 90 int sum = 0; 91 for (int i = 0; i < LockMode.MAX; i++) sum += heldCount[i]; 92 return sum; 93 } 94 95 final void addWaitQueue(Transaction t) { 96 synchronized (sync) { 97 if (waitQueue == null) waitQueue = new ArrayQueue(2, -1); 98 waitQueue.addBack(t); 99 } 100 } 101 102 final boolean hasWaiters() { 103 synchronized (sync) { 104 return waitQueue == null ? false : waitQueue.size() > 0; 105 } 106 } 107 108 final Transaction popWaitQueue() { 109 Transaction ret = null; 110 synchronized (sync) { 111 if (waitQueue != null) ret = (Transaction)waitQueue.popFront(); 112 } 113 return ret; 114 } 115 116 final Transaction headWaitQueue() { 117 Transaction ret = null; 118 synchronized (sync) { 119 if (waitQueue != null) ret = (Transaction)waitQueue.head(); 120 } 121 return ret; 122 } 123 124 final boolean couldLock(int mode) { 125 switch (mode) { 126 case LockMode.S: 127 return (heldCount[LockMode.X] == 0 && 128 heldCount[LockMode.IX] == 0 && 129 heldCount[LockMode.SIX] == 0); 130 case LockMode.IS: 131 return heldCount[LockMode.X] == 0; 132 case LockMode.X: 133 return (heldCount[LockMode.X] == 0 && 134 heldCount[LockMode.IX] == 0 && 135 heldCount[LockMode.SIX] == 0 && 136 heldCount[LockMode.IS] == 0 && 137 heldCount[LockMode.S] == 0); 138 case LockMode.IX: 139 return (heldCount[LockMode.X] == 0 && 140 heldCount[LockMode.S] == 0 && 141 heldCount[LockMode.SIX] == 0); 142 case LockMode.SIX: 143 return (heldCount[LockMode.X] == 0 && 144 heldCount[LockMode.S] == 0 && 145 heldCount[LockMode.IX] == 0 && 146 heldCount[LockMode.SIX] == 0); 147 default: 148 throw new RuntimeException ("Bad lock mode: " + mode); 149 } 150 } 151 152 final boolean couldPromote(int fromMode, int toMode) { 153 int savc = heldCount[fromMode]; 154 heldCount[fromMode] = 0; 155 boolean could = couldLock(toMode); 156 heldCount[fromMode] = savc; 157 return could; 158 } 159 160 public int compareTo(Object obj) { 161 return name.compareTo(((Lock)obj).name); 162 } 163 164 public boolean equals(Object obj) { 165 return 0 == compareTo(obj); 166 } 167 168 public int hashCode() { 169 return name.hashCode(); 170 } 171 172 public Lock getParent() { return parent; } 173 174 public String toString() { 176 return dump(); 177 } 178 179 public String dump() { 180 StringBuffer sb = new StringBuffer (); 181 sb.append(name); 182 sb.append(": "); 183 for (int i = 0; i < LockMode.MAX; i++) { 184 if (heldCount[i] > 0) { 185 sb.append("{"); 186 sb.append(LockMode.toString(i)); 187 sb.append(","); 188 sb.append(Integer.toString(heldCount[i])); 189 sb.append("} "); 190 } 191 } 192 Transaction t = headWaitQueue(); 193 if (t != null) { 194 sb.append("wait=T:"); 195 sb.append(String.valueOf(t.getTransactionId())); 196 if (waitQueue.size() > 1) { 197 sb.append(" + "); 198 sb.append(waitQueue.size() - 1); 199 sb.append(" other"); 200 if (waitQueue.size() > 2) sb.append('s'); 201 } 202 } 203 return sb.toString(); 204 } 205 } 207 | Popular Tags |