1 package org.myoodb.core.storage; 25 26 import java.io.*; 27 28 import org.myoodb.util.*; 29 import org.myoodb.core.*; 30 31 public final class Cluster implements Externalizable, AbstractCluster 32 { 33 private static final org.apache.log4j.Logger LOGGER = org.apache.log4j.Logger.getLogger(Cluster.class); 34 35 private AbstractLock m_lock; 36 private AbstractObjectContainer m_container; 37 38 public static File getMostCurrentCluster(String basename, Identifier objectId) 39 { 40 File current = new File(basename + ClusterStore.SUFFIX_CLUSTER); 41 42 final String strId = objectId.toString(); 43 final String strIdWithSuffix = strId + ClusterStore.SUFFIX_SEPARATOR; 44 final String strIdClusterPath = ClusterStore.getDirectoryName(strId, objectId.isRoot()); 45 46 FilenameFilter clusterFilter = new FilenameFilter() 47 { 48 public boolean accept(File dir, String name) 49 { 50 return (name.startsWith(strIdWithSuffix) == true) && (name.endsWith(ClusterStore.SUFFIX_TEMP) == false); 51 } 52 }; 53 54 long lastTX = -1; 55 File file = new File(strIdClusterPath); 56 String [] fileList = file.list(clusterFilter); 57 for (int i = 0; i < fileList.length; i++) 58 { 59 String [] tokens = fileList[i].split("\\."); 60 61 if (tokens.length == 3) 62 { 63 long tmpTX = Long.parseLong(tokens[1]); 64 65 if (tmpTX > lastTX) 66 { 67 current = new File(strIdClusterPath + File.separator + fileList[i]); 68 lastTX = tmpTX; 69 } 70 } 71 } 72 73 return current; 74 } 75 76 public static void delete(Identifier id) throws IOException 77 { 78 File file = new File(ClusterStore.getBasename(id) + ClusterStore.SUFFIX_CLUSTER); 79 80 if (file.exists() == true) 81 { 82 org.myoodb.core.FileHelper.delete(file); 83 } 84 85 File dfile = new File(ClusterStore.getDirectoryName(id.toString(), id.isRoot())); 87 String [] files = dfile.list(); 88 89 if ((files != null) && (files.length == 0)) 90 { 91 org.myoodb.core.FileHelper.delete(dfile); 92 } 93 } 94 95 public Cluster() 96 { 97 } 98 99 public Cluster(AbstractObjectContainer container, AbstractLock lock) 100 { 101 m_lock = lock; 102 setContainer(container); 103 } 104 105 protected void writeChild(AbstractTransaction tx) throws IOException 106 { 107 String basename = ClusterStore.getBasename(getObjectId()); 108 109 File child = new File(basename + 110 ClusterStore.SUFFIX_SEPARATOR + 111 tx.getTransactionIdentifier() + 112 ClusterStore.SUFFIX_CHILD); 113 114 File parent = getMostCurrentCluster(basename, getObjectId()); 115 116 InputStream in = null; 117 OutputStream out = null; 118 try 119 { 120 in = new FileInputStream(parent); 121 out = new FileOutputStream(child); 122 123 int offset = 0; 124 int size = in.available(); 125 byte[] buffer = new byte[in.available()]; 126 127 while (offset < size) 128 { 129 int bytesRead = in.read(buffer, offset, (size - offset)); 130 if (bytesRead == -1) 131 { 132 break; 133 } 134 135 out.write(buffer, offset, (size - offset)); 136 offset += bytesRead; 137 } 138 } 139 finally 140 { 141 if (in != null) 142 { 143 in.close(); 144 } 145 if (out != null) 146 { 147 out.close(); 148 } 149 } 150 } 151 152 protected void commitChild(AbstractTransaction tx) throws IOException 153 { 154 String basename = ClusterStore.getBasename(getObjectId()); 155 156 File temp = new File(basename + 157 ClusterStore.SUFFIX_SEPARATOR + 158 tx.getTransactionIdentifier() + 159 ClusterStore.SUFFIX_TEMP); 160 161 File child = new File(basename + 162 ClusterStore.SUFFIX_SEPARATOR + 163 tx.getTransactionIdentifier() + 164 ClusterStore.SUFFIX_CHILD); 165 166 if (temp.exists() == true) 167 { 168 org.myoodb.core.FileHelper.delete(temp); 169 } 170 171 if (child.renameTo(temp) == false) 172 { 173 throw new IOException("Unable to rename \"child\" file to \"temp\":" + child + " " + temp + " " + tx); 174 } 175 176 File parent = getMostCurrentCluster(basename, getObjectId()); 177 178 if (parent.exists() == true) 179 { 180 org.myoodb.core.FileHelper.delete(parent); 181 } 182 183 if (temp.renameTo(parent) == false) 184 { 185 throw new IOException("Unable to rename \"temp\" file to \"parent\":" + temp + " " + parent + " " + tx); 186 } 187 } 188 189 protected void deleteChild(AbstractTransaction tx) throws IOException 190 { 191 String basename = ClusterStore.getBasename(getObjectId()); 192 193 File child = new File(basename + 194 ClusterStore.SUFFIX_SEPARATOR + 195 tx.getTransactionIdentifier() + 196 ClusterStore.SUFFIX_CHILD); 197 198 if (child.exists() == true) 199 { 200 org.myoodb.core.FileHelper.delete(child); 201 } 202 } 203 204 protected Identifier getObjectId() 205 { 206 return m_container.getObjectId(); 207 } 208 209 public AbstractLock getLock() 210 { 211 return m_lock; 212 } 213 214 public void setLock(AbstractLock lock) 215 { 216 m_lock = lock; 217 } 218 219 public void setContainer(AbstractObjectContainer container) 220 { 221 m_container = container; 222 m_container.setCluster(this); 223 } 224 225 public AbstractObjectContainer getContainer() 226 { 227 return m_container; 228 } 229 230 public void setAssociatedTransaction(AbstractTransaction tx) throws IOException 231 { 232 if (tx.getTransactionType() == AbstractTransaction.EXPLICIT_TRANSACTION) 233 { 234 writeChild(tx); 235 } 236 } 237 238 public void commit(AbstractTransaction tx) throws IOException 239 { 240 if (tx.getStagingTransactionFlag() == false) 241 { 242 if (tx.getTransactionType() == AbstractTransaction.EXPLICIT_TRANSACTION) 243 { 244 commitChild(tx); 245 } 246 247 if (tx.isExplicitPiggyBack() == false) 248 { 249 m_lock.release(tx); 250 } 251 } 252 } 253 254 public void abort(AbstractTransaction tx) throws IOException 255 { 256 if (tx.getTransactionType() == AbstractTransaction.EXPLICIT_TRANSACTION) 257 { 258 deleteChild(tx); 259 } 260 261 m_lock.release(tx); 262 } 263 264 public boolean delete(AbstractTransaction tx) throws IOException 265 { 266 boolean isBase = false; 267 268 if (tx.getStagingTransactionFlag() == false) 269 { 270 String basename = ClusterStore.getBasename(getObjectId()); 271 272 File child = new File(basename + 273 ClusterStore.SUFFIX_SEPARATOR + 274 tx.getTransactionIdentifier() + 275 ClusterStore.SUFFIX_CHILD); 276 277 File base = new File(basename + ClusterStore.SUFFIX_CLUSTER); 278 279 if (child.equals(base) == true) 280 { 281 isBase = true; 282 } 283 284 if (child.exists() == true) 285 { 286 org.myoodb.core.FileHelper.delete(child); 287 } 288 289 File dfile = new File(ClusterStore.getDirectoryName(getObjectId().toString(), getObjectId().isRoot())); 291 String [] files = dfile.list(); 292 293 if ((files != null) && (files.length == 0)) 294 { 295 org.myoodb.core.FileHelper.delete(dfile); 296 } 297 } 298 299 return isBase; 300 } 301 302 public void read(String file) throws IOException, ClassNotFoundException 303 { 304 ObjectInputStream in = new FastObjectInputStream(new BufferedInputStream(new FileInputStream(file))); 305 306 try 307 { 308 readExternal(in); 309 } 310 finally 311 { 312 in.close(); 313 } 314 } 315 316 public void write(String filename) throws IOException 317 { 318 java.util.ConcurrentModificationException globalError = null; 319 320 for (int i = 0; i < ClusterStore.CONCURRENCY_RETRY; i++) 321 { 322 try 323 { 324 ObjectOutputStream out = new FastObjectOutputStream(new BufferedOutputStream(new FileOutputStream(filename))); 325 326 try 327 { 328 writeExternal(out); 329 globalError = null; 330 break; 331 } 332 finally 333 { 334 out.close(); 335 } 336 } 337 catch (java.util.ConcurrentModificationException e) 338 { 339 LOGGER.warn(null, e); 340 341 try 342 { 343 Thread.sleep(100); 344 } 345 catch (java.lang.InterruptedException ee) 346 { 347 } 349 350 globalError = e; 351 } 352 } 353 354 if (globalError != null) 355 { 356 throw globalError; 357 } 358 } 359 360 public void write() throws IOException 361 { 362 write(ClusterStore.getBasename(getObjectId()) + ClusterStore.SUFFIX_CLUSTER); 363 } 364 365 public void writeExternal(ObjectOutput out) throws IOException 366 { 367 out.writeObject(m_lock); 368 out.writeObject(m_container); 369 } 370 371 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException 372 { 373 m_lock = (AbstractLock) in.readObject(); 374 setContainer((AbstractObjectContainer) in.readObject()); 375 } 376 } 377 | Popular Tags |