mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Added getCommonAncestor to AVMService + test. Added to console test app.
Changed createSnapshot flavors to return version ids just created instead of void. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3270 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -31,7 +31,7 @@
|
|||||||
<value>build/storage</value>
|
<value>build/storage</value>
|
||||||
</property>
|
</property>
|
||||||
<property name="createTables">
|
<property name="createTables">
|
||||||
<value>true</value>
|
<value>false</value>
|
||||||
</property>
|
</property>
|
||||||
<property name="hibernateHelper">
|
<property name="hibernateHelper">
|
||||||
<ref bean="hibernateHelper"/>
|
<ref bean="hibernateHelper"/>
|
||||||
|
@@ -36,10 +36,10 @@ public class AVMCrawlTest extends AVMServiceTestBase
|
|||||||
public void testCrawl()
|
public void testCrawl()
|
||||||
{
|
{
|
||||||
int n = 4; // Number of Threads.
|
int n = 4; // Number of Threads.
|
||||||
int m = 4; // How many multiples of content to start with.
|
int m = 16; // How many multiples of content to start with.
|
||||||
long runTime = 1200000; // Ten minutes
|
long runTime = 1200000; // Ten minutes
|
||||||
fService.purgeRepository("main");
|
fService.purgeRepository("main");
|
||||||
fReaper.setInactiveBaseSleep(30000);
|
fReaper.setInactiveBaseSleep(60000);
|
||||||
BulkLoader loader = new BulkLoader();
|
BulkLoader loader = new BulkLoader();
|
||||||
loader.setAvmService(fService);
|
loader.setAvmService(fService);
|
||||||
for (int i = 0; i < m; i++)
|
for (int i = 0; i < m; i++)
|
||||||
|
@@ -398,6 +398,17 @@ public class AVMInteractiveConsole
|
|||||||
}
|
}
|
||||||
reader.close();
|
reader.close();
|
||||||
}
|
}
|
||||||
|
else if (command[0].equals("ca"))
|
||||||
|
{
|
||||||
|
if (command.length != 5)
|
||||||
|
{
|
||||||
|
System.err.println("Syntax error.");
|
||||||
|
}
|
||||||
|
AVMNodeDescriptor left = fService.lookup(Integer.parseInt(command[2]), command[1]);
|
||||||
|
AVMNodeDescriptor right = fService.lookup(Integer.parseInt(command[4]), command[3]);
|
||||||
|
AVMNodeDescriptor ca = fService.getCommonAncestor(left, right);
|
||||||
|
System.out.println(ca);
|
||||||
|
}
|
||||||
else if (command[0].equals("exit"))
|
else if (command[0].equals("exit"))
|
||||||
{
|
{
|
||||||
done = true;
|
done = true;
|
||||||
|
@@ -393,4 +393,33 @@ public class AVMNodeDescriptor
|
|||||||
throw new AVMException("Internal Error.");
|
throw new AVMException("Internal Error.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Equals override.
|
||||||
|
* @param obj
|
||||||
|
* @return Equality.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj)
|
||||||
|
{
|
||||||
|
if (this == obj)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof AVMNodeDescriptor))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return fID == ((AVMNodeDescriptor)obj).fID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hashcode override.
|
||||||
|
* @return The objid as hashcode.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return (int)fID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -172,13 +172,13 @@ public interface AVMService
|
|||||||
* semantics.
|
* semantics.
|
||||||
* @param repositories The names of the repositories to snapshot.
|
* @param repositories The names of the repositories to snapshot.
|
||||||
*/
|
*/
|
||||||
public void createSnapshot(List<String> repositories);
|
public List<Integer> createSnapshot(List<String> repositories);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Snapshot the given repository.
|
* Snapshot the given repository.
|
||||||
* @param repository The name of the repository to snapshot.
|
* @param repository The name of the repository to snapshot.
|
||||||
*/
|
*/
|
||||||
public void createSnapshot(String repository);
|
public int createSnapshot(String repository);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the set of versions in a Repository
|
* Get the set of versions in a Repository
|
||||||
@@ -276,4 +276,17 @@ public interface AVMService
|
|||||||
* @param path The path to the layered directory.
|
* @param path The path to the layered directory.
|
||||||
*/
|
*/
|
||||||
public void setOpacity(String path, boolean opacity);
|
public void setOpacity(String path, boolean opacity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the common ancestor of two nodes if one exists.
|
||||||
|
* @param left The first node.
|
||||||
|
* @param right The second node.
|
||||||
|
* @return The common ancestor. There are four possible results. Null means
|
||||||
|
* that there is no common ancestor. Left returned means that left is strictly
|
||||||
|
* an ancestor of right. Right returned means that right is strictly an
|
||||||
|
* ancestor of left. Any other non null return is the common ancestor and
|
||||||
|
* indicates that left and right are in conflict.
|
||||||
|
*/
|
||||||
|
public AVMNodeDescriptor getCommonAncestor(AVMNodeDescriptor left,
|
||||||
|
AVMNodeDescriptor right);
|
||||||
}
|
}
|
||||||
|
@@ -533,7 +533,7 @@ public class AVMServiceImpl implements AVMService
|
|||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.alfresco.repo.avm.AVMService#createSnapshot(java.util.List)
|
* @see org.alfresco.repo.avm.AVMService#createSnapshot(java.util.List)
|
||||||
*/
|
*/
|
||||||
public void createSnapshot(final List<String> repositories)
|
public List<Integer> createSnapshot(final List<String> repositories)
|
||||||
{
|
{
|
||||||
if (repositories == null)
|
if (repositories == null)
|
||||||
{
|
{
|
||||||
@@ -541,20 +541,23 @@ public class AVMServiceImpl implements AVMService
|
|||||||
}
|
}
|
||||||
class HTxnCallback implements HibernateTxnCallback
|
class HTxnCallback implements HibernateTxnCallback
|
||||||
{
|
{
|
||||||
|
public List<Integer> versionIDs;
|
||||||
|
|
||||||
public void perform(Session session)
|
public void perform(Session session)
|
||||||
{
|
{
|
||||||
fSuperRepository.setSession(session);
|
fSuperRepository.setSession(session);
|
||||||
fSuperRepository.createSnapshot(repositories);
|
versionIDs = fSuperRepository.createSnapshot(repositories);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HTxnCallback doit = new HTxnCallback();
|
HTxnCallback doit = new HTxnCallback();
|
||||||
fTransaction.perform(doit, true);
|
fTransaction.perform(doit, true);
|
||||||
|
return doit.versionIDs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.alfresco.repo.avm.AVMService#createSnapshot(java.lang.String)
|
* @see org.alfresco.repo.avm.AVMService#createSnapshot(java.lang.String)
|
||||||
*/
|
*/
|
||||||
public void createSnapshot(final String repository)
|
public int createSnapshot(final String repository)
|
||||||
{
|
{
|
||||||
if (repository == null)
|
if (repository == null)
|
||||||
{
|
{
|
||||||
@@ -562,14 +565,17 @@ public class AVMServiceImpl implements AVMService
|
|||||||
}
|
}
|
||||||
class HTxnCallback implements HibernateTxnCallback
|
class HTxnCallback implements HibernateTxnCallback
|
||||||
{
|
{
|
||||||
|
public int versionID;
|
||||||
|
|
||||||
public void perform(Session session)
|
public void perform(Session session)
|
||||||
{
|
{
|
||||||
fSuperRepository.setSession(session);
|
fSuperRepository.setSession(session);
|
||||||
fSuperRepository.createSnapshot(repository);
|
versionID = fSuperRepository.createSnapshot(repository);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HTxnCallback doit = new HTxnCallback();
|
HTxnCallback doit = new HTxnCallback();
|
||||||
fTransaction.perform(doit, true);
|
fTransaction.perform(doit, true);
|
||||||
|
return doit.versionID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -906,4 +912,36 @@ public class AVMServiceImpl implements AVMService
|
|||||||
HTxnCallback doit = new HTxnCallback();
|
HTxnCallback doit = new HTxnCallback();
|
||||||
fTransaction.perform(doit, false);
|
fTransaction.perform(doit, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the common ancestor of two nodes if one exists.
|
||||||
|
* @param left The first node.
|
||||||
|
* @param right The second node.
|
||||||
|
* @return The common ancestor. There are four possible results. Null means
|
||||||
|
* that there is no common ancestor. Left returned means that left is strictly
|
||||||
|
* an ancestor of right. Right returned means that right is strictly an
|
||||||
|
* ancestor of left. Any other non null return is the common ancestor and
|
||||||
|
* indicates that left and right are in conflict.
|
||||||
|
*/
|
||||||
|
public AVMNodeDescriptor getCommonAncestor(final AVMNodeDescriptor left,
|
||||||
|
final AVMNodeDescriptor right)
|
||||||
|
{
|
||||||
|
if (left == null || right == null)
|
||||||
|
{
|
||||||
|
throw new AVMBadArgumentException("Null node descriptor.");
|
||||||
}
|
}
|
||||||
|
class HTxnCallback implements HibernateTxnCallback
|
||||||
|
{
|
||||||
|
public AVMNodeDescriptor ancestor;
|
||||||
|
|
||||||
|
public void perform(Session session)
|
||||||
|
{
|
||||||
|
fSuperRepository.setSession(session);
|
||||||
|
ancestor = fSuperRepository.getCommonAncestor(left, right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HTxnCallback doit = new HTxnCallback();
|
||||||
|
fTransaction.perform(doit, false);
|
||||||
|
return doit.ancestor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1851,13 +1851,13 @@ public class AVMServiceTest extends AVMServiceTestBase
|
|||||||
loader.setAvmService(fService);
|
loader.setAvmService(fService);
|
||||||
loader.recursiveLoad("source/java/org/alfresco/repo/avm", "main:/");
|
loader.recursiveLoad("source/java/org/alfresco/repo/avm", "main:/");
|
||||||
times.add(System.currentTimeMillis());
|
times.add(System.currentTimeMillis());
|
||||||
fService.createSnapshot("main");
|
assertEquals(1, fService.createSnapshot("main"));
|
||||||
loader.recursiveLoad("source/java/org/alfresco/repo/action", "main:/");
|
loader.recursiveLoad("source/java/org/alfresco/repo/action", "main:/");
|
||||||
times.add(System.currentTimeMillis());
|
times.add(System.currentTimeMillis());
|
||||||
fService.createSnapshot("main");
|
assertEquals(2, fService.createSnapshot("main"));
|
||||||
loader.recursiveLoad("source/java/org/alfresco/repo/audit", "main:/");
|
loader.recursiveLoad("source/java/org/alfresco/repo/audit", "main:/");
|
||||||
times.add(System.currentTimeMillis());
|
times.add(System.currentTimeMillis());
|
||||||
fService.createSnapshot("main");
|
assertEquals(3, fService.createSnapshot("main"));
|
||||||
assertEquals(1, fService.getRepositoryVersions("main", null, new Date(times.get(0))).size());
|
assertEquals(1, fService.getRepositoryVersions("main", null, new Date(times.get(0))).size());
|
||||||
assertEquals(3, fService.getRepositoryVersions("main", new Date(times.get(0)), null).size());
|
assertEquals(3, fService.getRepositoryVersions("main", new Date(times.get(0)), null).size());
|
||||||
assertEquals(2, fService.getRepositoryVersions("main", new Date(times.get(1)),
|
assertEquals(2, fService.getRepositoryVersions("main", new Date(times.get(1)),
|
||||||
@@ -1948,4 +1948,30 @@ public class AVMServiceTest extends AVMServiceTestBase
|
|||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test common ancestor.
|
||||||
|
*/
|
||||||
|
public void testCommonAncestor()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
setupBasicTree();
|
||||||
|
fService.createBranch(-1, "main:/a", "main:/", "branch");
|
||||||
|
fService.createSnapshot("main");
|
||||||
|
AVMNodeDescriptor ancestor = fService.lookup(-1, "main:/a/b/c/foo");
|
||||||
|
fService.getFileOutputStream("main:/a/b/c/foo").close();
|
||||||
|
fService.getFileOutputStream("main:/branch/b/c/foo").close();
|
||||||
|
fService.createSnapshot("main");
|
||||||
|
AVMNodeDescriptor main = fService.lookup(-1, "main:/a/b/c/foo");
|
||||||
|
AVMNodeDescriptor branch = fService.lookup(-1, "main:/branch/b/c/foo");
|
||||||
|
AVMNodeDescriptor ca = fService.getCommonAncestor(main, branch);
|
||||||
|
assertEquals(ancestor, ca);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
package org.alfresco.repo.avm;
|
package org.alfresco.repo.avm;
|
||||||
|
|
||||||
import org.alfresco.repo.avm.hibernate.HibernateHelper;
|
|
||||||
import org.alfresco.repo.avm.util.BulkLoader;
|
import org.alfresco.repo.avm.util.BulkLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -46,8 +46,9 @@ interface Repository
|
|||||||
* Snapshots this repository. This sets all nodes in the
|
* Snapshots this repository. This sets all nodes in the
|
||||||
* the repository to the should be copied state, and creates
|
* the repository to the should be copied state, and creates
|
||||||
* a new version root.
|
* a new version root.
|
||||||
|
* @return The version id of the newly created snapshot.
|
||||||
*/
|
*/
|
||||||
public void createSnapshot();
|
public int createSnapshot();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new directory.
|
* Create a new directory.
|
||||||
|
@@ -125,9 +125,10 @@ class RepositoryImpl implements Repository, Serializable
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Snapshot this repository. This creates a new version record.
|
* Snapshot this repository. This creates a new version record.
|
||||||
|
* @return The version id of the new snapshot.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void createSnapshot()
|
public int createSnapshot()
|
||||||
{
|
{
|
||||||
// If the root isn't new, we can't take a snapshot since nothing has changed.
|
// If the root isn't new, we can't take a snapshot since nothing has changed.
|
||||||
if (!fRoot.getIsNew())
|
if (!fRoot.getIsNew())
|
||||||
@@ -151,6 +152,7 @@ class RepositoryImpl implements Repository, Serializable
|
|||||||
fSuper.getSession().save(versionRoot);
|
fSuper.getSession().save(versionRoot);
|
||||||
// Increment the version id.
|
// Increment the version id.
|
||||||
fNextVersionID++;
|
fNextVersionID++;
|
||||||
|
return fNextVersionID - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -33,8 +33,8 @@ public class SimultaneousLoadTest extends AVMServiceTestBase
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
int n = 8;
|
int n = 8;
|
||||||
int m = 1;
|
int m = 2;
|
||||||
fReaper.setInactiveBaseSleep(30000);
|
fReaper.setInactiveBaseSleep(60000);
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
fService.createDirectory("main:/", "d" + i);
|
fService.createDirectory("main:/", "d" + i);
|
||||||
|
@@ -414,28 +414,32 @@ class SuperRepository
|
|||||||
/**
|
/**
|
||||||
* Snapshot the given repositories.
|
* Snapshot the given repositories.
|
||||||
* @param repositories The list of repository name to snapshot.
|
* @param repositories The list of repository name to snapshot.
|
||||||
|
* @return A List of version ids for each newly snapshotted repository.
|
||||||
*/
|
*/
|
||||||
public void createSnapshot(List<String> repositories)
|
public List<Integer> createSnapshot(List<String> repositories)
|
||||||
{
|
{
|
||||||
|
List<Integer> result = new ArrayList<Integer>();
|
||||||
for (String repName : repositories)
|
for (String repName : repositories)
|
||||||
{
|
{
|
||||||
Repository repo = getRepositoryByName(repName, true);
|
Repository repo = getRepositoryByName(repName, true);
|
||||||
fSession.get().lock(repo, LockMode.UPGRADE);
|
fSession.get().lock(repo, LockMode.UPGRADE);
|
||||||
// fSession.get().lock(repo, LockMode.UPGRADE);
|
// fSession.get().lock(repo, LockMode.UPGRADE);
|
||||||
repo.createSnapshot();
|
result.add(repo.createSnapshot());
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a snapshot of a single repository.
|
* Create a snapshot of a single repository.
|
||||||
* @param repository The name of the repository.
|
* @param repository The name of the repository.
|
||||||
|
* @return The version id of the newly snapshotted repository.
|
||||||
*/
|
*/
|
||||||
public void createSnapshot(String repository)
|
public int createSnapshot(String repository)
|
||||||
{
|
{
|
||||||
Repository repo = getRepositoryByName(repository, true);
|
Repository repo = getRepositoryByName(repository, true);
|
||||||
fSession.get().lock(repo, LockMode.UPGRADE);
|
fSession.get().lock(repo, LockMode.UPGRADE);
|
||||||
// fSession.get().lock(repo, LockMode.UPGRADE);
|
// fSession.get().lock(repo, LockMode.UPGRADE);
|
||||||
repo.createSnapshot();
|
return repo.createSnapshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -890,6 +894,52 @@ class SuperRepository
|
|||||||
return getRepositoryByName(name, false).getDescriptor();
|
return getRepositoryByName(name, false).getDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the common ancestor of two nodes if one exists. Unfortunately
|
||||||
|
* this is a quadratic problem, taking time proportional to the product
|
||||||
|
* of the lengths of the left and right history chains.
|
||||||
|
* @param left The first node.
|
||||||
|
* @param right The second node.
|
||||||
|
* @return The common ancestor. There are four possible results. Null means
|
||||||
|
* that there is no common ancestor. Left returned means that left is strictly
|
||||||
|
* an ancestor of right. Right returned means that right is strictly an
|
||||||
|
* ancestor of left. Any other non null return is the common ancestor and
|
||||||
|
* indicates that left and right are in conflict.
|
||||||
|
*/
|
||||||
|
public AVMNodeDescriptor getCommonAncestor(AVMNodeDescriptor left,
|
||||||
|
AVMNodeDescriptor right)
|
||||||
|
{
|
||||||
|
AVMNode lNode = (AVMNode)fSession.get().get(AVMNodeImpl.class, left.getId());
|
||||||
|
AVMNode rNode = (AVMNode)fSession.get().get(AVMNodeImpl.class, right.getId());
|
||||||
|
if (lNode == null || rNode == null)
|
||||||
|
{
|
||||||
|
throw new AVMNotFoundException("Node not found.");
|
||||||
|
}
|
||||||
|
List<AVMNode> leftHistory = new ArrayList<AVMNode>();
|
||||||
|
while (lNode != null)
|
||||||
|
{
|
||||||
|
leftHistory.add(lNode);
|
||||||
|
lNode = lNode.getAncestor();
|
||||||
|
}
|
||||||
|
List<AVMNode> rightHistory = new ArrayList<AVMNode>();
|
||||||
|
while (rNode != null)
|
||||||
|
{
|
||||||
|
rightHistory.add(rNode);
|
||||||
|
rNode = rNode.getAncestor();
|
||||||
|
}
|
||||||
|
for (AVMNode l : leftHistory)
|
||||||
|
{
|
||||||
|
for (AVMNode r : rightHistory)
|
||||||
|
{
|
||||||
|
if (l.equals(r))
|
||||||
|
{
|
||||||
|
return l.getDescriptor("", "", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the single instance of SuperRepository.
|
* Get the single instance of SuperRepository.
|
||||||
* @return The single instance.
|
* @return The single instance.
|
||||||
|
Reference in New Issue
Block a user