mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Introduces a new variant on the link() call that makes the update() call
way faster in the worst case, i.e. tolerable so far. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3808 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -1262,4 +1262,27 @@ public class AVMRepository
|
||||
AVMStore store = getAVMStoreByName(pathParts[0]);
|
||||
store.link(pathParts[1], name, toLink);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the danger version of link. It must be called on
|
||||
* a copied and unsnapshotted directory. It blithely inserts
|
||||
* a child without checking if a child exists with a conflicting name.
|
||||
* @param parent The parent directory.
|
||||
* @param name The name to give the child.
|
||||
* @param child The child to link in.
|
||||
*/
|
||||
public void link(AVMNodeDescriptor parent, String name, AVMNodeDescriptor child)
|
||||
{
|
||||
AVMNode node = AVMContext.fgInstance.fAVMNodeDAO.getByID(parent.getId());
|
||||
if (!(node instanceof DirectoryNode))
|
||||
{
|
||||
throw new AVMWrongTypeException("Not a Directory.");
|
||||
}
|
||||
DirectoryNode dir = (DirectoryNode)node;
|
||||
if (!dir.getIsNew())
|
||||
{
|
||||
throw new AVMException("Directory has not already been copied.");
|
||||
}
|
||||
dir.link(name, child);
|
||||
}
|
||||
}
|
||||
|
@@ -1065,4 +1065,22 @@ public class AVMServiceImpl implements AVMService
|
||||
}
|
||||
fAVMRepository.link(parentPath, name, toLink);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a more dangerous version of link, which assumes
|
||||
* that copy on write has occurred for the parent node. This is
|
||||
* an internal call. Don't use it if you don't know precisely
|
||||
* what you are doing.
|
||||
* @param parent The parent node.
|
||||
* @param name The name to give the child.
|
||||
* @param child The child node to link.
|
||||
*/
|
||||
public void link(AVMNodeDescriptor parent, String name, AVMNodeDescriptor child)
|
||||
{
|
||||
if (parent == null || child == null)
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal Null Argument.");
|
||||
}
|
||||
fAVMRepository.link(parent, name, child);
|
||||
}
|
||||
}
|
||||
|
@@ -59,6 +59,56 @@ import org.alfresco.service.transaction.TransactionService;
|
||||
*/
|
||||
public class AVMServiceTest extends AVMServiceTestBase
|
||||
{
|
||||
/**
|
||||
* Test bulk update.
|
||||
*/
|
||||
public void testBulkUpdate()
|
||||
{
|
||||
try
|
||||
{
|
||||
BulkLoader loader = new BulkLoader();
|
||||
loader.setAvmService(fService);
|
||||
fService.createAVMStore("layer");
|
||||
fService.createLayeredDirectory("main:/", "layer:/", "layer");
|
||||
loader.recursiveLoad("config/alfresco/bootstrap", "layer:/layer");
|
||||
List<AVMDifference> diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/");
|
||||
assertEquals(1, diffs.size());
|
||||
fService.createSnapshot("layer");
|
||||
fSyncService.update(diffs, false, false, false, false);
|
||||
fService.createSnapshot("main");
|
||||
diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/");
|
||||
assertEquals(0, diffs.size());
|
||||
fSyncService.flatten("layer:/layer", "main:/");
|
||||
System.out.println("Layer:");
|
||||
System.out.println(recursiveList("layer", -1, true));
|
||||
System.out.println("Main:");
|
||||
System.out.println(recursiveList("main", -1, true));
|
||||
fService.createAVMStore("layer2");
|
||||
fService.createLayeredDirectory("layer:/layer", "layer2:/", "layer");
|
||||
loader.recursiveLoad("config/alfresco/bootstrap", "layer2:/layer/bootstrap");
|
||||
fService.createSnapshot("layer2");
|
||||
diffs = fSyncService.compare(-1, "layer2:/layer", -1, "layer:/layer");
|
||||
assertEquals(1, diffs.size());
|
||||
fSyncService.update(diffs, false, false, false, false);
|
||||
diffs = fSyncService.compare(-1, "layer2:/layer", -1, "layer:/layer");
|
||||
assertEquals(0, diffs.size());
|
||||
fSyncService.flatten("layer2:/layer", "layer:/layer");
|
||||
diffs = fSyncService.compare(-1, "layer:/layer", -1, "main:/");
|
||||
assertEquals(1, diffs.size());
|
||||
System.out.println("Layer2:");
|
||||
System.out.println(recursiveList("layer2", -1, true));
|
||||
System.out.println("Layer:");
|
||||
System.out.println(recursiveList("layer", -1, true));
|
||||
System.out.println("Main:");
|
||||
System.out.println(recursiveList("main", -1, true));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace(System.err);
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the flatten operation, with a little bit of compare and update.
|
||||
*/
|
||||
|
@@ -392,22 +392,40 @@ public class AVMSyncServiceImpl implements AVMSyncService
|
||||
*/
|
||||
private void recursiveCopy(String parentPath, String name, AVMNodeDescriptor toCopy)
|
||||
{
|
||||
// TODO Can we just do a link if it's a plain directory.
|
||||
// If it's a file or deleted simply link it in.
|
||||
if (toCopy.isFile() || toCopy.isDeleted())
|
||||
fAVMService.createDirectory(parentPath, name);
|
||||
String newParentPath = AVMNodeConverter.ExtendAVMPath(parentPath, name);
|
||||
AVMNodeDescriptor parentDesc = fAVMService.lookup(-1, newParentPath, true);
|
||||
Map<String, AVMNodeDescriptor> children =
|
||||
fAVMService.getDirectoryListing(toCopy, true);
|
||||
for (Map.Entry<String, AVMNodeDescriptor> entry : children.entrySet())
|
||||
{
|
||||
fAVMService.link(parentPath, name, toCopy);
|
||||
recursiveCopy(parentDesc, entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcutting helper that uses an AVMNodeDescriptor parent.
|
||||
* @param parent The parent we are linking into.
|
||||
* @param name The name to link in.
|
||||
* @param toCopy The node to link in.
|
||||
*/
|
||||
private void recursiveCopy(AVMNodeDescriptor parent, String name, AVMNodeDescriptor toCopy)
|
||||
{
|
||||
// If it's a file or deleted simply link it in.
|
||||
if (toCopy.isFile() || toCopy.isDeleted() || toCopy.isPlainDirectory())
|
||||
{
|
||||
fAVMService.link(parent, name, toCopy);
|
||||
return;
|
||||
}
|
||||
// Otherwise make a directory in the target parent, and recursiveCopy all the source
|
||||
// children into it.
|
||||
fAVMService.createDirectory(parentPath, name);
|
||||
String newParentPath = AVMNodeConverter.ExtendAVMPath(parentPath, name);
|
||||
fAVMService.createDirectory(parent.getPath(), name);
|
||||
AVMNodeDescriptor newParentDesc = fAVMService.lookup(parent, name);
|
||||
Map<String, AVMNodeDescriptor> children =
|
||||
fAVMService.getDirectoryListing(-1, toCopy.getPath(), true);
|
||||
fAVMService.getDirectoryListing(toCopy, true);
|
||||
for (Map.Entry<String, AVMNodeDescriptor> entry : children.entrySet())
|
||||
{
|
||||
recursiveCopy(newParentPath, entry.getKey(), entry.getValue());
|
||||
recursiveCopy(newParentDesc, entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -577,7 +595,7 @@ public class AVMSyncServiceImpl implements AVMSyncService
|
||||
}
|
||||
// Grab the listing
|
||||
Map<String, AVMNodeDescriptor> underListing =
|
||||
fAVMService.getDirectoryListing(-1, underlying.getPath(), true);
|
||||
fAVMService.getDirectoryListing(underlying, true);
|
||||
boolean flattened = true;
|
||||
for (String name : layerListing.keySet())
|
||||
{
|
||||
|
@@ -131,4 +131,12 @@ public interface DirectoryNode extends AVMNode
|
||||
* @param toLink The node to link in.
|
||||
*/
|
||||
public void link(Lookup lPath, String name, AVMNodeDescriptor toLink);
|
||||
|
||||
/**
|
||||
* Dangerous version of link that assumes that a child node of
|
||||
* the given name does not already exist.
|
||||
* @param name The name to give the child.
|
||||
* @param toLink The child to link in.
|
||||
*/
|
||||
public void link(String name, AVMNodeDescriptor toLink);
|
||||
}
|
@@ -17,6 +17,10 @@
|
||||
|
||||
package org.alfresco.repo.avm;
|
||||
|
||||
import org.alfresco.service.cmr.avm.AVMBadArgumentException;
|
||||
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
||||
import org.alfresco.service.cmr.avm.AVMNotFoundException;
|
||||
|
||||
/**
|
||||
* Base class for Directories.
|
||||
* @author britt
|
||||
@@ -40,4 +44,26 @@ abstract class DirectoryNodeImpl extends AVMNodeImpl implements DirectoryNode
|
||||
{
|
||||
super(id, repo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dangerous version of link.
|
||||
* @param name The name to give the child.
|
||||
* @param toLink The child to link in.
|
||||
*/
|
||||
public void link(String name, AVMNodeDescriptor toLink)
|
||||
{
|
||||
AVMNode node = AVMContext.fgInstance.fAVMNodeDAO.getByID(toLink.getId());
|
||||
if (node == null)
|
||||
{
|
||||
throw new AVMNotFoundException("Child node not found.");
|
||||
}
|
||||
if (node.getType() == AVMNodeType.LAYERED_DIRECTORY &&
|
||||
!((LayeredDirectoryNode)node).getPrimaryIndirection())
|
||||
{
|
||||
throw new AVMBadArgumentException("Non primary layered directories cannot be linked.");
|
||||
}
|
||||
// Make the new ChildEntry and save.
|
||||
ChildEntry newChild = new ChildEntryImpl(name, this, node);
|
||||
AVMContext.fgInstance.fChildEntryDAO.save(newChild);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user