Various changes to keep Hibernate session caches from growing without bound.

Deleting AVM locks is considerably faster which makes large submits faster.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6935 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Britt Park 2007-10-09 01:11:19 +00:00
parent 2a47726733
commit 4489bd0a22
12 changed files with 341 additions and 172 deletions

View File

@ -15,11 +15,11 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of * As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre * the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's * and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing * FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here: * the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing * http://www.alfresco.com/legal/licensing
*/ */
@ -41,13 +41,13 @@ public interface AttributeDAO
* @param attr The attribute to save. * @param attr The attribute to save.
*/ */
public void save(Attribute attr); public void save(Attribute attr);
/** /**
* Delete an attribute (recursively). * Delete an attribute (recursively).
* @param attr The attribute to delete. * @param attr The attribute to delete.
*/ */
public void delete(Attribute attr); public void delete(Attribute attr);
/** /**
* Find all attributes that match a given path and AttrQuery. * Find all attributes that match a given path and AttrQuery.
* @param map The map within which to query. * @param map The map within which to query.
@ -55,11 +55,17 @@ public interface AttributeDAO
* @return A List of key, attribute value pairs. * @return A List of key, attribute value pairs.
*/ */
public List<Pair<String,Attribute>> find(MapAttribute map, AttrQuery query); public List<Pair<String,Attribute>> find(MapAttribute map, AttrQuery query);
/** /**
* Delete entries from a map that match the given query. * Delete entries from a map that match the given query.
* @param map * @param map
* @param query * @param query
*/ */
public void delete(MapAttribute map, AttrQuery query); public void delete(MapAttribute map, AttrQuery query);
/**
* Evict an Attribute from the session cache.
* @param attr
*/
public void evict(Attribute attr);
} }

View File

@ -15,11 +15,11 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of * As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre * the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's * and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing * FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here: * the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing * http://www.alfresco.com/legal/licensing
*/ */
@ -44,30 +44,30 @@ import org.alfresco.util.Pair;
public class AttributeServiceImpl implements AttributeService public class AttributeServiceImpl implements AttributeService
{ {
private GlobalAttributeEntryDAO fGlobalAttributeEntryDAO; private GlobalAttributeEntryDAO fGlobalAttributeEntryDAO;
private AttributeDAO fAttributeDAO; private AttributeDAO fAttributeDAO;
private AttributeConverter fAttributeConverter; private AttributeConverter fAttributeConverter;
public AttributeServiceImpl() public AttributeServiceImpl()
{ {
} }
public void setGlobalAttributeEntryDao(GlobalAttributeEntryDAO dao) public void setGlobalAttributeEntryDao(GlobalAttributeEntryDAO dao)
{ {
fGlobalAttributeEntryDAO = dao; fGlobalAttributeEntryDAO = dao;
} }
public void setAttributeDao(AttributeDAO dao) public void setAttributeDao(AttributeDAO dao)
{ {
fAttributeDAO = dao; fAttributeDAO = dao;
} }
public void setAttributeConverter(AttributeConverter converter) public void setAttributeConverter(AttributeConverter converter)
{ {
fAttributeConverter = converter; fAttributeConverter = converter;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.attributes.AttributeService#getAttribute(java.lang.String) * @see org.alfresco.service.cmr.attributes.AttributeService#getAttribute(java.lang.String)
*/ */
@ -93,7 +93,7 @@ public class AttributeServiceImpl implements AttributeService
int off = 0; int off = 0;
while (off < path.length()) while (off < path.length())
{ {
while (off < path.length() && path.charAt(off) == '/') while (off < path.length() && path.charAt(off) == '/')
{ {
off++; off++;
} }
@ -121,7 +121,7 @@ public class AttributeServiceImpl implements AttributeService
} }
return components; return components;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.attributes.AttributeService#query(java.lang.String, org.alfresco.service.cmr.attributes.AttrQuery) * @see org.alfresco.service.cmr.attributes.AttributeService#query(java.lang.String, org.alfresco.service.cmr.attributes.AttrQuery)
*/ */
@ -192,7 +192,9 @@ public class AttributeServiceImpl implements AttributeService
{ {
return null; return null;
} }
return fAttributeConverter.toValue(found); Attribute converted = fAttributeConverter.toValue(found);
fAttributeDAO.evict(found);
return converted;
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -251,7 +253,9 @@ public class AttributeServiceImpl implements AttributeService
{ {
throw new AVMWrongTypeException("Not a Map: " + keys); throw new AVMWrongTypeException("Not a Map: " + keys);
} }
found.put(name, fAttributeConverter.toPersistent(value)); Attribute converted = fAttributeConverter.toPersistent(value);
found.put(name, converted);
fAttributeDAO.evict(converted);
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -278,11 +282,11 @@ public class AttributeServiceImpl implements AttributeService
} }
List<Pair<String, Attribute>> rawResult = List<Pair<String, Attribute>> rawResult =
fAttributeDAO.find((MapAttribute)found, query); fAttributeDAO.find((MapAttribute)found, query);
List<Pair<String, Attribute>> result = List<Pair<String, Attribute>> result =
new ArrayList<Pair<String, Attribute>>(); new ArrayList<Pair<String, Attribute>>();
for (Pair<String, Attribute> raw : rawResult) for (Pair<String, Attribute> raw : rawResult)
{ {
result.add(new Pair<String, Attribute>(raw.getFirst(), result.add(new Pair<String, Attribute>(raw.getFirst(),
fAttributeConverter.toValue(raw.getSecond()))); fAttributeConverter.toValue(raw.getSecond())));
} }
return result; return result;
@ -313,7 +317,7 @@ public class AttributeServiceImpl implements AttributeService
} }
found.remove(name); found.remove(name);
} }
private Attribute getAttributeFromPath(List<String> keys) private Attribute getAttributeFromPath(List<String> keys)
{ {
GlobalAttributeEntry entry = fGlobalAttributeEntryDAO.get(keys.get(0)); GlobalAttributeEntry entry = fGlobalAttributeEntryDAO.get(keys.get(0));
@ -480,7 +484,9 @@ public class AttributeServiceImpl implements AttributeService
{ {
throw new AVMWrongTypeException("Attribute Not List: " + keys); throw new AVMWrongTypeException("Attribute Not List: " + keys);
} }
Attribute converted = fAttributeConverter.toPersistent(value);
found.set(index, fAttributeConverter.toPersistent(value)); found.set(index, fAttributeConverter.toPersistent(value));
fAttributeDAO.evict(converted);
} }
/* (non-Javadoc) /* (non-Javadoc)

View File

@ -15,11 +15,11 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of * As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre * the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's * and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing * FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here: * the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing * http://www.alfresco.com/legal/licensing
*/ */
@ -43,6 +43,8 @@ import org.alfresco.repo.attributes.Attribute.Type;
import org.alfresco.service.cmr.attributes.AttrQuery; import org.alfresco.service.cmr.attributes.AttrQuery;
import org.alfresco.service.cmr.attributes.AttrQueryHelper; import org.alfresco.service.cmr.attributes.AttrQueryHelper;
import org.alfresco.util.Pair; import org.alfresco.util.Pair;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query; import org.hibernate.Query;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport; import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
@ -53,24 +55,26 @@ import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class AttributeDAOHibernate extends HibernateDaoSupport implements public class AttributeDAOHibernate extends HibernateDaoSupport implements
AttributeDAO AttributeDAO
{ {
private static Log fgLogger = LogFactory.getLog(AttributeDAOHibernate.class);
private MapEntryDAO fMapEntryDAO; private MapEntryDAO fMapEntryDAO;
private ListEntryDAO fListEntryDAO; private ListEntryDAO fListEntryDAO;
public AttributeDAOHibernate() public AttributeDAOHibernate()
{ {
} }
public void setMapEntryDao(MapEntryDAO dao) public void setMapEntryDao(MapEntryDAO dao)
{ {
fMapEntryDAO = dao; fMapEntryDAO = dao;
} }
public void setListEntryDao(ListEntryDAO dao) public void setListEntryDao(ListEntryDAO dao)
{ {
fListEntryDAO = dao; fListEntryDAO = dao;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.repo.attributes.AttributeDAO#delete(org.alfresco.repo.attributes.Attribute) * @see org.alfresco.repo.attributes.AttributeDAO#delete(org.alfresco.repo.attributes.Attribute)
*/ */
@ -83,6 +87,7 @@ public class AttributeDAOHibernate extends HibernateDaoSupport implements
for (MapEntry entry : mapEntries) for (MapEntry entry : mapEntries)
{ {
Attribute subAttr = entry.getAttribute(); Attribute subAttr = entry.getAttribute();
getSession().evict(entry);
fMapEntryDAO.delete(entry); fMapEntryDAO.delete(entry);
delete(subAttr); delete(subAttr);
} }
@ -94,10 +99,16 @@ public class AttributeDAOHibernate extends HibernateDaoSupport implements
for (ListEntry entry : listEntries) for (ListEntry entry : listEntries)
{ {
Attribute subAttr = entry.getAttribute(); Attribute subAttr = entry.getAttribute();
getSession().evict(entry);
fListEntryDAO.delete(entry); fListEntryDAO.delete(entry);
delete(subAttr); delete(subAttr);
} }
} }
if (fgLogger.isDebugEnabled())
{
fgLogger.debug("Entities: " + getSession().getStatistics().getEntityCount());
}
getSession().evict(attr);
getSession().delete(attr); getSession().delete(attr);
} }
@ -144,4 +155,26 @@ public class AttributeDAOHibernate extends HibernateDaoSupport implements
{ {
getSession().save(attr); getSession().save(attr);
} }
/* (non-Javadoc)
* @see org.alfresco.repo.attributes.AttributeDAO#evict(org.alfresco.repo.attributes.Attribute)
*/
public void evict(Attribute attr)
{
if (attr.getType() == Attribute.Type.MAP)
{
for (Attribute child : attr.values())
{
evict(child);
}
}
if (attr.getType() == Attribute.Type.LIST)
{
for (Attribute child : attr)
{
evict(child);
}
}
getSession().evict(attr);
}
} }

View File

@ -34,13 +34,13 @@ public interface AVMNodeDAO
* Save the given node, having never been saved before. * Save the given node, having never been saved before.
*/ */
public void save(AVMNode node); public void save(AVMNode node);
/** /**
* Delete a single node. * Delete a single node.
* @param node The node to delete. * @param node The node to delete.
*/ */
public void delete(AVMNode node); public void delete(AVMNode node);
/** /**
* Get by ID. * Get by ID.
* @param id The id to get. * @param id The id to get.
@ -60,63 +60,69 @@ public interface AVMNodeDAO
* @param node The node. * @param node The node.
*/ */
public void update(AVMNode node); public void update(AVMNode node);
/** /**
* Get the ancestor of a node. * Get the ancestor of a node.
* @param node The node whose ancestor is desired. * @param node The node whose ancestor is desired.
* @return The ancestor or null. * @return The ancestor or null.
*/ */
public AVMNode getAncestor(AVMNode node); public AVMNode getAncestor(AVMNode node);
/** /**
* Get the node the given node was merged from. * Get the node the given node was merged from.
* @param node The node whose merged from is desired. * @param node The node whose merged from is desired.
* @return The merged from node or null. * @return The merged from node or null.
*/ */
public AVMNode getMergedFrom(AVMNode node); public AVMNode getMergedFrom(AVMNode node);
/** /**
* Get up to batchSize orphans. * Get up to batchSize orphans.
* @param batchSize Get no more than this number. * @param batchSize Get no more than this number.
* @return A List of orphaned AVMNodes. * @return A List of orphaned AVMNodes.
*/ */
public List<AVMNode> getOrphans(int batchSize); public List<AVMNode> getOrphans(int batchSize);
/** /**
* Get all content urls in he AVM Repository. * Get all content urls in he AVM Repository.
* @return A List of URL Strings. * @return A List of URL Strings.
*/ */
public List<String> getContentUrls(); public List<String> getContentUrls();
/** /**
* Get all the nodes that are new in the given store. * Get all the nodes that are new in the given store.
* @param store The store to query. * @param store The store to query.
* @return A List of AVMNodes. * @return A List of AVMNodes.
*/ */
public List<AVMNode> getNewInStore(AVMStore store); public List<AVMNode> getNewInStore(AVMStore store);
/** /**
* Inappropriate hack to get Hibernate to play nice. * Inappropriate hack to get Hibernate to play nice.
*/ */
public void flush(); public void flush();
/** /**
* Get a batch * Get a batch
* @return An iterator over all nodes. * @return An iterator over all nodes.
*/ */
List<AVMNode> getEmptyGUIDS(int count); List<AVMNode> getEmptyGUIDS(int count);
/** /**
* Get a batch of LayeredDirectories which have null indirectionVersions. * Get a batch of LayeredDirectories which have null indirectionVersions.
* @param count * @param count
* @return * @return
*/ */
List<LayeredDirectoryNode> getNullVersionLayeredDirectories(int count); List<LayeredDirectoryNode> getNullVersionLayeredDirectories(int count);
/** /**
* Get a batch of LayeredFiles which have null indirectionVersions. * Get a batch of LayeredFiles which have null indirectionVersions.
* @param count * @param count
* @return * @return
*/ */
List<LayeredFileNode> getNullVersionLayeredFiles(int count); List<LayeredFileNode> getNullVersionLayeredFiles(int count);
/**
* Evict an AVMNode that is no longer going to be used.
* @param node
*/
public void evict(AVMNode node);
} }

View File

@ -339,7 +339,10 @@ public class AVMRepository
} }
dir.putChild(name, child); dir.putChild(name, child);
fLookupCache.onWrite(pathParts[0]); fLookupCache.onWrite(pathParts[0]);
return child.getDescriptor(parent.getPath(), name, parent.getIndirection(), parent.getIndirectionVersion()); AVMNodeDescriptor desc = child.getDescriptor(parent.getPath(), name, parent.getIndirection(), parent.getIndirectionVersion());
fAVMNodeDAO.flush();
fAVMNodeDAO.evict(child);
return desc;
} }
/** /**
@ -2481,6 +2484,7 @@ public class AVMRepository
LayeredDirectoryNode dir = (LayeredDirectoryNode)node; LayeredDirectoryNode dir = (LayeredDirectoryNode)node;
dir.flatten(name); dir.flatten(name);
fAVMNodeDAO.flush(); fAVMNodeDAO.flush();
fAVMNodeDAO.evict(dir);
} }
finally finally
{ {
@ -2511,7 +2515,10 @@ public class AVMRepository
throw new AVMNotFoundException("Path not found."); throw new AVMNotFoundException("Path not found.");
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
return node.getDescriptor(lPath); AVMNodeDescriptor desc = node.getDescriptor(lPath);
fAVMNodeDAO.flush();
fAVMNodeDAO.evict(node);
return desc;
} }
finally finally
{ {
@ -2730,6 +2737,8 @@ public class AVMRepository
{ {
throw new AVMNotFoundException("Node not found: " + desc); throw new AVMNotFoundException("Node not found: " + desc);
} }
return node.getAspects(); Set<QName> aspects = node.getAspects();
fAVMNodeDAO.evict(node);
return aspects;
} }
} }

View File

@ -75,32 +75,32 @@ public class AVMStoreImpl implements AVMStore, Serializable
* The primary key. * The primary key.
*/ */
private long fID; private long fID;
/** /**
* The name of this AVMStore. * The name of this AVMStore.
*/ */
private String fName; private String fName;
/** /**
* The current root directory. * The current root directory.
*/ */
private DirectoryNode fRoot; private DirectoryNode fRoot;
/** /**
* The next version id. * The next version id.
*/ */
private int fNextVersionID; private int fNextVersionID;
/** /**
* The version (for concurrency control). * The version (for concurrency control).
*/ */
private long fVers; private long fVers;
/** /**
* The AVMRepository. * The AVMRepository.
*/ */
transient private AVMRepository fAVMRepository; transient private AVMRepository fAVMRepository;
/** /**
* Default constructor. * Default constructor.
*/ */
@ -108,7 +108,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
fAVMRepository = AVMRepository.GetInstance(); fAVMRepository = AVMRepository.GetInstance();
} }
/** /**
* Make a brand new AVMStore. * Make a brand new AVMStore.
* @param repo The AVMRepository. * @param repo The AVMRepository.
@ -144,7 +144,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
fNextVersionID++; fNextVersionID++;
AVMDAOs.Instance().fVersionRootDAO.save(versionRoot); AVMDAOs.Instance().fVersionRootDAO.save(versionRoot);
} }
/** /**
* Setter for hibernate. * Setter for hibernate.
* @param id The primary key. * @param id The primary key.
@ -153,7 +153,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
fID = id; fID = id;
} }
/** /**
* Get the primary key. * Get the primary key.
* @return The primary key. * @return The primary key.
@ -162,7 +162,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
return fID; return fID;
} }
/** /**
* Set a new root for this. * Set a new root for this.
* @param root * @param root
@ -305,7 +305,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
List<String> paths = fAVMRepository.getVersionPaths(versionRoot, node); List<String> paths = fAVMRepository.getVersionPaths(versionRoot, node);
for (String path : paths) for (String path : paths)
{ {
VersionLayeredNodeEntry entry = VersionLayeredNodeEntry entry =
new VersionLayeredNodeEntryImpl(versionRoot, path); new VersionLayeredNodeEntryImpl(versionRoot, path);
AVMDAOs.Instance().fVersionLayeredNodeEntryDAO.save(entry); AVMDAOs.Instance().fVersionLayeredNodeEntryDAO.save(entry);
} }
@ -361,6 +361,8 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
newDir.getProperties().putAll(properties); newDir.getProperties().putAll(properties);
} }
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(newDir);
} }
/** /**
@ -405,6 +407,8 @@ public class AVMStoreImpl implements AVMStore, Serializable
} }
dir.updateModTime(); dir.updateModTime();
dir.putChild(name, newDir); dir.putChild(name, newDir);
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(newDir);
// newDir.setVersionID(getNextVersionID()); // newDir.setVersionID(getNextVersionID());
} }
@ -436,11 +440,13 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
file.setAncestor(child); file.setAncestor(child);
} }
file.setContentData(new ContentData(null, file.setContentData(new ContentData(null,
RawServices.Instance().getMimetypeService().guessMimetype(name), RawServices.Instance().getMimetypeService().guessMimetype(name),
-1, -1,
"UTF-8")); "UTF-8"));
ContentWriter writer = createContentWriter(AVMNodeConverter.ExtendAVMPath(path, name)); ContentWriter writer = createContentWriter(AVMNodeConverter.ExtendAVMPath(path, name));
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(file);
return writer.getContentOutputStream(); return writer.getContentOutputStream();
} }
@ -472,7 +478,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
file.setAncestor(child); file.setAncestor(child);
} }
file.setContentData(new ContentData(null, file.setContentData(new ContentData(null,
RawServices.Instance().getMimetypeService().guessMimetype(name), RawServices.Instance().getMimetypeService().guessMimetype(name),
-1, -1,
"UTF-8")); "UTF-8"));
@ -484,11 +490,11 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
file.getProperties().putAll(properties); file.getProperties().putAll(properties);
} }
ContentWriter writer = createContentWriter(AVMNodeConverter.ExtendAVMPath(path, name));
// Yet another flush. // Yet another flush.
AVMDAOs.Instance().fAVMNodeDAO.flush(); AVMDAOs.Instance().fAVMNodeDAO.flush();
ContentWriter writer = createContentWriter(AVMNodeConverter.ExtendAVMPath(path, name)); AVMDAOs.Instance().fAVMNodeDAO.evict(file);
writer.putContent(data); writer.putContent(data);
} }
/** /**
@ -520,6 +526,8 @@ public class AVMStoreImpl implements AVMStore, Serializable
} }
dir.updateModTime(); dir.updateModTime();
dir.putChild(name, newFile); dir.putChild(name, newFile);
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(newFile);
// newFile.setVersionID(getNextVersionID()); // newFile.setVersionID(getNextVersionID());
} }
@ -561,7 +569,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
public ContentWriter createContentWriter(String path) public ContentWriter createContentWriter(String path)
{ {
NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, fName + ":" + path); NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, fName + ":" + path);
ContentWriter writer = ContentWriter writer =
RawServices.Instance().getContentService().getWriter(nodeRef, ContentModel.PROP_CONTENT, true); RawServices.Instance().getContentService().getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
return writer; return writer;
} }
@ -572,7 +580,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
* @param path The path to the directory. * @param path The path to the directory.
* @return A List of FolderEntries. * @return A List of FolderEntries.
*/ */
public SortedMap<String, AVMNodeDescriptor> getListing(int version, String path, public SortedMap<String, AVMNodeDescriptor> getListing(int version, String path,
boolean includeDeleted) boolean includeDeleted)
{ {
Lookup lPath = lookupDirectory(version, path, false); Lookup lPath = lookupDirectory(version, path, false);
@ -615,7 +623,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
* @param lPath The Lookup for the directory. * @param lPath The Lookup for the directory.
* @return A Map of names to descriptors. * @return A Map of names to descriptors.
*/ */
private SortedMap<String, AVMNodeDescriptor> private SortedMap<String, AVMNodeDescriptor>
translateListing(Map<String, AVMNode> listing, Lookup lPath) translateListing(Map<String, AVMNode> listing, Lookup lPath)
{ {
SortedMap<String, AVMNodeDescriptor> results = new TreeMap<String, AVMNodeDescriptor>(); SortedMap<String, AVMNodeDescriptor> results = new TreeMap<String, AVMNodeDescriptor>();
@ -625,6 +633,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
AVMNode child = AVMNodeUnwrapper.Unwrap(listing.get(name)); AVMNode child = AVMNodeUnwrapper.Unwrap(listing.get(name));
AVMNodeDescriptor desc = child.getDescriptor(lPath, name); AVMNodeDescriptor desc = child.getDescriptor(lPath, name);
results.put(name, desc); results.put(name, desc);
AVMDAOs.Instance().fAVMNodeDAO.evict(child);
} }
return results; return results;
} }
@ -643,7 +652,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
return dir.getDeletedNames(); List<String> deleted = dir.getDeletedNames();
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(dir);
return deleted;
} }
/** /**
@ -676,6 +688,8 @@ public class AVMStoreImpl implements AVMStore, Serializable
} }
dir.removeChild(lPath, name); dir.removeChild(lPath, name);
dir.updateModTime(); dir.updateModTime();
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(dir);
} }
/** /**
@ -697,11 +711,13 @@ public class AVMStoreImpl implements AVMStore, Serializable
} }
((LayeredDirectoryNode)node).uncover(lPath, name); ((LayeredDirectoryNode)node).uncover(lPath, name);
node.updateModTime(); node.updateModTime();
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(node);
} }
// TODO This is problematic. As time goes on this returns // TODO This is problematic. As time goes on this returns
// larger and larger data sets. Perhaps what we should do is // larger and larger data sets. Perhaps what we should do is
// provide methods for getting versions by date range, n most // provide methods for getting versions by date range, n most
// recent etc. // recent etc.
/** /**
* Get the set of all extant versions for this AVMStore. * Get the set of all extant versions for this AVMStore.
@ -714,7 +730,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
List<VersionDescriptor> descs = new ArrayList<VersionDescriptor>(); List<VersionDescriptor> descs = new ArrayList<VersionDescriptor>();
for (VersionRoot vr : versions) for (VersionRoot vr : versions)
{ {
VersionDescriptor desc = VersionDescriptor desc =
new VersionDescriptor(fName, new VersionDescriptor(fName,
vr.getVersionID(), vr.getVersionID(),
vr.getCreator(), vr.getCreator(),
@ -789,7 +805,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
else else
{ {
root = AVMDAOs.Instance().fAVMNodeDAO.getAVMStoreRoot(this, version); root = AVMDAOs.Instance().fAVMNodeDAO.getAVMStoreRoot(this, version);
} }
return root.getDescriptor(fName + ":", "", null, -1); return root.getDescriptor(fName + ":", "", null, -1);
} }
@ -847,7 +863,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
} }
return lPath.getIndirectionPath(); return lPath.getIndirectionPath();
} }
/** /**
* Make the indicated node a primary indirection. * Make the indicated node a primary indirection.
* @param path The path to the node. * @param path The path to the node.
@ -866,6 +882,8 @@ public class AVMStoreImpl implements AVMStore, Serializable
} }
dir.turnPrimary(lPath); dir.turnPrimary(lPath);
dir.updateModTime(); dir.updateModTime();
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(dir);
} }
/** /**
@ -887,8 +905,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
} }
dir.retarget(lPath, target); dir.retarget(lPath, target);
dir.updateModTime(); dir.updateModTime();
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(dir);
} }
/** /**
* Set the name of this AVMStore. * Set the name of this AVMStore.
* @param name * @param name
@ -897,7 +917,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
fName = name; fName = name;
} }
/** /**
* Get the name of this AVMStore. * Get the name of this AVMStore.
* @return The name. * @return The name.
@ -906,7 +926,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
return fName; return fName;
} }
/** /**
* Set the next version id. * Set the next version id.
* @param nextVersionID * @param nextVersionID
@ -915,7 +935,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
fNextVersionID = nextVersionID; fNextVersionID = nextVersionID;
} }
/** /**
* Get the next version id. * Get the next version id.
* @return The next version id. * @return The next version id.
@ -924,7 +944,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
return fNextVersionID; return fNextVersionID;
} }
/** /**
* This gets the last extant version id. * This gets the last extant version id.
*/ */
@ -941,7 +961,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
fRoot = root; fRoot = root;
} }
/** /**
* Get the root directory. * Get the root directory.
* @return The root directory. * @return The root directory.
@ -950,7 +970,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
return fRoot; return fRoot;
} }
/** /**
* Set the version (for concurrency control). Hibernate. * Set the version (for concurrency control). Hibernate.
* @param vers * @param vers
@ -959,7 +979,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
fVers = vers; fVers = vers;
} }
/** /**
* Get the version (for concurrency control). Hibernate. * Get the version (for concurrency control). Hibernate.
* @return The version. * @return The version.
@ -1035,7 +1055,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
*/ */
public AVMStoreDescriptor getDescriptor() public AVMStoreDescriptor getDescriptor()
{ {
return new AVMStoreDescriptor(fName, return new AVMStoreDescriptor(fName,
getProperty(ContentModel.PROP_CREATOR).getStringValue(), getProperty(ContentModel.PROP_CREATOR).getStringValue(),
((Date)getProperty(ContentModel.PROP_CREATED).getValue(DataTypeDefinition.DATE)).getTime()); ((Date)getProperty(ContentModel.PROP_CREATED).getValue(DataTypeDefinition.DATE)).getTime());
} }
@ -1060,8 +1080,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
} }
((LayeredDirectoryNode)node).setOpacity(opacity); ((LayeredDirectoryNode)node).setOpacity(opacity);
node.updateModTime(); node.updateModTime();
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(node);
} }
// TODO Does it make sense to set properties on DeletedNodes? // TODO Does it make sense to set properties on DeletedNodes?
/** /**
* Set a property on a node. * Set a property on a node.
@ -1079,8 +1101,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
node.setProperty(name, value); node.setProperty(name, value);
node.setGuid(GUID.generate()); node.setGuid(GUID.generate());
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(node);
} }
/** /**
* Set a collection of properties on a node. * Set a collection of properties on a node.
* @param path The path to the node. * @param path The path to the node.
@ -1096,8 +1120,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
node.addProperties(properties); node.addProperties(properties);
node.setGuid(GUID.generate()); node.setGuid(GUID.generate());
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(node);
} }
/** /**
* Get a property by name. * Get a property by name.
* @param version The version to lookup. * @param version The version to lookup.
@ -1113,9 +1139,12 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
return node.getProperty(name); PropertyValue prop = node.getProperty(name);
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(node);
return prop;
} }
/** /**
* Get all the properties associated with a node. * Get all the properties associated with a node.
* @param version The version to lookup. * @param version The version to lookup.
@ -1130,9 +1159,12 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
return node.getProperties(); Map<QName, PropertyValue> props = node.getProperties();
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(node);
return props;
} }
/** /**
* Delete a single property from a node. * Delete a single property from a node.
* @param path The path to the node. * @param path The path to the node.
@ -1148,8 +1180,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
node.setGuid(GUID.generate()); node.setGuid(GUID.generate());
node.deleteProperty(name); node.deleteProperty(name);
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(node);
} }
/** /**
* Delete all properties from a node. * Delete all properties from a node.
* @param path The path to the node. * @param path The path to the node.
@ -1164,6 +1198,8 @@ public class AVMStoreImpl implements AVMStore, Serializable
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
node.setGuid(GUID.generate()); node.setGuid(GUID.generate());
node.deleteProperties(); node.deleteProperties();
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(node);
} }
/** /**
@ -1179,7 +1215,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
prop.setValue(value); prop.setValue(value);
AVMDAOs.Instance().fAVMStorePropertyDAO.save(prop); AVMDAOs.Instance().fAVMStorePropertyDAO.save(prop);
} }
/** /**
* Set a group of properties on this store. Replaces any property that exists. * Set a group of properties on this store. Replaces any property that exists.
* @param properties A Map of QNames to PropertyValues to set. * @param properties A Map of QNames to PropertyValues to set.
@ -1191,7 +1227,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
setProperty(name, properties.get(name)); setProperty(name, properties.get(name));
} }
} }
/** /**
* Get a property by name. * Get a property by name.
* @param name The QName of the property to fetch. * @param name The QName of the property to fetch.
@ -1206,14 +1242,14 @@ public class AVMStoreImpl implements AVMStore, Serializable
} }
return prop.getValue(); return prop.getValue();
} }
/** /**
* Get all the properties associated with this node. * Get all the properties associated with this node.
* @return A Map of the properties. * @return A Map of the properties.
*/ */
public Map<QName, PropertyValue> getProperties() public Map<QName, PropertyValue> getProperties()
{ {
List<AVMStoreProperty> props = List<AVMStoreProperty> props =
AVMDAOs.Instance().fAVMStorePropertyDAO.get(this); AVMDAOs.Instance().fAVMStorePropertyDAO.get(this);
Map<QName, PropertyValue> retVal = new HashMap<QName, PropertyValue>(); Map<QName, PropertyValue> retVal = new HashMap<QName, PropertyValue>();
for (AVMStoreProperty prop : props) for (AVMStoreProperty prop : props)
@ -1222,7 +1258,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
} }
return retVal; return retVal;
} }
/** /**
* Delete a property. * Delete a property.
* @param name The name of the property to delete. * @param name The name of the property to delete.
@ -1231,7 +1267,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
AVMDAOs.Instance().fAVMStorePropertyDAO.delete(this, name); AVMDAOs.Instance().fAVMStorePropertyDAO.delete(this, name);
} }
/** /**
* Get the ContentData on a file. * Get the ContentData on a file.
* @param version The version to look under. * @param version The version to look under.
@ -1250,9 +1286,12 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
throw new AVMWrongTypeException("File Expected."); throw new AVMWrongTypeException("File Expected.");
} }
return ((FileNode)node).getContentData(lPath); ContentData content = ((FileNode)node).getContentData(lPath);
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(node);
return content;
} }
/** /**
* Get the ContentData on a file for writing. * Get the ContentData on a file for writing.
* @param path The path to the file. * @param path The path to the file.
@ -1272,7 +1311,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
} }
node.updateModTime(); node.updateModTime();
node.setGuid(GUID.generate()); node.setGuid(GUID.generate());
return ((FileNode)node).getContentData(lPath); ContentData content = ((FileNode)node).getContentData(lPath);
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(node);
return content;
} }
/** /**
@ -1293,6 +1335,8 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMWrongTypeException("File Expected."); throw new AVMWrongTypeException("File Expected.");
} }
((FileNode)node).setContentData(data); ((FileNode)node).setContentData(data);
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(node);
} }
/** /**
@ -1310,6 +1354,8 @@ public class AVMStoreImpl implements AVMStore, Serializable
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
node.copyMetaDataFrom(from); node.copyMetaDataFrom(from);
node.setGuid(GUID.generate()); node.setGuid(GUID.generate());
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(node);
} }
/** /**
@ -1327,8 +1373,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
node.getAspects().add(aspectName); node.getAspects().add(aspectName);
node.setGuid(GUID.generate()); node.setGuid(GUID.generate());
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(node);
} }
/** /**
* Get all aspects on a given node. * Get all aspects on a given node.
* @param version The version to look under. * @param version The version to look under.
@ -1343,7 +1391,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
return node.getAspects(); Set<QName> aspects = node.getAspects();
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(node);
return aspects;
} }
/** /**
@ -1368,8 +1419,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
node.getProperties().remove(name); node.getProperties().remove(name);
} }
node.setGuid(GUID.generate()); node.setGuid(GUID.generate());
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(node);
} }
/** /**
* Does a given node have a given aspect. * Does a given node have a given aspect.
* @param version The version to look under. * @param version The version to look under.
@ -1385,9 +1438,11 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
return node.getAspects().contains(aspectName); boolean has = node.getAspects().contains(aspectName);
AVMDAOs.Instance().fAVMNodeDAO.evict(node);
return has;
} }
/** /**
* Set the ACL on a node. * Set the ACL on a node.
* @param path The path to the node. * @param path The path to the node.
@ -1403,8 +1458,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
node.setAcl(acl); node.setAcl(acl);
node.setGuid(GUID.generate()); node.setGuid(GUID.generate());
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(node);
} }
/** /**
* Get the ACL on a node. * Get the ACL on a node.
* @param version The version to look under. * @param version The version to look under.
@ -1420,7 +1477,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
} }
return lPath.getCurrentNode().getAcl(); return lPath.getCurrentNode().getAcl();
} }
/** /**
* Link a node intro a directory, directly. * Link a node intro a directory, directly.
* @param parentPath The path to the directory. * @param parentPath The path to the directory.
@ -1436,6 +1493,8 @@ public class AVMStoreImpl implements AVMStore, Serializable
} }
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
dir.link(lPath, name, toLink); dir.link(lPath, name, toLink);
//AVMDAOs.Instance().fAVMNodeDAO.flush();
//AVMDAOs.Instance().fAVMNodeDAO.evict(dir);
} }
/** /**
@ -1473,12 +1532,15 @@ public class AVMStoreImpl implements AVMStore, Serializable
toLink.getAspects().add(WCMModel.ASPECT_REVERTED); toLink.getAspects().add(WCMModel.ASPECT_REVERTED);
PropertyValue value = new PropertyValue(null, toRevertTo.getId()); PropertyValue value = new PropertyValue(null, toRevertTo.getId());
toLink.setProperty(WCMModel.PROP_REVERTED_ID, value); toLink.setProperty(WCMModel.PROP_REVERTED_ID, value);
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(dir);
AVMDAOs.Instance().fAVMNodeDAO.evict(toLink);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.repo.avm.AVMStore#setGuid(java.lang.String, java.lang.String) * @see org.alfresco.repo.avm.AVMStore#setGuid(java.lang.String, java.lang.String)
*/ */
public void setGuid(String path, String guid) public void setGuid(String path, String guid)
{ {
Lookup lPath = lookup(-1, path, true, true); Lookup lPath = lookup(-1, path, true, true);
if (lPath == null) if (lPath == null)
@ -1487,6 +1549,8 @@ public class AVMStoreImpl implements AVMStore, Serializable
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
node.setGuid(guid); node.setGuid(guid);
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(node);
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -1506,6 +1570,8 @@ public class AVMStoreImpl implements AVMStore, Serializable
} }
PlainFileNode file = (PlainFileNode)node; PlainFileNode file = (PlainFileNode)node;
file.setEncoding(encoding); file.setEncoding(encoding);
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(file);
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -1525,5 +1591,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
} }
PlainFileNode file = (PlainFileNode)node; PlainFileNode file = (PlainFileNode)node;
file.setMimeType(mimeType); file.setMimeType(mimeType);
AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fAVMNodeDAO.evict(file);
} }
} }

View File

@ -36,7 +36,7 @@ public interface ChildEntryDAO
* @param entry The entry to save. * @param entry The entry to save.
*/ */
public void save(ChildEntry entry); public void save(ChildEntry entry);
/** /**
* Get an entry by name and parent. * Get an entry by name and parent.
* @param name The name of the child to find. * @param name The name of the child to find.
@ -44,14 +44,14 @@ public interface ChildEntryDAO
* @return The ChildEntry or null if not foun. * @return The ChildEntry or null if not foun.
*/ */
public ChildEntry get(ChildKey key); public ChildEntry get(ChildKey key);
/** /**
* Get all the children of a given parent. * Get all the children of a given parent.
* @param parent The parent. * @param parent The parent.
* @return A List of ChildEntries. * @return A List of ChildEntries.
*/ */
public List<ChildEntry> getByParent(DirectoryNode parent); public List<ChildEntry> getByParent(DirectoryNode parent);
/** /**
* Get the entry for a given child in a given parent. * Get the entry for a given child in a given parent.
* @param parent The parent. * @param parent The parent.
@ -59,29 +59,35 @@ public interface ChildEntryDAO
* @return The ChildEntry or null. * @return The ChildEntry or null.
*/ */
public ChildEntry getByParentChild(DirectoryNode parent, AVMNode child); public ChildEntry getByParentChild(DirectoryNode parent, AVMNode child);
/** /**
* Get all the ChildEntries corresponding to the given child. * Get all the ChildEntries corresponding to the given child.
* @param child The child for which to look up entries. * @param child The child for which to look up entries.
* @return The matching entries. * @return The matching entries.
*/ */
public List<ChildEntry> getByChild(AVMNode child); public List<ChildEntry> getByChild(AVMNode child);
/** /**
* Update a dirty ChildEntry. * Update a dirty ChildEntry.
* @param child The dirty entry. * @param child The dirty entry.
*/ */
public void update(ChildEntry child); public void update(ChildEntry child);
/** /**
* Delete one. * Delete one.
* @param child The one to delete. * @param child The one to delete.
*/ */
public void delete(ChildEntry child); public void delete(ChildEntry child);
/** /**
* Delete all children of the given parent. * Delete all children of the given parent.
* @param parent The parent. * @param parent The parent.
*/ */
public void deleteByParent(AVMNode parent); public void deleteByParent(AVMNode parent);
/**
* Evict a child entry.
* @param entry
*/
public void evict(ChildEntry entry);
} }

View File

@ -402,6 +402,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
{ {
listing.put(entry.getKey().getName(), entry.getChild()); listing.put(entry.getKey().getName(), entry.getChild());
} }
AVMDAOs.Instance().fChildEntryDAO.evict(entry);
} }
return listing; return listing;
} }
@ -420,6 +421,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
{ {
listing.put(entry.getKey().getName(), entry.getChild()); listing.put(entry.getKey().getName(), entry.getChild());
} }
AVMDAOs.Instance().fChildEntryDAO.evict(entry);
} }
return listing; return listing;
} }
@ -445,6 +447,8 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
AVMNodeDescriptor childDesc = AVMNodeDescriptor childDesc =
childNode.getDescriptor(dir.getPath(), child.getKey().getName(), dir.getIndirection(), dir.getIndirectionVersion()); childNode.getDescriptor(dir.getPath(), child.getKey().getName(), dir.getIndirection(), dir.getIndirectionVersion());
listing.put(child.getKey().getName(), childDesc); listing.put(child.getKey().getName(), childDesc);
AVMDAOs.Instance().fAVMNodeDAO.evict(childNode);
AVMDAOs.Instance().fChildEntryDAO.evict(child);
} }
return listing; return listing;
} }
@ -477,6 +481,7 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
listing.get(name).getDescriptor(dir.getPath(), name, listing.get(name).getDescriptor(dir.getPath(), name,
lookup.getCurrentIndirection(), lookup.getCurrentIndirection(),
lookup.getCurrentIndirectionVersion())); lookup.getCurrentIndirectionVersion()));
AVMDAOs.Instance().fAVMNodeDAO.evict(listing.get(name));
} }
} }
} }
@ -494,6 +499,8 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
child.getKey().getName(), child.getKey().getName(),
dir.getIndirection(), dir.getIndirection(),
dir.getIndirectionVersion())); dir.getIndirectionVersion()));
AVMDAOs.Instance().fAVMNodeDAO.evict(child.getChild());
AVMDAOs.Instance().fChildEntryDAO.evict(child);
} }
} }
return baseListing; return baseListing;
@ -582,10 +589,13 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
{ {
return null; return null;
} }
return entry.getChild().getDescriptor(mine.getPath(), AVMNodeDescriptor desc = entry.getChild().getDescriptor(mine.getPath(),
name, name,
mine.getIndirection(), mine.getIndirection(),
mine.getIndirectionVersion()); mine.getIndirectionVersion());
AVMDAOs.Instance().fAVMNodeDAO.evict(entry.getChild());
AVMDAOs.Instance().fChildEntryDAO.evict(entry);
return desc;
} }
// If we are opaque don't check underneath. // If we are opaque don't check underneath.
if (fOpacity) if (fOpacity)
@ -601,7 +611,9 @@ class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements LayeredDirec
{ {
return null; return null;
} }
return child.getFirst().getDescriptor(lookup); AVMNodeDescriptor desc = child.getFirst().getDescriptor(lookup);
AVMDAOs.Instance().fAVMNodeDAO.evict(child.getFirst());
return desc;
} }
else else
{ {

View File

@ -1,5 +1,5 @@
/** /**
* *
*/ */
package org.alfresco.repo.avm; package org.alfresco.repo.avm;
@ -16,32 +16,32 @@ import org.apache.commons.logging.LogFactory;
* All lookup traffic goes through here. * All lookup traffic goes through here.
* @author britt * @author britt
*/ */
public class LookupCache public class LookupCache
{ {
private static Log fgLogger = LogFactory.getLog(LookupCache.class); private static Log fgLogger = LogFactory.getLog(LookupCache.class);
/** /**
* The Map of of keys to lookups. * The Map of of keys to lookups.
*/ */
private SimpleCache<LookupKey, Lookup> fCache; private SimpleCache<LookupKey, Lookup> fCache;
/** /**
* Reference to the Node DAO. * Reference to the Node DAO.
*/ */
private AVMNodeDAO fAVMNodeDAO; private AVMNodeDAO fAVMNodeDAO;
/** /**
* Reference to the Store DAO. * Reference to the Store DAO.
*/ */
private AVMStoreDAO fAVMStoreDAO; private AVMStoreDAO fAVMStoreDAO;
/** /**
* Make one up. * Make one up.
*/ */
public LookupCache() public LookupCache()
{ {
} }
/** /**
* Set up the node dao. * Set up the node dao.
* @param dao The dao to set. * @param dao The dao to set.
@ -50,21 +50,21 @@ public class LookupCache
{ {
fAVMNodeDAO = dao; fAVMNodeDAO = dao;
} }
/** /**
* Set the store dao. * Set the store dao.
* @param dao The dao to set. * @param dao The dao to set.
*/ */
public void setAvmStoreDAO(AVMStoreDAO dao) public void setAvmStoreDAO(AVMStoreDAO dao)
{ {
fAVMStoreDAO = dao; fAVMStoreDAO = dao;
} }
public void setTransactionalCache(SimpleCache<LookupKey, Lookup> cache) public void setTransactionalCache(SimpleCache<LookupKey, Lookup> cache)
{ {
fCache = cache; fCache = cache;
} }
/** /**
* Lookup a path. Try to fulfill the request from the cache. * Lookup a path. Try to fulfill the request from the cache.
* @param store The AVMStore. * @param store The AVMStore.
@ -74,7 +74,7 @@ public class LookupCache
* @param includeDeleted * @param includeDeleted
* @return * @return
*/ */
public Lookup lookup(AVMStore store, int version, SimplePath path, public Lookup lookup(AVMStore store, int version, SimplePath path,
boolean write, boolean includeDeleted) boolean write, boolean includeDeleted)
{ {
// Create a key object. // Create a key object.
@ -95,7 +95,7 @@ public class LookupCache
if (path.size() == 0) if (path.size() == 0)
{ {
return null; return null;
} }
Lookup result = new Lookup(store, store.getName(), version); Lookup result = new Lookup(store, store.getName(), version);
// Grab the root node to start the lookup. // Grab the root node to start the lookup.
DirectoryNode dir = null; DirectoryNode dir = null;
@ -114,6 +114,7 @@ public class LookupCache
{ {
return null; return null;
} }
dir = (DirectoryNode)AVMNodeUnwrapper.Unwrap(dir);
// Add an entry for the root. // Add an entry for the root.
result.add(dir, "", true, write); result.add(dir, "", true, write);
dir = (DirectoryNode)result.getCurrentNode(); dir = (DirectoryNode)result.getCurrentNode();
@ -149,9 +150,9 @@ public class LookupCache
} }
result.add(child.getFirst(), path.get(path.size() - 1), child.getSecond(), write); result.add(child.getFirst(), path.get(path.size() - 1), child.getSecond(), write);
fCache.put(key, result); fCache.put(key, result);
return result; return result;
} }
/** /**
* Try to find a match in the cache. * Try to find a match in the cache.
* @param key The lookup key. * @param key The lookup key.
@ -196,9 +197,9 @@ public class LookupCache
} }
return null; return null;
} }
// Following are the cache invalidation calls. // Following are the cache invalidation calls.
/** /**
* Called when a simple write operation occurs. This * Called when a simple write operation occurs. This
* invalidates all read lookups and all layered lookups. * invalidates all read lookups and all layered lookups.
@ -216,7 +217,7 @@ public class LookupCache
{ {
Lookup value = fCache.get(key); Lookup value = fCache.get(key);
if ((key.getStoreName().equals(storeName) && if ((key.getStoreName().equals(storeName) &&
!key.isWrite()) || value == null || !key.isWrite()) || value == null ||
(!key.isWrite() && value.isLayered())) (!key.isWrite() && value.isLayered()))
{ {
if (fgLogger.isDebugEnabled()) if (fgLogger.isDebugEnabled())
@ -227,7 +228,7 @@ public class LookupCache
} }
} }
} }
/** /**
* Called when a delete has occurred in a store. This invalidates both * Called when a delete has occurred in a store. This invalidates both
* reads and write lookups in that store. * reads and write lookups in that store.
@ -254,9 +255,9 @@ public class LookupCache
} }
} }
} }
/** /**
* Called when a snapshot occurs in a store. This invalidates write * Called when a snapshot occurs in a store. This invalidates write
* lookups. Read lookups stay untouched. * lookups. Read lookups stay untouched.
*/ */
public synchronized void onSnapshot(String storeName) public synchronized void onSnapshot(String storeName)
@ -283,7 +284,7 @@ public class LookupCache
} }
} }
} }
public synchronized void reset() public synchronized void reset()
{ {
fCache.clear(); fCache.clear();

View File

@ -55,14 +55,14 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
AVMDAOs.Instance().fAVMNodeDAO.save(this); AVMDAOs.Instance().fAVMNodeDAO.save(this);
AVMDAOs.Instance().fAVMNodeDAO.flush(); AVMDAOs.Instance().fAVMNodeDAO.flush();
} }
/** /**
* Anonymous constructor. * Anonymous constructor.
*/ */
protected PlainDirectoryNodeImpl() protected PlainDirectoryNodeImpl()
{ {
} }
/** /**
* Copy like constructor. * Copy like constructor.
* @param other The other directory. * @param other The other directory.
@ -89,7 +89,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
} }
/** /**
* Does this directory directly contain the given node. * Does this directory directly contain the given node.
* @param node The node to check. * @param node The node to check.
* @return Whether it was found. * @return Whether it was found.
*/ */
@ -114,7 +114,8 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
{ {
continue; continue;
} }
result.put(child.getKey().getName(), child.getChild()); result.put(child.getKey().getName(), AVMNodeUnwrapper.Unwrap(child.getChild()));
AVMDAOs.Instance().fChildEntryDAO.evict(child);
} }
return result; return result;
} }
@ -128,14 +129,14 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
{ {
return getListing(lPath, includeDeleted); return getListing(lPath, includeDeleted);
} }
/** /**
* Get a listing of the nodes directly contained by a directory. * Get a listing of the nodes directly contained by a directory.
* @param dir The node's descriptor. * @param dir The node's descriptor.
* @param includeDeleted Whether to include deleted nodes. * @param includeDeleted Whether to include deleted nodes.
* @return A Map of Strings to descriptors. * @return A Map of Strings to descriptors.
*/ */
public SortedMap<String, AVMNodeDescriptor> getListingDirect(AVMNodeDescriptor dir, public SortedMap<String, AVMNodeDescriptor> getListingDirect(AVMNodeDescriptor dir,
boolean includeDeleted) boolean includeDeleted)
{ {
return getListing(dir, includeDeleted); return getListing(dir, includeDeleted);
@ -160,11 +161,13 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
{ {
continue; continue;
} }
result.put(child.getKey().getName(), result.put(child.getKey().getName(),
child.getChild().getDescriptor(dir.getPath(), child.getChild().getDescriptor(dir.getPath(),
child.getKey().getName(), child.getKey().getName(),
dir.getIndirection(), dir.getIndirection(),
dir.getIndirectionVersion())); dir.getIndirectionVersion()));
AVMDAOs.Instance().fAVMNodeDAO.evict(child.getChild());
AVMDAOs.Instance().fChildEntryDAO.evict(child);
} }
return result; return result;
} }
@ -190,7 +193,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
{ {
ChildKey key = new ChildKey(this, name); ChildKey key = new ChildKey(this, name);
ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key); ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key);
if (entry == null || if (entry == null ||
(!includeDeleted && entry.getChild().getType() == AVMNodeType.DELETED_NODE)) (!includeDeleted && entry.getChild().getType() == AVMNodeType.DELETED_NODE))
{ {
return null; return null;
@ -214,12 +217,15 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
} }
ChildKey key = new ChildKey(this, name); ChildKey key = new ChildKey(this, name);
ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key); ChildEntry entry = AVMDAOs.Instance().fChildEntryDAO.get(key);
if (entry == null || if (entry == null ||
(!includeDeleted && entry.getChild().getType() == AVMNodeType.DELETED_NODE)) (!includeDeleted && entry.getChild().getType() == AVMNodeType.DELETED_NODE))
{ {
return null; return null;
} }
return entry.getChild().getDescriptor(mine.getPath(), name, (String)null, -1); AVMNodeDescriptor desc = entry.getChild().getDescriptor(mine.getPath(), name, (String)null, -1);
AVMDAOs.Instance().fAVMNodeDAO.evict(entry.getChild());
AVMDAOs.Instance().fChildEntryDAO.evict(entry);
return desc;
} }
/** /**
@ -291,11 +297,11 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
public AVMNode copy(Lookup lPath) public AVMNode copy(Lookup lPath)
{ {
DirectoryNode newMe = null; DirectoryNode newMe = null;
// In a layered context a copy on write creates a new // In a layered context a copy on write creates a new
// layered directory. // layered directory.
if (lPath.isLayered()) if (lPath.isLayered())
{ {
// Subtlety warning: This distinguishes the case of a // Subtlety warning: This distinguishes the case of a
// Directory that was branched into the layer and one // Directory that was branched into the layer and one
// that is indirectly seen in this layer. // that is indirectly seen in this layer.
newMe = new LayeredDirectoryNodeImpl(this, lPath.getAVMStore(), lPath, newMe = new LayeredDirectoryNodeImpl(this, lPath.getAVMStore(), lPath,
@ -311,7 +317,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
} }
/** /**
* Get the type of this node. * Get the type of this node.
* @return The type of this node. * @return The type of this node.
*/ */
public int getType() public int getType()
@ -327,10 +333,10 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
public String toString(Lookup lPath) public String toString(Lookup lPath)
{ {
return "[PD:" + getId() + "]"; return "[PD:" + getId() + "]";
} }
/** /**
* Turn this into a primary indirection. This must be in a * Turn this into a primary indirection. This must be in a
* layered context. * layered context.
* @param lPath The Lookup. * @param lPath The Lookup.
*/ */
@ -414,7 +420,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
false, false,
-1, -1,
false, false,
-1, -1,
-1); -1);
} }
@ -449,7 +455,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
-1, -1,
-1); -1);
} }
/** /**
* Link a node with the given id into this directory. * Link a node with the given id into this directory.
* @param lPath The Lookup for this directory. * @param lPath The Lookup for this directory.
@ -461,7 +467,7 @@ class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectory
if (DEBUG) if (DEBUG)
{ {
checkReadOnly(); checkReadOnly();
} }
// Assure that the incoming node exists. // Assure that the incoming node exists.
AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(toLink.getId()); AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(toLink.getId());
if (node == null) if (node == null)

View File

@ -50,7 +50,7 @@ class AVMNodeDAOHibernate extends HibernateDaoSupport implements
{ {
super(); super();
} }
/** /**
* Save the given node, having never been saved before. * Save the given node, having never been saved before.
*/ */
@ -85,7 +85,7 @@ class AVMNodeDAOHibernate extends HibernateDaoSupport implements
{ {
getSession().flush(); getSession().flush();
} }
/** /**
* Get the root of a particular version. * Get the root of a particular version.
* @param store The store we're querying. * @param store The store we're querying.
@ -94,7 +94,7 @@ class AVMNodeDAOHibernate extends HibernateDaoSupport implements
*/ */
public DirectoryNode getAVMStoreRoot(AVMStore store, int version) public DirectoryNode getAVMStoreRoot(AVMStore store, int version)
{ {
Query query = Query query =
getSession().getNamedQuery("VersionRoot.GetVersionRoot"); getSession().getNamedQuery("VersionRoot.GetVersionRoot");
query.setEntity("store", store); query.setEntity("store", store);
query.setInteger("version", version); query.setInteger("version", version);
@ -131,7 +131,7 @@ class AVMNodeDAOHibernate extends HibernateDaoSupport implements
} }
/** /**
* Get up to batchSize orphans. * Get up to batchSize orphans.
* @param batchSize Get no more than this number. * @param batchSize Get no more than this number.
* @return A List of orphaned AVMNodes. * @return A List of orphaned AVMNodes.
*/ */
@ -166,7 +166,7 @@ class AVMNodeDAOHibernate extends HibernateDaoSupport implements
query.setEntity("store", store); query.setEntity("store", store);
return (List<AVMNode>)query.list(); return (List<AVMNode>)query.list();
} }
/** /**
* Inappropriate hack to get Hibernate to play nice. * Inappropriate hack to get Hibernate to play nice.
*/ */
@ -209,4 +209,12 @@ class AVMNodeDAOHibernate extends HibernateDaoSupport implements
query.setMaxResults(count); query.setMaxResults(count);
return (List<LayeredFileNode>)query.list(); return (List<LayeredFileNode>)query.list();
} }
/* (non-Javadoc)
* @see org.alfresco.repo.avm.AVMNodeDAO#evict(org.alfresco.repo.avm.AVMNode)
*/
public void evict(AVMNode node)
{
getSession().evict(node);
}
} }

View File

@ -48,7 +48,7 @@ class ChildEntryDAOHibernate extends HibernateDaoSupport implements
{ {
super(); super();
} }
/** /**
* Save an unsaved ChildEntry. * Save an unsaved ChildEntry.
* @param entry The entry to save. * @param entry The entry to save.
@ -68,7 +68,7 @@ class ChildEntryDAOHibernate extends HibernateDaoSupport implements
{ {
return (ChildEntry)getSession().get(ChildEntryImpl.class, key); return (ChildEntry)getSession().get(ChildEntryImpl.class, key);
} }
/** /**
* Get all the children of a given parent. * Get all the children of a given parent.
* @param parent The parent. * @param parent The parent.
@ -142,4 +142,12 @@ class ChildEntryDAOHibernate extends HibernateDaoSupport implements
delete.setEntity("parent", parent); delete.setEntity("parent", parent);
delete.executeUpdate(); delete.executeUpdate();
} }
/* (non-Javadoc)
* @see org.alfresco.repo.avm.ChildEntryDAO#evict(org.alfresco.repo.avm.ChildEntry)
*/
public void evict(ChildEntry entry)
{
getSession().evict(entry);
}
} }