Purged some useless passing of SuperRepositories as parameters.

Yet another concurrency test.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3155 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Britt Park
2006-06-19 23:59:19 +00:00
parent 8800461d79
commit 8614d80962
12 changed files with 164 additions and 75 deletions

View File

@@ -36,10 +36,17 @@ public class AVMStressTest extends AVMServiceTestBase
try try
{ {
BulkLoader loader = new BulkLoader(fService); BulkLoader loader = new BulkLoader(fService);
loader.recursiveLoad("source", "main:/"); long start = System.currentTimeMillis();
for (int i = 0; i < 1; i++)
{
fService.createDirectory("main:/", "" + i);
loader.recursiveLoad("source", "main:/" + i);
fService.createSnapshot("main");
}
System.out.println("Load time: " + (System.currentTimeMillis() - start));
List<AVMTester> testers = new ArrayList<AVMTester>(); List<AVMTester> testers = new ArrayList<AVMTester>();
List<Thread> threads = new ArrayList<Thread>(); List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < 8; i++) for (int i = 0; i < 1; i++)
{ {
AVMTester tester AVMTester tester
= new AVMTester(400, // create file. = new AVMTester(400, // create file.
@@ -54,7 +61,10 @@ public class AVMStressTest extends AVMServiceTestBase
10000, // # ops 10000, // # ops
fService, fService,
"" + i); "" + i);
tester.Refresh(); if (i == 0)
{
tester.Refresh();
}
Thread thread = new Thread(tester); Thread thread = new Thread(tester);
testers.add(tester); testers.add(tester);
threads.add(thread); threads.add(thread);
@@ -64,12 +74,12 @@ public class AVMStressTest extends AVMServiceTestBase
thread.start(); thread.start();
} }
int exited = 0; int exited = 0;
while (exited != 8) while (exited != 1)
{ {
try try
{ {
Thread.sleep(2000); Thread.sleep(2000);
for (int i = 0; i < 8; i++) for (int i = 0; i < 1; i++)
{ {
if (threads.get(i) == null) if (threads.get(i) == null)
{ {

View File

@@ -40,25 +40,22 @@ interface FileContent
/** /**
* Get an input stream from the content. * Get an input stream from the content.
* @param superRepo The SuperRepository.
* @return An InputStream. * @return An InputStream.
*/ */
public InputStream getInputStream(SuperRepository superRepo); public InputStream getInputStream();
/** /**
* Get an output stream to the content. * Get an output stream to the content.
* @param superRepo The SuperRepository.
* @return an OutputStream. * @return an OutputStream.
*/ */
public OutputStream getOutputStream(SuperRepository superRepo); public OutputStream getOutputStream();
/** /**
* Get a random access file to this content. * Get a random access file to this content.
* @param superRepo The SuperRepository.
* @param access The mode to open the file in. * @param access The mode to open the file in.
* @return A RandomAccessFile. * @return A RandomAccessFile.
*/ */
public RandomAccessFile getRandomAccess(SuperRepository superRepo, String access); public RandomAccessFile getRandomAccess(String access);
/** /**
* Delete the contents of this from the backing store. * Delete the contents of this from the backing store.
@@ -70,7 +67,7 @@ interface FileContent
* @param superRepo * @param superRepo
* @return The length of the file. * @return The length of the file.
*/ */
public long getLength(SuperRepository superRepo); public long getLength();
/** /**
* Get the object id. * Get the object id.

View File

@@ -73,38 +73,37 @@ class FileContentImpl implements FileContent, Serializable
/** /**
* Make a brand new one. * Make a brand new one.
* @param superRepo The SuperRepository. * @param id The id for this content.
* @param source A possibly null stream to get data from.
*/ */
public FileContentImpl(SuperRepository superRepo) public FileContentImpl(long id)
{ {
fID = superRepo.issueContentID(); fID = id;
fRefCount = 1; fRefCount = 1;
// Initialize the contents. // Initialize the contents.
try try
{ {
OutputStream out = getOutputStream(superRepo); OutputStream out = getOutputStream();
out.close(); out.close();
} }
catch (IOException ie) catch (IOException ie)
{ {
throw new AVMException("File data error.", ie); throw new AVMException("File data error.", ie);
} }
superRepo.getSession().save(this); SuperRepository.GetInstance().getSession().save(this);
} }
/** /**
* Copy constructor, sort of. * Copy constructor, sort of.
* @param other The content to copy from. * @param other The content to copy from.
* @param superRepo The SuperRepository. * @param id The id for this content.
*/ */
public FileContentImpl(FileContent other, SuperRepository superRepo) public FileContentImpl(FileContent other, long id)
{ {
fID = superRepo.issueContentID(); fID = id;
fRefCount = 1; fRefCount = 1;
// Copy the contents from other to this. // Copy the contents from other to this.
BufferedInputStream in = new BufferedInputStream(other.getInputStream(superRepo)); BufferedInputStream in = new BufferedInputStream(other.getInputStream());
BufferedOutputStream out = new BufferedOutputStream(this.getOutputStream(superRepo)); BufferedOutputStream out = new BufferedOutputStream(getOutputStream());
try try
{ {
byte [] buff = new byte[4096]; // Nyah, nyah. byte [] buff = new byte[4096]; // Nyah, nyah.
@@ -121,7 +120,7 @@ class FileContentImpl implements FileContent, Serializable
{ {
throw new AVMException("I/O failure in Copy on Write.", ie); throw new AVMException("I/O failure in Copy on Write.", ie);
} }
superRepo.getSession().save(this); SuperRepository.GetInstance().getSession().save(this);
} }
/** /**
@@ -144,40 +143,38 @@ class FileContentImpl implements FileContent, Serializable
/** /**
* Get an InputStream from this FileContent. * Get an InputStream from this FileContent.
* @param superRepo The SuperRepository (to get backing store location from).
* @return An InputStream. * @return An InputStream.
*/ */
public InputStream getInputStream(SuperRepository superRepo) public InputStream getInputStream()
{ {
try try
{ {
return new FileInputStream(getContentPath(superRepo)); return new FileInputStream(getContentPath());
} }
catch (IOException ie) catch (IOException ie)
{ {
throw new AVMException("Could not open for reading: " + getContentPath(superRepo), ie); throw new AVMException("Could not open for reading: " + getContentPath(), ie);
} }
} }
/** /**
* Gets an ouptut stream to this node. * Gets an ouptut stream to this node.
* @param superRepo The SuperRepository.
* @return An OutputStream. * @return An OutputStream.
*/ */
public OutputStream getOutputStream(SuperRepository superRepo) public OutputStream getOutputStream()
{ {
try try
{ {
File dir = new File(getDirectoryPath(superRepo)); File dir = new File(getDirectoryPath());
if (!dir.exists()) if (!dir.exists())
{ {
dir.mkdirs(); dir.mkdirs();
} }
return new FileOutputStream(getContentPath(superRepo)); return new FileOutputStream(getContentPath());
} }
catch (IOException ie) catch (IOException ie)
{ {
throw new AVMException("Could not open for writing: " + getContentPath(superRepo), ie); throw new AVMException("Could not open for writing: " + getContentPath(), ie);
} }
} }
@@ -189,15 +186,15 @@ class FileContentImpl implements FileContent, Serializable
* @param access The access more for RandomAccessFile. * @param access The access more for RandomAccessFile.
* @return A RandomAccessFile. * @return A RandomAccessFile.
*/ */
public RandomAccessFile getRandomAccess(SuperRepository superRepo, String access) public RandomAccessFile getRandomAccess(String access)
{ {
try try
{ {
return new RandomAccessFile(getContentPath(superRepo), access); return new RandomAccessFile(getContentPath(), access);
} }
catch (IOException ie) catch (IOException ie)
{ {
throw new AVMException("Could not open for random access: " + getContentPath(superRepo), ie); throw new AVMException("Could not open for random access: " + getContentPath(), ie);
} }
} }
@@ -206,45 +203,42 @@ class FileContentImpl implements FileContent, Serializable
*/ */
public void delete() public void delete()
{ {
File file = new File(getContentPath(SuperRepository.GetInstance())); File file = new File(getContentPath());
file.delete(); file.delete();
} }
/** /**
* Get the length of this content. * Get the length of this content.
* @param superRepo The SuperRepository
* @return The length of the content. * @return The length of the content.
*/ */
public long getLength(SuperRepository superRepo) public long getLength()
{ {
File file = new File(getContentPath(superRepo)); File file = new File(getContentPath());
return file.length(); return file.length();
} }
/** /**
* Retrieve the full path for this content. * Retrieve the full path for this content.
* @param superRepo
* @return The full path for this content. * @return The full path for this content.
*/ */
private synchronized String getContentPath(SuperRepository superRepo) private synchronized String getContentPath()
{ {
if (fName == null) if (fName == null)
{ {
calcPathData(superRepo); calcPathData();
} }
return fName; return fName;
} }
/** /**
* Get the directory path for this content. * Get the directory path for this content.
* @param superRepo
* @return The directory path. * @return The directory path.
*/ */
private synchronized String getDirectoryPath(SuperRepository superRepo) private synchronized String getDirectoryPath()
{ {
if (fPath == null) if (fPath == null)
{ {
calcPathData(superRepo); calcPathData();
} }
return fPath; return fPath;
} }
@@ -252,7 +246,7 @@ class FileContentImpl implements FileContent, Serializable
/** /**
* Calculate the path data. * Calculate the path data.
*/ */
private void calcPathData(SuperRepository superRepo) private void calcPathData()
{ {
Formatter form = new Formatter(new StringBuilder()); Formatter form = new Formatter(new StringBuilder());
form.format("%016x", fID); form.format("%016x", fID);
@@ -263,7 +257,7 @@ class FileContentImpl implements FileContent, Serializable
(fID & 0xff0000) >> 16, (fID & 0xff0000) >> 16,
(fID & 0xff00) >> 8); (fID & 0xff00) >> 8);
String dir = form.toString(); String dir = form.toString();
fPath = superRepo.getStorageRoot() + dir; fPath = SuperRepository.GetInstance().getStorageRoot() + dir;
fName = fPath + "/" + name; fName = fPath + "/" + name;
} }

View File

@@ -31,8 +31,7 @@ interface FileNode extends AVMNode
/** /**
* Get the content object for writing. This will do COW * Get the content object for writing. This will do COW
* as needed. * as needed.
* @param The repository.
* @return A FileContent object. * @return A FileContent object.
*/ */
public FileContent getContentForWrite(Repository repo); public FileContent getContentForWrite();
} }

View File

@@ -299,7 +299,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
{ {
try try
{ {
Lookup lookup = lPath.getRepository().getSuperRepository().lookupDirectory(-1, getUnderlying(lPath)); Lookup lookup = SuperRepository.GetInstance().lookupDirectory(-1, getUnderlying(lPath));
DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode();
if (dir.lookupChild(lookup, name, -1) != null) if (dir.lookupChild(lookup, name, -1) != null)
{ {
@@ -343,7 +343,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
Map<String, AVMNode> baseListing = null; Map<String, AVMNode> baseListing = null;
try try
{ {
Lookup lookup = lPath.getRepository().getSuperRepository().lookupDirectory(-1, getUnderlying(lPath)); Lookup lookup = SuperRepository.GetInstance().lookupDirectory(-1, getUnderlying(lPath));
DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode();
baseListing = dir.getListing(lookup); baseListing = dir.getListing(lookup);
} }
@@ -443,7 +443,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
// Not here so check our indirection. // Not here so check our indirection.
try try
{ {
Lookup lookup = lPath.getRepository().getSuperRepository().lookupDirectory(-1, getUnderlying(lPath)); Lookup lookup = SuperRepository.GetInstance().lookupDirectory(-1, getUnderlying(lPath));
DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode();
return dir.lookupChild(lookup, name, -1); return dir.lookupChild(lookup, name, -1);
} }
@@ -538,7 +538,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
// See if the name is seen via indirection. // See if the name is seen via indirection.
try try
{ {
Lookup lookup = lPath.getRepository().getSuperRepository().lookupDirectory(-1, getUnderlying(lPath)); Lookup lookup = SuperRepository.GetInstance().lookupDirectory(-1, getUnderlying(lPath));
DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lookup.getCurrentNode();
if (dir.lookupChild(lookup, name, -1) == null) if (dir.lookupChild(lookup, name, -1) == null)
{ {
@@ -621,7 +621,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
DeletedChild dc = toModify.getDeleted(name); DeletedChild dc = toModify.getDeleted(name);
if (dc != null) if (dc != null)
{ {
lPath.getRepository().getSuperRepository().getSession().delete(dc); SuperRepository.GetInstance().getSession().delete(dc);
} }
} }

View File

@@ -69,7 +69,7 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
public AVMNode possiblyCopy(Lookup lPath) public AVMNode possiblyCopy(Lookup lPath)
{ {
// LayeredFileNodes are always copied. // LayeredFileNodes are always copied.
Lookup lookup = lPath.getRepository().getSuperRepository().lookup(-1, fIndirection); Lookup lookup = SuperRepository.GetInstance().lookup(-1, fIndirection);
AVMNode indirect = lookup.getCurrentNode(); AVMNode indirect = lookup.getCurrentNode();
if (indirect.getType() != AVMNodeType.LAYERED_FILE && if (indirect.getType() != AVMNodeType.LAYERED_FILE &&
indirect.getType() != AVMNodeType.PLAIN_FILE) indirect.getType() != AVMNodeType.PLAIN_FILE)
@@ -113,10 +113,9 @@ class LayeredFileNodeImpl extends FileNodeImpl implements LayeredFileNode
/** /**
* Get File Content for writing. Should never be called. * Get File Content for writing. Should never be called.
* @param repo The Repository.
* @return Always null. * @return Always null.
*/ */
public FileContent getContentForWrite(Repository repo) public FileContent getContentForWrite()
{ {
assert false : "Never happens"; assert false : "Never happens";
return null; return null;

View File

@@ -295,7 +295,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
public void turnPrimary(Lookup lPath) public void turnPrimary(Lookup lPath)
{ {
LayeredDirectoryNode toModify = (LayeredDirectoryNode)copyOnWrite(lPath); LayeredDirectoryNode toModify = (LayeredDirectoryNode)copyOnWrite(lPath);
Lookup lookup = lPath.getRepository().getSuperRepository().lookup(-1, lPath.getRepresentedPath()); Lookup lookup = SuperRepository.GetInstance().lookup(-1, lPath.getRepresentedPath());
toModify.rawSetPrimary(lookup.getCurrentIndirection()); toModify.rawSetPrimary(lookup.getCurrentIndirection());
} }

View File

@@ -47,7 +47,7 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
public PlainFileNodeImpl(Repository repos) public PlainFileNodeImpl(Repository repos)
{ {
super(repos.getSuperRepository().issueID(), repos); super(repos.getSuperRepository().issueID(), repos);
fContent = new FileContentImpl(repos.getSuperRepository()); fContent = new FileContentImpl(SuperRepository.GetInstance().issueContentID());
repos.getSuperRepository().getSession().save(this); repos.getSuperRepository().getSession().save(this);
} }
@@ -114,13 +114,12 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
/** /**
* Get content for writing. * Get content for writing.
* @param repo The Repository.
*/ */
public FileContent getContentForWrite(Repository repo) public FileContent getContentForWrite()
{ {
if (fContent.getRefCount() > 1) if (fContent.getRefCount() > 1)
{ {
fContent = new FileContentImpl(fContent, repo.getSuperRepository()); fContent = new FileContentImpl(fContent, SuperRepository.GetInstance().issueContentID());
} }
return fContent; return fContent;
} }
@@ -157,8 +156,7 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
null, null,
false, false,
-1, -1,
getContentForRead() getContentForRead().getLength());
.getLength(lPath.getRepository().getSuperRepository()));
} }
/** /**
@@ -185,8 +183,7 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
null, null,
false, false,
-1, -1,
getContentForRead() getContentForRead().getLength());
.getLength(getRepository().getSuperRepository()));
} }
/** /**

View File

@@ -224,7 +224,7 @@ class RepositoryImpl implements Repository, Serializable
PlainFileNodeImpl file = new PlainFileNodeImpl(this); PlainFileNodeImpl file = new PlainFileNodeImpl(this);
file.setVersionID(getNextVersionID()); file.setVersionID(getNextVersionID());
dir.addChild(name, file, lPath); dir.addChild(name, file, lPath);
return file.getContentForWrite(this).getOutputStream(fSuper); return file.getContentForWrite().getOutputStream();
} }
/** /**
@@ -266,7 +266,7 @@ class RepositoryImpl implements Repository, Serializable
} }
FileNode file = (FileNode)node; FileNode file = (FileNode)node;
FileContent content = file.getContentForRead(); FileContent content = file.getContentForRead();
return content.getInputStream(fSuper); return content.getInputStream();
} }
/** /**
@@ -309,8 +309,8 @@ class RepositoryImpl implements Repository, Serializable
} }
FileNode file = (FileNode)node; FileNode file = (FileNode)node;
file = (FileNode)file.copyOnWrite(lPath); file = (FileNode)file.copyOnWrite(lPath);
FileContent content = file.getContentForWrite(this); FileContent content = file.getContentForWrite();
return content.getOutputStream(fSuper); // TODO Do we really need fSuper? return content.getOutputStream(); // TODO Do we really need fSuper?
} }
/** /**
@@ -343,13 +343,13 @@ class RepositoryImpl implements Repository, Serializable
if (write) if (write)
{ {
file = (FileNode)file.copyOnWrite(lPath); file = (FileNode)file.copyOnWrite(lPath);
content = file.getContentForWrite(this); content = file.getContentForWrite();
} }
else else
{ {
content = file.getContentForRead(); content = file.getContentForRead();
} }
return content.getRandomAccess(fSuper, access); return content.getRandomAccess(access);
} }
/** /**

View File

@@ -0,0 +1,94 @@
/*
* Copyright (C) 2006 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.avm;
import org.alfresco.repo.avm.util.BulkLoader;
/**
* This tests loading content simultaneously.
* @author britt
*/
public class SimultaneousLoadTest extends AVMServiceTestBase
{
/**
* Test loading content simultaneously.
*/
public void testSimultaneousLoad()
{
try
{
int n = 16;
for (int i = 0; i < n; i++)
{
fService.createDirectory("main:/", "d" + i);
}
fService.createSnapshot("main");
Thread [] threads = new Thread[n];
for (int i = 0; i < n; i++)
{
Loader loader = new Loader("source", "main:/d" + i);
threads[i] = new Thread(loader);
threads[i].start();
}
for (int i = 0; i < n; i++)
{
threads[i].join();
}
}
catch (Exception e)
{
e.printStackTrace(System.err);
fail();
}
}
private class Loader implements Runnable
{
/**
* The BulkLoader.
*/
private BulkLoader fLoader;
/**
* The source directory.
*/
private String fSource;
/**
* The destination path.
*/
private String fDestination;
/**
* Set up.
* @param source Source directory.
* @param destination Destination path.
*/
public Loader(String source, String destination)
{
fLoader = new BulkLoader(fService);
fSource = source;
fDestination = destination;
}
public void run()
{
fLoader.recursiveLoad(fSource, fDestination);
}
}
}

View File

@@ -528,7 +528,7 @@ class SuperRepository
throw new AVMWrongTypeException("Not a file."); throw new AVMWrongTypeException("Not a file.");
} }
FileNode file = (FileNode)node; FileNode file = (FileNode)node;
return file.getContentForRead().getInputStream(SuperRepository.GetInstance()); return file.getContentForRead().getInputStream();
} }
/** /**

View File

@@ -72,7 +72,6 @@ public class BulkLoader
*/ */
public void recursiveLoad(String fsPath, String repPath) public void recursiveLoad(String fsPath, String repPath)
{ {
System.out.println(fsPath);
File file = new File(fsPath); File file = new File(fsPath);
String name = file.getName(); String name = file.getName();
if (file.isDirectory()) if (file.isDirectory())