mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Factored the ancestor-descendent and merged from-to relationships
out of AVMNode. Easier to get hibernate to do what I want and appears to be a little more efficient as it removes several FK constraints from a frequently updated table. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3137 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -19,6 +19,9 @@ package org.alfresco.repo.avm;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.Session;
|
||||
|
||||
/**
|
||||
* Base class for all repository file system like objects.
|
||||
* @author britt
|
||||
@@ -35,16 +38,6 @@ abstract class AVMNodeImpl implements AVMNode, Serializable
|
||||
*/
|
||||
private int fVersionID;
|
||||
|
||||
/**
|
||||
* The ancestor of this.
|
||||
*/
|
||||
private AVMNode fAncestor;
|
||||
|
||||
/**
|
||||
* The node that was merged into this.
|
||||
*/
|
||||
private AVMNode fMergedFrom;
|
||||
|
||||
/**
|
||||
* The Repository that owns this.
|
||||
*/
|
||||
@@ -87,8 +80,6 @@ abstract class AVMNodeImpl implements AVMNode, Serializable
|
||||
{
|
||||
fID = id;
|
||||
fVersionID = -1;
|
||||
fAncestor = null;
|
||||
fMergedFrom = null;
|
||||
fRepository = repo;
|
||||
fIsRoot = false;
|
||||
long time = System.currentTimeMillis();
|
||||
@@ -107,7 +98,14 @@ abstract class AVMNodeImpl implements AVMNode, Serializable
|
||||
*/
|
||||
public void setAncestor(AVMNode ancestor)
|
||||
{
|
||||
fAncestor = ancestor;
|
||||
if (ancestor == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
HistoryLinkImpl link = new HistoryLinkImpl();
|
||||
link.setAncestor(ancestor);
|
||||
link.setDescendent(this);
|
||||
SuperRepository.GetInstance().getSession().save(link);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,7 +114,10 @@ abstract class AVMNodeImpl implements AVMNode, Serializable
|
||||
*/
|
||||
public AVMNode getAncestor()
|
||||
{
|
||||
return fAncestor;
|
||||
Session sess = SuperRepository.GetInstance().getSession();
|
||||
Query query = sess.createQuery("select hl.ancestor from HistoryLinkImpl hl where hl.descendent = :desc");
|
||||
query.setEntity("desc", this);
|
||||
return (AVMNode)query.uniqueResult();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,7 +126,14 @@ abstract class AVMNodeImpl implements AVMNode, Serializable
|
||||
*/
|
||||
public void setMergedFrom(AVMNode mergedFrom)
|
||||
{
|
||||
fMergedFrom = mergedFrom;
|
||||
if (mergedFrom == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
MergeLinkImpl link = new MergeLinkImpl();
|
||||
link.setMfrom(mergedFrom);
|
||||
link.setMto(this);
|
||||
SuperRepository.GetInstance().getSession().save(link);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,7 +142,10 @@ abstract class AVMNodeImpl implements AVMNode, Serializable
|
||||
*/
|
||||
public AVMNode getMergedFrom()
|
||||
{
|
||||
return fMergedFrom;
|
||||
Session sess = SuperRepository.GetInstance().getSession();
|
||||
Query query = sess.createQuery("select ml.mfrom from MergeLinkImpl ml where ml.mto = :to");
|
||||
query.setEntity("to", this);
|
||||
return (AVMNode)query.uniqueResult();
|
||||
}
|
||||
|
||||
/**
|
||||
|
49
source/java/org/alfresco/repo/avm/HistoryLink.java
Normal file
49
source/java/org/alfresco/repo/avm/HistoryLink.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Interface for the ancestor-descendent relationship.
|
||||
* @author britt
|
||||
*/
|
||||
interface HistoryLink
|
||||
{
|
||||
/**
|
||||
* Set the ancestor part of this.
|
||||
* @param ancestor
|
||||
*/
|
||||
public void setAncestor(AVMNode ancestor);
|
||||
|
||||
/**
|
||||
* Get the ancestor part of this.
|
||||
* @return The ancestor.
|
||||
*/
|
||||
public AVMNode getAncestor();
|
||||
|
||||
/**
|
||||
* Set the descendent part of this.
|
||||
* @param descendent
|
||||
*/
|
||||
public void setDescendent(AVMNode descendent);
|
||||
|
||||
/**
|
||||
* Get the descendent part of this.
|
||||
* @return
|
||||
*/
|
||||
public AVMNode getDescendent();
|
||||
}
|
75
source/java/org/alfresco/repo/avm/HistoryLinkImpl.java
Normal file
75
source/java/org/alfresco/repo/avm/HistoryLinkImpl.java
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Holds a ancestor-descendent relationship.
|
||||
* @author britt
|
||||
*/
|
||||
class HistoryLinkImpl implements HistoryLink, Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -430859344980137718L;
|
||||
|
||||
/**
|
||||
* The ancestor.
|
||||
*/
|
||||
private AVMNode fAncestor;
|
||||
|
||||
/**
|
||||
* The descendent.
|
||||
*/
|
||||
private AVMNode fDescendent;
|
||||
|
||||
/**
|
||||
* Set the ancestor part of this.
|
||||
* @param ancestor
|
||||
*/
|
||||
public void setAncestor(AVMNode ancestor)
|
||||
{
|
||||
fAncestor = ancestor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ancestor part of this.
|
||||
* @return The ancestor.
|
||||
*/
|
||||
public AVMNode getAncestor()
|
||||
{
|
||||
return fAncestor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the descendent part of this.
|
||||
* @param descendent
|
||||
*/
|
||||
public void setDescendent(AVMNode descendent)
|
||||
{
|
||||
fDescendent = descendent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the descendent part of this.
|
||||
* @return The descendent.
|
||||
*/
|
||||
public AVMNode getDescendent()
|
||||
{
|
||||
return fDescendent;
|
||||
}
|
||||
}
|
49
source/java/org/alfresco/repo/avm/MergeLink.java
Normal file
49
source/java/org/alfresco/repo/avm/MergeLink.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* This is the interface for the merged from - to relationship.
|
||||
* @author britt
|
||||
*/
|
||||
interface MergeLink
|
||||
{
|
||||
/**
|
||||
* Set the from part.
|
||||
* @param from
|
||||
*/
|
||||
public void setMfrom(AVMNode from);
|
||||
|
||||
/**
|
||||
* Get the from part.
|
||||
* @return The from part.
|
||||
*/
|
||||
public AVMNode getMfrom();
|
||||
|
||||
/**
|
||||
* Set the to part.
|
||||
* @param to
|
||||
*/
|
||||
public void setMto(AVMNode to);
|
||||
|
||||
/**
|
||||
* Get the to part.
|
||||
* @return The to part.
|
||||
*/
|
||||
public AVMNode getMto();
|
||||
}
|
75
source/java/org/alfresco/repo/avm/MergeLinkImpl.java
Normal file
75
source/java/org/alfresco/repo/avm/MergeLinkImpl.java
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* This contains a single merged from-to relationship.
|
||||
* @author britt
|
||||
*/
|
||||
class MergeLinkImpl implements MergeLink, Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 6672271083042424944L;
|
||||
|
||||
/**
|
||||
* The node that was merged from.
|
||||
*/
|
||||
private AVMNode fFrom;
|
||||
|
||||
/**
|
||||
* The node that was merged to.
|
||||
*/
|
||||
private AVMNode fTo;
|
||||
|
||||
/**
|
||||
* Set the from part.
|
||||
* @param from
|
||||
*/
|
||||
public void setMfrom(AVMNode from)
|
||||
{
|
||||
fFrom = from;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the from part.
|
||||
* @return The from part.
|
||||
*/
|
||||
public AVMNode getMfrom()
|
||||
{
|
||||
return fFrom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the to part.
|
||||
* @param to
|
||||
*/
|
||||
public void setMto(AVMNode to)
|
||||
{
|
||||
fTo = to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the to part.
|
||||
* @return The to part.
|
||||
*/
|
||||
public AVMNode getMto()
|
||||
{
|
||||
return fTo;
|
||||
}
|
||||
}
|
@@ -184,6 +184,7 @@ class OrphanReaper implements Runnable
|
||||
{
|
||||
public void perform(Session session)
|
||||
{
|
||||
SuperRepository.GetInstance().setSession(session);
|
||||
Query query = session.getNamedQuery("FindOrphans");
|
||||
query.setMaxResults(fBatchSize);
|
||||
List<AVMNode> nodes = (List<AVMNode>)query.list();
|
||||
@@ -196,28 +197,48 @@ class OrphanReaper implements Runnable
|
||||
for (AVMNode node : nodes)
|
||||
{
|
||||
// Save away the ancestor and merged from fields from this node.
|
||||
AVMNode ancestor = node.getAncestor();
|
||||
AVMNode mergedFrom = node.getMergedFrom();
|
||||
// Get all the nodes that have this node as ancestor.
|
||||
query = session.getNamedQuery("AVMNode.GetDescendents");
|
||||
query.setEntity("node", node);
|
||||
List<AVMNode> descendents = (List<AVMNode>)query.list();
|
||||
for (AVMNode desc : descendents)
|
||||
query = session.createQuery("from HistoryLinkImpl hl where hl.descendent = :desc");
|
||||
query.setEntity("desc", node);
|
||||
HistoryLink hlink = (HistoryLink)query.uniqueResult();
|
||||
AVMNode ancestor = null;
|
||||
if (hlink != null)
|
||||
{
|
||||
ancestor = hlink.getAncestor();
|
||||
session.delete(hlink);
|
||||
}
|
||||
query = session.createQuery("from MergeLinkImpl ml where ml.mto = :to");
|
||||
query.setEntity("to", node);
|
||||
MergeLink mlink = (MergeLink)query.uniqueResult();
|
||||
AVMNode mergedFrom = null;
|
||||
if (mlink != null)
|
||||
{
|
||||
mergedFrom = mlink.getMfrom();
|
||||
session.delete(mlink);
|
||||
}
|
||||
// Get all the nodes that have this node as ancestor.
|
||||
query = session.getNamedQuery("HistoryLink.ByAncestor");
|
||||
query.setEntity("node", node);
|
||||
List<HistoryLink> links = (List<HistoryLink>)query.list();
|
||||
for (HistoryLink link : links)
|
||||
{
|
||||
AVMNode desc = link.getDescendent();
|
||||
desc.setAncestor(ancestor);
|
||||
if (desc.getMergedFrom() == null)
|
||||
{
|
||||
desc.setMergedFrom(mergedFrom);
|
||||
}
|
||||
session.delete(link);
|
||||
}
|
||||
// Get all the nodes that have this node as mergedFrom
|
||||
query = session.getNamedQuery("AVMNode.GetMergedTo");
|
||||
query = session.getNamedQuery("MergeLink.ByFrom");
|
||||
query.setEntity("merged", node);
|
||||
List<AVMNode> merged = (List<AVMNode>)query.list();
|
||||
for (AVMNode merge : merged)
|
||||
List<MergeLink> mlinks = (List<MergeLink>)query.list();
|
||||
for (MergeLink link : mlinks)
|
||||
{
|
||||
merge.setMergedFrom(ancestor);
|
||||
link.getMto().setMergedFrom(ancestor);
|
||||
session.delete(link);
|
||||
}
|
||||
session.flush();
|
||||
node = AVMNodeUnwrapper.Unwrap(node);
|
||||
// Extra work for directories.
|
||||
if (node instanceof DirectoryNode)
|
||||
|
@@ -37,7 +37,7 @@ public class PurgeTest extends AVMServiceTestBase
|
||||
setupBasicTree();
|
||||
BulkLoader loader = new BulkLoader(fService);
|
||||
long start = System.currentTimeMillis();
|
||||
loader.recursiveLoad("source", "main:/");
|
||||
loader.recursiveLoad("source/web", "main:/");
|
||||
System.err.println("Load time: " + (System.currentTimeMillis() - start) + "ms");
|
||||
fService.createSnapshot("main");
|
||||
System.err.println("Load time + snapshot: " + (System.currentTimeMillis() - start) + "ms");
|
||||
|
@@ -24,14 +24,6 @@
|
||||
<version column="vers"
|
||||
name="vers"
|
||||
type="long"/>
|
||||
<!-- BasicAttributes are attributes that pretty much all AVMNodes will
|
||||
have. -->
|
||||
<many-to-one name="ancestor" column="ancestor_id"
|
||||
class="AVMNodeImpl"/>
|
||||
<!-- Nothing does anything with this yet. We'll need it for
|
||||
complete versioning semantics. -->
|
||||
<many-to-one name="mergedFrom" column="merged_from"
|
||||
class="AVMNodeImpl"/>
|
||||
<!-- This should really be not null, but I haven't figured out
|
||||
the right way to build the relation so that nullability constraints
|
||||
won't cause violations in the db during saves. -->
|
||||
@@ -174,6 +166,18 @@
|
||||
column="parent_id"/>
|
||||
</composite-id>
|
||||
</class>
|
||||
<class name="HistoryLinkImpl" proxy="HistoryLink" table="history_links">
|
||||
<composite-id>
|
||||
<key-many-to-one name="ancestor" class="AVMNodeImpl" column="ancestor"/>
|
||||
<key-many-to-one name="descendent" class="AVMNodeImpl" column="descendent"/>
|
||||
</composite-id>
|
||||
</class>
|
||||
<class name="MergeLinkImpl" proxy="MergeLink" table="merge_links">
|
||||
<composite-id>
|
||||
<key-many-to-one name="mfrom" class="AVMNodeImpl" column="mfrom"/>
|
||||
<key-many-to-one name="mto" class="AVMNodeImpl" column="mto"/>
|
||||
</composite-id>
|
||||
</class>
|
||||
<query name="ChildEntry.ByNameParent">
|
||||
<![CDATA[
|
||||
from ChildEntryImpl ce
|
||||
@@ -210,14 +214,28 @@
|
||||
</query>
|
||||
<query name="AVMNode.GetDescendents">
|
||||
<![CDATA[
|
||||
from AVMNodeImpl an
|
||||
where an.ancestor = :node
|
||||
select hl.descendent
|
||||
from HistoryLinkImpl hl
|
||||
where hl.ancestor = :node
|
||||
]]>
|
||||
</query>
|
||||
<query name="HistoryLink.ByAncestor">
|
||||
<![CDATA[
|
||||
from HistoryLinkImpl hl
|
||||
where hl.ancestor = :node
|
||||
]]>
|
||||
</query>
|
||||
<query name="AVMNode.GetMergedTo">
|
||||
<![CDATA[
|
||||
from AVMNodeImpl an
|
||||
where an.mergedFrom = :merged
|
||||
select ml.mto
|
||||
from MergeLinkImpl ml
|
||||
where ml.mfrom = :merged
|
||||
]]>
|
||||
</query>
|
||||
<query name="MergeLink.ByFrom">
|
||||
<![CDATA[
|
||||
from MergeLinkImpl ml
|
||||
where ml.mfrom = :merged
|
||||
]]>
|
||||
</query>
|
||||
<query name="VersionRoot.GetVersionRoot">
|
||||
|
Reference in New Issue
Block a user