Skip to content

Commit

Permalink
XWIKI-22782: Only save modified xobjects
Browse files Browse the repository at this point in the history
  • Loading branch information
tmortagne committed Feb 11, 2025
1 parent 672c9e5 commit 71756b8
Show file tree
Hide file tree
Showing 11 changed files with 315 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,8 @@ private static Transformation getMacroTransformation()
*/
private boolean isMetaDataDirty = true;

private boolean changeTracked;

private int elements = HAS_OBJECTS | HAS_ATTACHMENTS;

// Meta Data
Expand Down Expand Up @@ -2429,6 +2431,34 @@ public void setMetaDataDirty(boolean metaDataDirty)
this.isMetaDataDirty = metaDataDirty;
}

/**
* Indicate if flags indicating which part of the document has been modified can be trusted.
*
* @return the true if change made to this {@link XWikiDocument} instance are tracked
* @since 17.1.0RC1
* @since 16.10.4
* @since 16.4.7
*/
@Unstable
public boolean isChangeTracked()
{
return this.changeTracked;
}

/**
* Indicate if flags indicating which part of the document has been modified can be trusted.
*
* @param changeTracked true if change made to this {@link XWikiDocument} instance are tracked
* @since 17.1.0RC1
* @since 16.10.4
* @since 16.4.7
*/
@Unstable
public void setChangeTracked(boolean changeTracked)
{
this.changeTracked = changeTracked;
}

public String getAttachmentURL(String filename, XWikiContext context)
{
return getAttachmentURL(filename, "download", context);
Expand Down Expand Up @@ -4595,6 +4625,10 @@ private XWikiDocument cloneInternal(DocumentReference newDocumentReference, bool
Constructor<? extends XWikiDocument> constructor = getClass().getConstructor(DocumentReference.class);
doc = constructor.newInstance(newDocumentReference);

if (keepsIdentity && getDocumentReference().equals(doc.getDocumentReference())) {
doc.setChangeTracked(isChangeTracked());
}

// Make sure the coordinate of the document is fully accurate before any other manipulation
doc.setLocale(getLocale());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import javax.inject.Inject;
import javax.inject.Named;
Expand All @@ -29,6 +31,9 @@
import org.apache.commons.lang3.StringUtils;
import org.xwiki.component.annotation.Component;
import org.xwiki.configuration.ConfigurationSource;
import org.xwiki.model.EntityType;
import org.xwiki.model.reference.EntityReference;
import org.xwiki.model.reference.EntityReferenceResolver;

import com.xpn.xwiki.internal.XWikiCfgConfigurationSource;

Expand All @@ -46,6 +51,10 @@ public class HibernateConfiguration
@Named(XWikiCfgConfigurationSource.ROLEHINT)
private ConfigurationSource xwikiConfiguration;

@Inject
@Named("relative")
private EntityReferenceResolver<String> resolver;

private String path;

/**
Expand Down Expand Up @@ -164,4 +173,21 @@ public List<String> getIgnoredMigrations()
{
return getList("xwiki.store.migration.ignored");
}

/**
* @return the local references of the classes for which we should apply a save optimization (save only the modified
* ones)
* @since 17.1.0RC1
* @since 16.10.4
* @since 16.4.7
*/
public Set<EntityReference> getOptimizedXObjectClasses()
{
List<String> references =
this.xwikiConfiguration.getProperty("xwiki.store.hibernate.optimizedObjectSave.classes", List.class);

return references != null
? references.stream().map(r -> this.resolver.resolve(r, EntityType.DOCUMENT)).collect(Collectors.toSet())
: null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.xwiki.model.reference.EntityReferenceResolver;
import org.xwiki.store.merge.MergeManagerResult;

import com.google.common.base.Objects;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.doc.XWikiDocument;
Expand Down Expand Up @@ -224,8 +225,12 @@ public void setXClassReference(EntityReference xClassReference)
}
}

this.xClassReference = ref;
this.xClassReferenceCache = null;
if (!Objects.equal(this.xClassReference, ref)) {
this.xClassReference = ref;
this.xClassReferenceCache = null;

setDirty(true);
}
}

/**
Expand Down Expand Up @@ -265,7 +270,6 @@ public void safeput(String name, PropertyInterface property)
{
addField(name, property);
if (property instanceof BaseProperty) {
((BaseProperty) property).setObject(this);
((BaseProperty) property).setName(name);
}
}
Expand Down Expand Up @@ -537,9 +541,15 @@ public void addField(String name, PropertyInterface element)
{
this.fields.put(name, element);

if (element instanceof BaseElement) {
((BaseElement) element).setOwnerDocument(getOwnerDocument());
if (element instanceof BaseElement baseElement) {
baseElement.setOwnerDocument(getOwnerDocument());

if (element instanceof BaseProperty baseProperty) {
baseProperty.setObject(this);
}
}

setDirty(true);
}

public void removeField(String name)
Expand All @@ -548,6 +558,8 @@ public void removeField(String name)
if (field != null) {
this.fields.remove(name);
this.fieldsToRemove.add(field);

setDirty(true);
}
}

Expand Down Expand Up @@ -647,6 +659,8 @@ public BaseCollection clone()
}
collection.setFields(cfields);

collection.setDirty(isDirty());

return collection;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.io.IOException;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.Objects;

import javax.inject.Provider;

Expand All @@ -37,6 +38,7 @@
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.model.reference.EntityReference;
import org.xwiki.model.reference.EntityReferenceSerializer;
import org.xwiki.stability.Unstable;
import org.xwiki.store.merge.MergeManager;
import org.xwiki.store.merge.MergeManagerResult;

Expand Down Expand Up @@ -101,7 +103,37 @@ public abstract class BaseElement<R extends EntityReference> implements ElementI
private EntityReferenceSerializer<String> localUidStringEntityReferenceSerializer;

private ContextualLocalizationManager localization;


private transient boolean dirty = true;

/**
* @return true of the element was modified (or created)
* @since 17.1.0RC1
* @since 16.10.4
* @since 16.4.7
*/
@Unstable
public boolean isDirty()
{
return this.dirty;
}

/**
* @param dirty true of the element was modified (or created)
* @since 17.1.0RC1
* @since 16.10.4
* @since 16.4.7
*/
@Unstable
public void setDirty(boolean dirty)
{
this.dirty = dirty;

if (dirty && this.ownerDocument != null) {
this.ownerDocument.setMetaDataDirty(true);
}
}

/**
* @return a merge manager instance.
* @since 11.8RC1
Expand Down Expand Up @@ -161,12 +193,16 @@ public String getName()
}

@Override
public void setDocumentReference(DocumentReference reference)
public void setDocumentReference(DocumentReference documentReference)
{
// If the name is already set then reset it since we're now using a reference
this.documentReference = reference;
this.name = null;
this.referenceCache = null;
if (!Objects.equals(documentReference, this.documentReference)) {
// If the name is already set then reset it since we're now using a reference
this.documentReference = documentReference;
this.name = null;
this.referenceCache = null;

setDirty(true);
}
}

/**
Expand All @@ -185,8 +221,12 @@ public void setName(String name)
throw new IllegalStateException("BaseElement#setName could not be called when a reference has been set.");
}

this.name = name;
this.referenceCache = null;
if (!StringUtils.equals(name, this.name)) {
this.name = name;
this.referenceCache = null;

setDirty(true);
}
}

public String getPrettyName()
Expand Down Expand Up @@ -349,6 +389,8 @@ public BaseElement clone()
}

element.setPrettyName(getPrettyName());

element.dirty = this.dirty;
} catch (Exception e) {
// This should not happen
element = null;
Expand Down Expand Up @@ -417,7 +459,13 @@ public boolean apply(ElementInterface newElement, boolean clean)
*/
public void setOwnerDocument(XWikiDocument ownerDocument)
{
this.ownerDocument = ownerDocument;
if (this.ownerDocument != ownerDocument) {
this.ownerDocument = ownerDocument;

if (this.ownerDocument != null && isDirty()) {
this.ownerDocument.setMetaDataDirty(true);
}
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
*/
package com.xpn.xwiki.objects;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
Expand All @@ -44,7 +43,7 @@
import com.xpn.xwiki.objects.classes.PropertyClass;
import com.xpn.xwiki.web.Utils;

public class BaseObject extends BaseCollection<BaseObjectReference> implements ObjectInterface, Serializable, Cloneable
public class BaseObject extends BaseCollection<BaseObjectReference> implements ObjectInterface, Cloneable
{
private static final long serialVersionUID = 1L;

Expand Down Expand Up @@ -201,6 +200,8 @@ public BaseObject clone()
// is expensive)
object.setGuid(this.guid);

object.setDirty(isDirty());

return object;
}

Expand Down
Loading

0 comments on commit 71756b8

Please sign in to comment.