Rejiggered ChildEntry and its mapping, for considerably better performance. Actually

it was kind of a Doh! moment.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@4336 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Britt Park
2006-11-12 13:53:29 +00:00
parent ae4ba1126e
commit fa0bb97dc1
13 changed files with 344 additions and 320 deletions

View File

@@ -1,121 +0,0 @@
/*
* 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 java.util.ArrayList;
import java.util.List;
import org.alfresco.repo.avm.util.BulkLoader;
/**
* Another performance test that runs simultaneous crawlers that
* do operations with locality of reference.
* @author britt
*/
public class AVMCrawlTest extends AVMServiceTestBase
{
/**
* Do the crawl test.
*/
public void testCrawl()
{
// int n = 1; // Number of Threads.
// int m = 1; // How many multiples of content to start with.
// long runTime = 120000; // 2 minutes
// fService.purgeAVMStore("main");
// BulkLoader loader = new BulkLoader();
// loader.setAvmService(fService);
// for (int i = 0; i < m; i++)
// {
// fService.createAVMStore("d" + i);
// loader.recursiveLoad("source", "d" + i + ":/");
// fService.createSnapshot("d" + i, null, null);
// }
// long startTime = System.currentTimeMillis();
// List<AVMCrawler> crawlers = new ArrayList<AVMCrawler>();
// List<Thread> threads = new ArrayList<Thread>();
// for (int i = 0; i < n; i++)
// {
// crawlers.add(new AVMCrawler(fService));
// threads.add(new Thread(crawlers.get(i)));
// threads.get(i).start();
// }
// while (true)
// {
// try
// {
// Thread.sleep(5000);
// // Check that none of the crawlers has errored out.
// for (AVMCrawler crawler : crawlers)
// {
// if (crawler.getError())
// {
// for (AVMCrawler craw : crawlers)
// {
// craw.setDone();
// }
// for (Thread thread : threads)
// {
// try
// {
// thread.join();
// }
// catch (InterruptedException ie)
// {
// // Do nothing.
// }
// }
// fail();
// }
// }
// }
// catch (InterruptedException ie)
// {
// // Do nothing.
// }
// long now = System.currentTimeMillis();
// if (now - startTime > runTime)
// {
// break;
// }
// }
// for (AVMCrawler crawler : crawlers)
// {
// crawler.setDone();
// }
// for (Thread thread : threads)
// {
// try
// {
// thread.join();
// }
// catch (InterruptedException ie)
// {
// // Do nothing.
// }
// }
// long ops = 0L;
// for (AVMCrawler crawler : crawlers)
// {
// ops += crawler.getOpCount();
// }
// long time = System.currentTimeMillis() - startTime;
// System.out.println("Ops/Sec: " + (ops * 1000L / time));
}
}

View File

@@ -0,0 +1,121 @@
/*
* 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 java.util.ArrayList;
import java.util.List;
import org.alfresco.repo.avm.util.BulkLoader;
/**
* Another performance test that runs simultaneous crawlers that
* do operations with locality of reference.
* @author britt
*/
public class AVMCrawlTestP extends AVMServiceTestBase
{
/**
* Do the crawl test.
*/
public void testCrawl()
{
int n = 2; // Number of Threads.
int m = 4; // How many multiples of content to start with.
long runTime = 300000; // 5 minutes
fService.purgeAVMStore("main");
BulkLoader loader = new BulkLoader();
loader.setAvmService(fService);
for (int i = 0; i < m; i++)
{
fService.createAVMStore("d" + i);
loader.recursiveLoad("source", "d" + i + ":/");
fService.createSnapshot("d" + i, null, null);
}
long startTime = System.currentTimeMillis();
List<AVMCrawler> crawlers = new ArrayList<AVMCrawler>();
List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < n; i++)
{
crawlers.add(new AVMCrawler(fService));
threads.add(new Thread(crawlers.get(i)));
threads.get(i).start();
}
while (true)
{
try
{
Thread.sleep(5000);
// Check that none of the crawlers has errored out.
for (AVMCrawler crawler : crawlers)
{
if (crawler.getError())
{
for (AVMCrawler craw : crawlers)
{
craw.setDone();
}
for (Thread thread : threads)
{
try
{
thread.join();
}
catch (InterruptedException ie)
{
// Do nothing.
}
}
fail();
}
}
}
catch (InterruptedException ie)
{
// Do nothing.
}
long now = System.currentTimeMillis();
if (now - startTime > runTime)
{
break;
}
}
for (AVMCrawler crawler : crawlers)
{
crawler.setDone();
}
for (Thread thread : threads)
{
try
{
thread.join();
}
catch (InterruptedException ie)
{
// Do nothing.
}
}
long ops = 0L;
for (AVMCrawler crawler : crawlers)
{
ops += crawler.getOpCount();
}
long time = System.currentTimeMillis() - startTime;
System.out.println("Ops/Sec: " + (ops * 1000L / time));
}
}

View File

@@ -1145,9 +1145,9 @@ public class AVMRepository
List<ChildEntry> entries = AVMDAOs.Instance().fChildEntryDAO.getByChild(node);
for (ChildEntry entry : entries)
{
String name = entry.getName();
String name = entry.getKey().getName();
components.add(name);
AVMNode parent = entry.getParent();
AVMNode parent = entry.getKey().getParent();
recursiveGetPaths(parent, components, paths);
components.remove(components.size() - 1);
}
@@ -1175,9 +1175,9 @@ public class AVMRepository
List<ChildEntry> entries = AVMDAOs.Instance().fChildEntryDAO.getByChild(node);
for (ChildEntry entry : entries)
{
String name = entry.getName();
String name = entry.getKey().getName();
components.add(name);
AVMNode parent = entry.getParent();
AVMNode parent = entry.getKey().getParent();
recursiveGetHeadPaths(parent, components, paths);
components.remove(components.size() - 1);
}
@@ -1201,9 +1201,9 @@ public class AVMRepository
List<ChildEntry> entries = AVMDAOs.Instance().fChildEntryDAO.getByChild(node);
for (ChildEntry entry : entries)
{
String name = entry.getName();
String name = entry.getKey().getName();
components.add(name);
AVMNode parent = entry.getParent();
AVMNode parent = entry.getKey().getParent();
recursiveGetHeadPaths(parent, components, paths);
components.remove(components.size() - 1);
}

View File

@@ -72,7 +72,7 @@ public class AVMServiceTestBase extends TestCase
{
if (fContext == null)
{
fContext = new FileSystemXmlApplicationContext("config/alfresco/avm-test-context.xml");
fContext = new FileSystemXmlApplicationContext("config/alfresco/application-context.xml");
fService = (AVMService)fContext.getBean("AVMService");
fReaper = (OrphanReaper)fContext.getBean("orphanReaper");
fSyncService = (AVMSyncService)fContext.getBean("AVMSyncService");

View File

@@ -24,28 +24,16 @@ package org.alfresco.repo.avm;
public interface ChildEntry
{
/**
* Set the name of the child.
* @param name
* Set the key for this ChildEntry.
* @param key The ChildKey.
*/
public void setName(String name);
public void setKey(ChildKey key);
/**
* Get the name of the child.
* @return The child's name.
* Get the ChildKey for this ChildEntry.
* @return
*/
public String getName();
/**
* Set the parent in this entry.
* @param parent
*/
public void setParent(DirectoryNode parent);
/**
* Get the parent of this child.
* @return The parent.
*/
public DirectoryNode getParent();
public ChildKey getKey();
/**
* Set the child in this entry.

View File

@@ -37,7 +37,7 @@ public interface ChildEntryDAO
* @param parent The parent to look in.
* @return The ChildEntry or null if not foun.
*/
public ChildEntry getByNameParent(String name, DirectoryNode parent);
public ChildEntry get(ChildKey key);
/**
* Get all the children of a given parent.

View File

@@ -23,35 +23,20 @@ import java.io.Serializable;
* An entry in a directory. Contains a name, parent, and child.
* @author britt
*/
class ChildEntryImpl implements ChildEntry, Serializable
public class ChildEntryImpl implements ChildEntry, Serializable
{
private static final long serialVersionUID = -307752114272916930L;
/**
* The primary key.
* The key.
*/
private Long fID;
/**
* The name of the entry.
*/
private String fName;
/**
* The parent.
*/
private DirectoryNode fParent;
private ChildKey fKey;
/**
* The child.
*/
private AVMNode fChild;
/**
* The Optimistic lock version
*/
private long fVers;
/**
* Default constructor for Hibernate.
*/
@@ -61,55 +46,34 @@ class ChildEntryImpl implements ChildEntry, Serializable
/**
* Make up a brand new entry.
* @param name
* @param parent
* @param child
* @param key The ChildKey.
* @param child The child.
*/
public ChildEntryImpl(String name,
DirectoryNode parent,
public ChildEntryImpl(ChildKey key,
AVMNode child)
{
fName = name;
fParent = parent;
fKey = key;
fChild = child;
}
/**
* Set the key for this ChildEntry.
* @param key The ChildKey.
*/
public void setKey(ChildKey key)
{
fKey = key;
}
/**
* Set the name of this entry.
* @param name
* Get the ChildKey for this ChildEntry.
* @return
*/
public void setName(String name)
public ChildKey getKey()
{
fName = name;
return fKey;
}
/**
* Get the name of this entry.
* @return The name of this entry.
*/
public String getName()
{
return fName;
}
/**
* Set the parent in this entry.
* @param parent
*/
public void setParent(DirectoryNode parent)
{
fParent = parent;
}
/**
* Get the parent in this entry.
* @return The parent.
*/
public DirectoryNode getParent()
{
return fParent;
}
/**
* Set the child in this entry.
* @param child
@@ -145,7 +109,7 @@ class ChildEntryImpl implements ChildEntry, Serializable
return false;
}
ChildEntry other = (ChildEntry)obj;
return fName.equals(other.getName()) && fParent.equals(other.getParent());
return fKey.equals(other.getKey());
}
/**
@@ -155,42 +119,6 @@ class ChildEntryImpl implements ChildEntry, Serializable
@Override
public int hashCode()
{
return fName.hashCode() + fParent.hashCode();
}
/**
* Get the version for optimistic locking.
* @return The version for optimistic locking.
*/
protected long getVers()
{
return fVers;
}
/**
* Set the version for optimistic locking.
* @param vers the vers to set
*/
protected void setVers(long vers)
{
fVers = vers;
}
/**
* Set the primary key. (For Hibernate)
* @param id
*/
protected void setId(Long id)
{
fID = id;
}
/**
* Get the primary key. (For Hibernate).
* @return The primary key.
*/
protected Long getId()
{
return fID;
return fKey.hashCode();
}
}

View File

@@ -0,0 +1,116 @@
/*
* 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 java.io.Serializable;
/**
* The key to a ChildEntry, a Parent and a name.
* @author britt
*/
public class ChildKey implements Serializable
{
private static final long serialVersionUID = 2033634095972856432L;
/**
* The Parent.
*/
private DirectoryNode fParent;
/**
* The child's name.
*/
private String fName;
/**
* Construct one with parameters.
* @param parent The parent directory.
* @param name The name of the child.
*/
public ChildKey(DirectoryNode parent, String name)
{
fParent = parent;
fName = name;
}
/**
* A Default Constructor.
*/
public ChildKey()
{
}
/**
* Set the parent.
*/
public void setParent(DirectoryNode parent)
{
fParent = parent;
}
/**
* Get the parent.
* @return A DirectoryNode.
*/
public DirectoryNode getParent()
{
return fParent;
}
/**
* Set the name.
*/
public void setName(String name)
{
fName = name;
}
/**
* Get the name.
*/
public String getName()
{
return fName;
}
/**
* Override of equals.
*/
@Override
public boolean equals(Object other)
{
if (this == other)
{
return true;
}
if (!(other instanceof ChildKey))
{
return false;
}
ChildKey o = (ChildKey)other;
return fParent.equals(o.getParent()) &&
fName.equals(o.getName());
}
/**
* Override of hashCode.
*/
public int hashCode()
{
return fParent.hashCode() + fName.hashCode();
}
}

View File

@@ -63,7 +63,8 @@ abstract class DirectoryNodeImpl extends AVMNodeImpl implements DirectoryNode
throw new AVMBadArgumentException("Non primary layered directories cannot be linked.");
}
// Make the new ChildEntry and save.
ChildEntry newChild = new ChildEntryImpl(name, this, node);
ChildKey key = new ChildKey(this, name);
ChildEntry newChild = new ChildEntryImpl(key, node);
AVMDAOs.Instance().fChildEntryDAO.save(newChild);
}
}

View File

@@ -108,8 +108,8 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
AVMDAOs.Instance().fAVMNodeDAO.save(this);
for (ChildEntry child : AVMDAOs.Instance().fChildEntryDAO.getByParent(other))
{
ChildEntryImpl newChild = new ChildEntryImpl(child.getName(),
this,
ChildKey key = new ChildKey(this, child.getKey().getName());
ChildEntryImpl newChild = new ChildEntryImpl(key,
child.getChild());
AVMDAOs.Instance().fChildEntryDAO.save(newChild);
}
@@ -142,8 +142,8 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
{
for (ChildEntry child : AVMDAOs.Instance().fChildEntryDAO.getByParent(other))
{
ChildEntryImpl newChild = new ChildEntryImpl(child.getName(),
this,
ChildKey key = new ChildKey(this, child.getKey().getName());
ChildEntryImpl newChild = new ChildEntryImpl(key,
child.getChild());
AVMDAOs.Instance().fChildEntryDAO.save(newChild);
}
@@ -280,7 +280,8 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
*/
public void putChild(String name, AVMNode node)
{
ChildEntry existing = AVMDAOs.Instance().fChildEntryDAO.getByNameParent(name, this);
ChildKey key = new ChildKey(this, name);
ChildEntry existing = AVMDAOs.Instance().fChildEntryDAO.get(key);
if (existing != null)
{
existing.setChild(node);
@@ -288,7 +289,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
}
else
{
ChildEntry entry = new ChildEntryImpl(name, this, node);
ChildEntry entry = new ChildEntryImpl(key, node);
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fChildEntryDAO.save(entry);
}
@@ -337,11 +338,11 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
{
if (!includeDeleted && entry.getChild().getType() == AVMNodeType.DELETED_NODE)
{
listing.remove(entry.getName());
listing.remove(entry.getKey().getName());
}
else
{
listing.put(entry.getName(), entry.getChild());
listing.put(entry.getKey().getName(), entry.getChild());
}
}
return listing;
@@ -359,7 +360,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
{
if (includeDeleted || entry.getChild().getType() != AVMNodeType.DELETED_NODE)
{
listing.put(entry.getName(), entry.getChild());
listing.put(entry.getKey().getName(), entry.getChild());
}
}
return listing;
@@ -384,8 +385,8 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
continue;
}
AVMNodeDescriptor childDesc =
childNode.getDescriptor(dir.getPath(), child.getName(), dir.getIndirection());
listing.put(child.getName(), childDesc);
childNode.getDescriptor(dir.getPath(), child.getKey().getName(), dir.getIndirection());
listing.put(child.getKey().getName(), childDesc);
}
return listing;
}
@@ -425,13 +426,13 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
{
if (!includeDeleted && child.getChild().getType() == AVMNodeType.DELETED_NODE)
{
baseListing.remove(child.getName());
baseListing.remove(child.getKey().getName());
}
else
{
baseListing.put(child.getName(),
baseListing.put(child.getKey().getName(),
child.getChild().getDescriptor(dir.getPath(),
child.getName(),
child.getKey().getName(),
dir.getIndirection()));
}
}
@@ -450,7 +451,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
{
if (entry.getChild().getType() == AVMNodeType.DELETED_NODE)
{
listing.add(entry.getName());
listing.add(entry.getKey().getName());
}
}
return listing;
@@ -467,7 +468,8 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
@SuppressWarnings("unchecked")
public AVMNode lookupChild(Lookup lPath, String name, boolean includeDeleted)
{
ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.getByNameParent(name, this);
ChildKey key = new ChildKey(this, name);
ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key);
if (entry != null)
{
if (!includeDeleted && entry.getChild().getType() == AVMNodeType.DELETED_NODE)
@@ -508,7 +510,8 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
{
throw new AVMBadArgumentException("Illegal null argument.");
}
ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.getByNameParent(name, this);
ChildKey key = new ChildKey(this, name);
ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key);
if (entry != null)
{
if (!includeDeleted && entry.getChild().getType() == AVMNodeType.DELETED_NODE)
@@ -549,7 +552,8 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
@SuppressWarnings("unchecked")
public void removeChild(Lookup lPath, String name)
{
ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.getByNameParent(name, this);
ChildKey key = new ChildKey(this, name);
ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key);
AVMNode child = null;
if (entry != null)
{
@@ -627,7 +631,8 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
*/
public void uncover(Lookup lPath, String name)
{
ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.getByNameParent(name, this);
ChildKey key = new ChildKey(this, name);
ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key);
if (entry.getChild().getType() != AVMNodeType.DELETED_NODE)
{
throw new AVMException("One can only uncover deleted nodes.");
@@ -798,6 +803,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
}
// Look for an existing child of that name.
AVMNode existing = lookupChild(lPath, name, true);
ChildKey key = new ChildKey(this, name);
if (existing != null)
{
if (existing.getType() != AVMNodeType.DELETED_NODE)
@@ -809,13 +815,13 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
// directory do we delete it.
if (directlyContains(existing))
{
ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.getByNameParent(name, this);
ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key);
AVMDAOs.Instance().fChildEntryDAO.delete(entry);
AVMDAOs.Instance().fAVMNodeDAO.flush();
}
}
// Make the new ChildEntry and save.
ChildEntry newChild = new ChildEntryImpl(name, this, node);
ChildEntry newChild = new ChildEntryImpl(key, node);
AVMDAOs.Instance().fChildEntryDAO.save(newChild);
}
@@ -825,7 +831,8 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
*/
public void flatten(String name)
{
ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.getByNameParent(name, this);
ChildKey key = new ChildKey(this, name);
ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key);
if (entry != null)
{
AVMDAOs.Instance().fChildEntryDAO.delete(entry);

View File

@@ -68,8 +68,8 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
AVMDAOs.Instance().fAVMNodeDAO.save(this);
for (ChildEntry child : AVMDAOs.Instance().fChildEntryDAO.getByParent(other))
{
ChildEntry newChild = new ChildEntryImpl(child.getName(),
this,
ChildKey key = new ChildKey(this, child.getKey().getName());
ChildEntry newChild = new ChildEntryImpl(key,
child.getChild());
AVMDAOs.Instance().fChildEntryDAO.save(newChild);
}
@@ -105,7 +105,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
{
continue;
}
result.put(child.getName(), child.getChild());
result.put(child.getKey().getName(), child.getChild());
}
return result;
}
@@ -151,8 +151,10 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
{
continue;
}
result.put(child.getName(),
child.getChild().getDescriptor(dir.getPath(), child.getName(), dir.getIndirection()));
result.put(child.getKey().getName(),
child.getChild().getDescriptor(dir.getPath(),
child.getKey().getName(),
dir.getIndirection()));
}
return result;
}
@@ -176,7 +178,8 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
@SuppressWarnings("unchecked")
public AVMNode lookupChild(Lookup lPath, String name, boolean includeDeleted)
{
ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.getByNameParent(name, this);
ChildKey key = new ChildKey(this, name);
ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key);
if (entry == null ||
(!includeDeleted && entry.getChild().getType() == AVMNodeType.DELETED_NODE))
{
@@ -199,7 +202,8 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
{
throw new AVMBadArgumentException("Path is null.");
}
ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.getByNameParent(name, this);
ChildKey key = new ChildKey(this, name);
ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key);
if (entry == null ||
(!includeDeleted && entry.getChild().getType() == AVMNodeType.DELETED_NODE))
{
@@ -216,7 +220,8 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
@SuppressWarnings("unchecked")
public void removeChild(Lookup lPath, String name)
{
ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.getByNameParent(name, this);
ChildKey key = new ChildKey(this, name);
ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key);
if (entry != null)
{
AVMNode child = entry.getChild();
@@ -241,7 +246,8 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
*/
public void putChild(String name, AVMNode node)
{
ChildEntry existing = AVMDAOs.Instance().fChildEntryDAO.getByNameParent(name, this);
ChildKey key = new ChildKey(this, name);
ChildEntry existing = AVMDAOs.Instance().fChildEntryDAO.get(key);
if (existing != null)
{
existing.setChild(node);
@@ -249,7 +255,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
}
else
{
ChildEntry entry = new ChildEntryImpl(name, this, node);
ChildEntry entry = new ChildEntryImpl(key, node);
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fChildEntryDAO.save(entry);
}
@@ -433,7 +439,8 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
throw new AVMBadArgumentException("Non primary layered directories cannot be linked.");
}
// Check for an existing child by the given name.
ChildEntry child = AVMDAOs.Instance().fChildEntryDAO.getByNameParent(name, this);
ChildKey key = new ChildKey(this, name);
ChildEntry child = AVMDAOs.Instance().fChildEntryDAO.get(key);
if (child != null)
{
if (child.getChild().getType() != AVMNodeType.DELETED_NODE)
@@ -447,7 +454,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
AVMDAOs.Instance().fAVMNodeDAO.flush();
}
// Make the new entry and save.
ChildEntry newChild = new ChildEntryImpl(name, this, node);
ChildEntry newChild = new ChildEntryImpl(key, node);
AVMDAOs.Instance().fChildEntryDAO.save(newChild);
}
}

View File

@@ -135,19 +135,15 @@
<property name="tag" type="string" length="255" column="tag"/>
<property name="description" type="string" length="8192" column="description"/>
</class>
<class name="ChildEntryImpl" proxy="ChildEntry" table="avm_child_entries" optimistic-lock="version">
<cache usage="read-write"/>
<id name="id" column="id" type="long">
<generator class="native"/>
</id>
<natural-id>
<property name="name" type="string" length="160" column="name" index="child_name_index" not-null="true"/>
<many-to-one name="parent" column="parent_id" class="DirectoryNodeImpl" not-null="true"/>
</natural-id>
<version name="vers" column="vers" type="long"/>
<many-to-one name="child" column="child_id" class="AVMNodeImpl"
not-null="true"/>
</class>
<class name="ChildEntryImpl" proxy="ChildEntry" table="avm_child_entries">
<cache usage="read-write"/>
<composite-id name="key" class="ChildKey">
<key-many-to-one name="parent" column="parent_id" class="DirectoryNodeImpl"/>
<key-property name="name" column="name" type="string" length="160"/>
</composite-id>
<many-to-one name="child" column="child_id" class="AVMNodeImpl"
not-null="true"/>
</class>
<class name="HistoryLinkImpl" proxy="HistoryLink" table="avm_history_links">
<composite-id>
<key-many-to-one name="ancestor" class="AVMNodeImpl" column="ancestor"/>
@@ -204,31 +200,10 @@
<many-to-one name="node" class="AVMNodeImpl" column="node_id"/>
<property name="name" column="qname" type="QName" length="200"/>
</class>
<query name="ChildEntry.ByNameParent">
<![CDATA[
from ChildEntryImpl ce
where
ce.name = :name and ce.parent = :parent
]]>
</query>
<query name="ChildEntry.ByParent">
<![CDATA[
from ChildEntryImpl ce
where
ce.parent = :parent
]]>
</query>
<query name="ChildEntry.ByParentChild">
<![CDATA[
from ChildEntryImpl ce
where
ce.child = :child and ce.parent = :parent
]]>
</query>
<query name="ChildEntry.DeleteByParent">
<![CDATA[
delete ChildEntryImpl ce
where ce.parent = :parent
where ce.key.parent = :parent
]]>
</query>
<query name="AVMNode.GetNewInStore">

View File

@@ -21,7 +21,9 @@ import java.util.List;
import org.alfresco.repo.avm.AVMNode;
import org.alfresco.repo.avm.ChildEntry;
import org.alfresco.repo.avm.ChildEntryImpl;
import org.alfresco.repo.avm.ChildEntryDAO;
import org.alfresco.repo.avm.ChildKey;
import org.alfresco.repo.avm.DirectoryNode;
import org.hibernate.Query;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
@@ -56,13 +58,9 @@ class ChildEntryDAOHibernate extends HibernateDaoSupport implements
* @param parent The parent to look in.
* @return The ChildEntry or null if not foun.
*/
public ChildEntry getByNameParent(String name, DirectoryNode parent)
public ChildEntry get(ChildKey key)
{
Query query = getSession().createQuery(
"from ChildEntryImpl ce where ce.name = :name and ce.parent = :parent");
query.setString("name", name);
query.setEntity("parent", parent);
return (ChildEntry)query.uniqueResult();
return (ChildEntry)getSession().get(ChildEntryImpl.class, key);
}
/**
@@ -73,7 +71,8 @@ class ChildEntryDAOHibernate extends HibernateDaoSupport implements
@SuppressWarnings("unchecked")
public List<ChildEntry> getByParent(DirectoryNode parent)
{
Query query = getSession().getNamedQuery("ChildEntry.ByParent");
Query query =
getSession().createQuery("from ChildEntryImpl ce where ce.key.parent = :parent");
query.setEntity("parent", parent);
return (List<ChildEntry>)query.list();
}
@@ -86,7 +85,9 @@ class ChildEntryDAOHibernate extends HibernateDaoSupport implements
*/
public ChildEntry getByParentChild(DirectoryNode parent, AVMNode child)
{
Query query = getSession().getNamedQuery("ChildEntry.ByParentChild");
Query query =
getSession().createQuery("from ChildEntryImpl ce where ce.key.parent = :parent " +
"and ce.child = :child");
query.setEntity("parent", parent);
query.setEntity("child", child);
return (ChildEntry)query.uniqueResult();
@@ -124,6 +125,7 @@ class ChildEntryDAOHibernate extends HibernateDaoSupport implements
getSession().delete(child);
}
// TODO Does this have dangerous interactions with the cache?
/**
* Delete all children of the given parent.
* @param parent The parent.