mirror of
https://github.com/Alfresco/SearchServices.git
synced 2025-09-17 14:21:20 +00:00
Merged HEAD-BUG-FIX (5.0/Cloud) to HEAD (5.0/Cloud)
76927: Merged PLATFORM1 (5.0/Cloud) to HEAD-BUG-FIX (5.0/Cloud) 67096: Merged BRANCHES/DEV/aowian/plat1_solr4 to BRANCHES/DEV/PLATFORM1 BRANCHES/DEV/PLATFORM1: 65032: ACE-916: Carve out tracking from SOLR 1.4 - Initial checkin. Does not compile 65034: ACE-916: Carve out tracking from SOLR 1.4 - Another checkin. Does not compile 65036: ACE-916: Carve out tracking from SOLR 1.4 - Another checkin. Does not compile - Added InformationServer interface 65393: ACE-916: Carve out tracking from SOLR 1.4 - Another checkin. Does not compile 65963: ACE-916: Carve out tracking from SOLR 1.4 - Changed references of toDocument method to LegacySolrInformationServer 65988: ACE-916: Carve out tracking from SOLR 1.4 - Created individual classes and got CoreTracker and LegacySolrInformationServer to compile 66090: ACE-916: Carve out tracking from SOLR 1.4 - Getting closer to no red 66091: ACE-916: Carve out tracking from SOLR 1.4 - Getting closer to no red 66092: ACE-916: Carve out tracking from SOLR 1.4 - Getting closer to no red 66847: ACE-916: Carve out tracking from SOLR 1.4 - Updated eclipse .project files to include SONAR nature - Updated solr4 pom to use different port - Added adapter for solr data object in SOLR Client, therefore introducing dependency on legacy jars while keeping the main client code version agnostic - TODO: Finish making Tracker API work in client project, and explore moving trackers into client project 66863: ACE-916: Carve out tracking from SOLR 1.4 - Moved Tracker, TrackerStats, etc into Client project, and abstracted some data objects. - TODO: Deal with AlfrescoSolrDataModel 66926: ACE-916: Carve out tracking from SOLR 1.4 - Removed some classes that had already been moved - TODO: Deal with AlfrescoSolrDataModel 66957: ACE-916: Carve out tracking from SOLR 1.4 - Moved adapters into legacy solr project and removed client project's dependency on legacy jars. - TODO: Deal with AlfrescoSolrDataModel 66959: ACE-916: Carve out tracking from SOLR 1.4 - Moved AlfrescoSolrDataModel to InformationServer and exposed needed APIs - Finally, the red is gone, and the code compiles. 67027: ACE-916: Carve out tracking from SOLR 1.4 - Removed unused import 67028: ACE-916: Carve out tracking from SOLR 1.4 - Merged PLATFORM1 to aowian/plat1_solr4 67029: ACE-916: Carve out tracking from SOLR 1.4 - Merged PLATFORM1 to aowian/plat1_solr4 67076: ACE-916: Carve out tracking from SOLR 1.4 - Reverse merged from aowian/plat1_solr4 to aowian/plat1_solr4 at -67028 67090: ACE-916: Carve out tracking from SOLR 1.4 - Merged PLATFORM1 at 67076 to aowian/plat1_solr4 67093: ACE-916: Carve out tracking from SOLR 1.4 - Merged PLATFORM1 at 67085 to aowian/plat1_solr4 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@77771 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.solr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andy
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class AclReport
|
||||||
|
{
|
||||||
|
|
||||||
|
private Long aclId;
|
||||||
|
|
||||||
|
private boolean existsInDb;
|
||||||
|
|
||||||
|
private Long indexAclDoc;
|
||||||
|
|
||||||
|
private Long indexAclTx;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the aclId
|
||||||
|
*/
|
||||||
|
public Long getAclId()
|
||||||
|
{
|
||||||
|
return aclId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param aclId the aclId to set
|
||||||
|
*/
|
||||||
|
public void setAclId(Long aclId)
|
||||||
|
{
|
||||||
|
this.aclId = aclId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the existsInDb
|
||||||
|
*/
|
||||||
|
public boolean isExistsInDb()
|
||||||
|
{
|
||||||
|
return existsInDb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param existsInDb the existsInDb to set
|
||||||
|
*/
|
||||||
|
public void setExistsInDb(boolean existsInDb)
|
||||||
|
{
|
||||||
|
this.existsInDb = existsInDb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the indexAclDoc
|
||||||
|
*/
|
||||||
|
public Long getIndexAclDoc()
|
||||||
|
{
|
||||||
|
return indexAclDoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param indexAclDoc the indexAclDoc to set
|
||||||
|
*/
|
||||||
|
public void setIndexAclDoc(Long indexAclDoc)
|
||||||
|
{
|
||||||
|
this.indexAclDoc = indexAclDoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the indexAclTx
|
||||||
|
*/
|
||||||
|
public Long getIndexAclTx()
|
||||||
|
{
|
||||||
|
return indexAclTx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param indexAclTx the indexAclTx to set
|
||||||
|
*/
|
||||||
|
public void setIndexAclTx(Long indexAclTx)
|
||||||
|
{
|
||||||
|
this.indexAclTx = indexAclTx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,61 @@
|
|||||||
|
|
||||||
|
package org.alfresco.solr;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.concurrent.LinkedBlockingDeque;
|
||||||
|
|
||||||
|
public class BoundedDeque<T> implements Iterable<T>
|
||||||
|
{
|
||||||
|
private LinkedBlockingDeque<T> deque;
|
||||||
|
|
||||||
|
private int max = 10;
|
||||||
|
|
||||||
|
public BoundedDeque(int max)
|
||||||
|
{
|
||||||
|
this.max = max;
|
||||||
|
setDeque(new LinkedBlockingDeque<T>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return getDeque().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(T add)
|
||||||
|
{
|
||||||
|
while (getDeque().size() > (max - 1))
|
||||||
|
{
|
||||||
|
getDeque().removeLast();
|
||||||
|
}
|
||||||
|
getDeque().addFirst(add);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getLast()
|
||||||
|
{
|
||||||
|
return getDeque().getFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.lang.Iterable#iterator()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Iterator<T> iterator()
|
||||||
|
{
|
||||||
|
return getDeque().iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkedBlockingDeque<T> getDeque()
|
||||||
|
{
|
||||||
|
return deque;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeque(LinkedBlockingDeque<T> deque)
|
||||||
|
{
|
||||||
|
this.deque = deque;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
package org.alfresco.solr;
|
||||||
|
|
||||||
|
public class IndexTrackingShutdownException extends RuntimeException
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -1294455847013444397L;
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.solr;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.alfresco.httpclient.AuthenticationException;
|
||||||
|
import org.alfresco.repo.dictionary.DictionaryComponent;
|
||||||
|
import org.alfresco.repo.dictionary.M2Model;
|
||||||
|
import org.alfresco.repo.dictionary.NamespaceDAO;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.solr.adapters.IOpenBitSet;
|
||||||
|
import org.alfresco.solr.adapters.ISimpleOrderedMap;
|
||||||
|
import org.alfresco.solr.client.AclChangeSet;
|
||||||
|
import org.alfresco.solr.client.AclReaders;
|
||||||
|
import org.alfresco.solr.client.AlfrescoModel;
|
||||||
|
import org.alfresco.solr.client.Node;
|
||||||
|
import org.alfresco.solr.client.Transaction;
|
||||||
|
import org.alfresco.solr.tracker.Tracker;
|
||||||
|
import org.json.JSONException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the interface to the information server, whether it be Solr or some other search server.
|
||||||
|
* @author Ahmed Owian
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface InformationServer
|
||||||
|
{
|
||||||
|
|
||||||
|
void rollback() throws IOException;
|
||||||
|
|
||||||
|
void commit() throws IOException;
|
||||||
|
|
||||||
|
void indexAclTransaction(AclChangeSet changeSet, boolean overwrite) throws IOException;
|
||||||
|
|
||||||
|
void indexTransaction(Transaction info, boolean overwrite) throws IOException;
|
||||||
|
|
||||||
|
void deleteByTransactionId(Long transactionId) throws IOException;
|
||||||
|
|
||||||
|
void deleteByAclChangeSetId(Long aclChangeSetId) throws IOException;
|
||||||
|
|
||||||
|
void deleteByAclId(Long aclId) throws IOException;
|
||||||
|
|
||||||
|
void deleteByNodeId(Long nodeId) throws IOException;
|
||||||
|
|
||||||
|
void indexNode(Node node, boolean overwrite) throws IOException, AuthenticationException, JSONException;
|
||||||
|
|
||||||
|
NodeReport checkNodeCommon(NodeReport nodeReport);
|
||||||
|
|
||||||
|
long indexAcl(List<AclReaders> aclReaderList, boolean overwrite) throws IOException;
|
||||||
|
|
||||||
|
TrackerState getTrackerInitialState() throws IOException;
|
||||||
|
|
||||||
|
int getDocSetSize(String targetTxId, String targetTxCommitTime) throws IOException;
|
||||||
|
|
||||||
|
int getRegisteredSearcherCount();
|
||||||
|
|
||||||
|
TrackerState getTrackerState();
|
||||||
|
|
||||||
|
void checkCache() throws IOException;
|
||||||
|
|
||||||
|
boolean isInIndex(String fieldType, long id) throws IOException;
|
||||||
|
|
||||||
|
Set<Long> getErrorDocIds() throws IOException;
|
||||||
|
|
||||||
|
Iterable<Map.Entry<String, Object>> getCoreStats() throws IOException;
|
||||||
|
|
||||||
|
Tracker getTracker();
|
||||||
|
|
||||||
|
Map<String, Set<String>> getModelErrors();
|
||||||
|
|
||||||
|
IOpenBitSet getOpenBitSetInstance();
|
||||||
|
|
||||||
|
<T> ISimpleOrderedMap<T> getSimpleOrderedMapInstance();
|
||||||
|
|
||||||
|
DictionaryComponent getDictionaryService(String alternativeDictionary);
|
||||||
|
|
||||||
|
NamespaceDAO getNamespaceDAO();
|
||||||
|
|
||||||
|
List<AlfrescoModel> getAlfrescoModels();
|
||||||
|
|
||||||
|
void afterInitModels();
|
||||||
|
|
||||||
|
boolean putModel(M2Model model);
|
||||||
|
|
||||||
|
M2Model getM2Model(QName modelQName);
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.solr;
|
||||||
|
|
||||||
|
import org.alfresco.solr.client.Node.SolrApiNodeStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andy
|
||||||
|
*/
|
||||||
|
public class NodeReport
|
||||||
|
{
|
||||||
|
private Long dbid;
|
||||||
|
|
||||||
|
private Long dbTx;
|
||||||
|
|
||||||
|
private SolrApiNodeStatus dbNodeStatus;
|
||||||
|
|
||||||
|
private Long indexLeafDoc;
|
||||||
|
|
||||||
|
private Long indexAuxDoc;
|
||||||
|
|
||||||
|
private Long indexLeafTx;
|
||||||
|
|
||||||
|
private Long indexAuxTx;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the dbid
|
||||||
|
*/
|
||||||
|
public Long getDbid()
|
||||||
|
{
|
||||||
|
return dbid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dbid
|
||||||
|
* the dbid to set
|
||||||
|
*/
|
||||||
|
public void setDbid(Long dbid)
|
||||||
|
{
|
||||||
|
this.dbid = dbid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the dbTx
|
||||||
|
*/
|
||||||
|
public Long getDbTx()
|
||||||
|
{
|
||||||
|
return dbTx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dbTx
|
||||||
|
* the dbTx to set
|
||||||
|
*/
|
||||||
|
public void setDbTx(Long dbTx)
|
||||||
|
{
|
||||||
|
this.dbTx = dbTx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the dbNodeStatus
|
||||||
|
*/
|
||||||
|
public SolrApiNodeStatus getDbNodeStatus()
|
||||||
|
{
|
||||||
|
return dbNodeStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dbNodeStatus
|
||||||
|
* the dbNodeStatus to set
|
||||||
|
*/
|
||||||
|
public void setDbNodeStatus(SolrApiNodeStatus dbNodeStatus)
|
||||||
|
{
|
||||||
|
this.dbNodeStatus = dbNodeStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the indexLeafDoc
|
||||||
|
*/
|
||||||
|
public Long getIndexLeafDoc()
|
||||||
|
{
|
||||||
|
return indexLeafDoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param indexLeafDoc
|
||||||
|
* the indexLeafDoc to set
|
||||||
|
*/
|
||||||
|
public void setIndexLeafDoc(Long indexLeafDoc)
|
||||||
|
{
|
||||||
|
this.indexLeafDoc = indexLeafDoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the indexAuxDoc
|
||||||
|
*/
|
||||||
|
public Long getIndexAuxDoc()
|
||||||
|
{
|
||||||
|
return indexAuxDoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param indexAuxDoc
|
||||||
|
* the indexAuxDoc to set
|
||||||
|
*/
|
||||||
|
public void setIndexAuxDoc(Long indexAuxDoc)
|
||||||
|
{
|
||||||
|
this.indexAuxDoc = indexAuxDoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the indexLeafTx
|
||||||
|
*/
|
||||||
|
public Long getIndexLeafTx()
|
||||||
|
{
|
||||||
|
return indexLeafTx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param indexLeafTx the indexLeafTx to set
|
||||||
|
*/
|
||||||
|
public void setIndexLeafTx(Long indexLeafTx)
|
||||||
|
{
|
||||||
|
this.indexLeafTx = indexLeafTx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the indexAuxTx
|
||||||
|
*/
|
||||||
|
public Long getIndexAuxTx()
|
||||||
|
{
|
||||||
|
return indexAuxTx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param indexAuxTx the indexAuxTx to set
|
||||||
|
*/
|
||||||
|
public void setIndexAuxTx(Long indexAuxTx)
|
||||||
|
{
|
||||||
|
this.indexAuxTx = indexAuxTx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,231 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.solr;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class was moved from org.alfresco.solr.tracker.CoreTracker
|
||||||
|
*/
|
||||||
|
public class TrackerState
|
||||||
|
{
|
||||||
|
private volatile long lastChangeSetIdOnServer;
|
||||||
|
|
||||||
|
private volatile long lastChangeSetCommitTimeOnServer;
|
||||||
|
|
||||||
|
private volatile long lastIndexedChangeSetId;
|
||||||
|
|
||||||
|
private volatile long lastIndexedTxCommitTime = 0;
|
||||||
|
|
||||||
|
private volatile long lastIndexedTxId = 0;
|
||||||
|
|
||||||
|
private volatile long lastIndexedChangeSetCommitTime = 0;
|
||||||
|
|
||||||
|
private volatile long lastTxCommitTimeOnServer = 0;
|
||||||
|
|
||||||
|
private volatile long lastTxIdOnServer = 0;
|
||||||
|
|
||||||
|
private volatile long lastIndexedTxIdBeforeHoles = -1;
|
||||||
|
|
||||||
|
private volatile long lastIndexedChangeSetIdBeforeHoles = -1;
|
||||||
|
|
||||||
|
private volatile boolean running = false;
|
||||||
|
|
||||||
|
private volatile boolean checkedFirstTransactionTime = false;
|
||||||
|
|
||||||
|
private volatile boolean check = false;
|
||||||
|
|
||||||
|
private long timeToStopIndexing;
|
||||||
|
|
||||||
|
private long lastGoodChangeSetCommitTimeInIndex;
|
||||||
|
|
||||||
|
private long lastGoodTxCommitTimeInIndex ;
|
||||||
|
|
||||||
|
private long timeBeforeWhichThereCanBeNoHoles;
|
||||||
|
|
||||||
|
public long getLastChangeSetIdOnServer()
|
||||||
|
{
|
||||||
|
return lastChangeSetIdOnServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastChangeSetIdOnServer(long lastChangeSetIdOnServer)
|
||||||
|
{
|
||||||
|
this.lastChangeSetIdOnServer = lastChangeSetIdOnServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastChangeSetCommitTimeOnServer()
|
||||||
|
{
|
||||||
|
return lastChangeSetCommitTimeOnServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastChangeSetCommitTimeOnServer(long lastChangeSetCommitTimeOnServer)
|
||||||
|
{
|
||||||
|
this.lastChangeSetCommitTimeOnServer = lastChangeSetCommitTimeOnServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastIndexedChangeSetId()
|
||||||
|
{
|
||||||
|
return lastIndexedChangeSetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastIndexedChangeSetId(long lastIndexedChangeSetId)
|
||||||
|
{
|
||||||
|
this.lastIndexedChangeSetId = lastIndexedChangeSetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastIndexedTxCommitTime()
|
||||||
|
{
|
||||||
|
return lastIndexedTxCommitTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastIndexedTxCommitTime(long lastIndexedTxCommitTime)
|
||||||
|
{
|
||||||
|
this.lastIndexedTxCommitTime = lastIndexedTxCommitTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastIndexedTxId()
|
||||||
|
{
|
||||||
|
return lastIndexedTxId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastIndexedTxId(long lastIndexedTxId)
|
||||||
|
{
|
||||||
|
this.lastIndexedTxId = lastIndexedTxId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastIndexedChangeSetCommitTime()
|
||||||
|
{
|
||||||
|
return lastIndexedChangeSetCommitTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastIndexedChangeSetCommitTime(long lastIndexedChangeSetCommitTime)
|
||||||
|
{
|
||||||
|
this.lastIndexedChangeSetCommitTime = lastIndexedChangeSetCommitTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastTxCommitTimeOnServer()
|
||||||
|
{
|
||||||
|
return lastTxCommitTimeOnServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastTxCommitTimeOnServer(long lastTxCommitTimeOnServer)
|
||||||
|
{
|
||||||
|
this.lastTxCommitTimeOnServer = lastTxCommitTimeOnServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastTxIdOnServer()
|
||||||
|
{
|
||||||
|
return lastTxIdOnServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastTxIdOnServer(long lastTxIdOnServer)
|
||||||
|
{
|
||||||
|
this.lastTxIdOnServer = lastTxIdOnServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastIndexedTxIdBeforeHoles()
|
||||||
|
{
|
||||||
|
return lastIndexedTxIdBeforeHoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastIndexedTxIdBeforeHoles(long lastIndexedTxIdBeforeHoles)
|
||||||
|
{
|
||||||
|
this.lastIndexedTxIdBeforeHoles = lastIndexedTxIdBeforeHoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastIndexedChangeSetIdBeforeHoles()
|
||||||
|
{
|
||||||
|
return lastIndexedChangeSetIdBeforeHoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastIndexedChangeSetIdBeforeHoles(long lastIndexedChangeSetIdBeforeHoles)
|
||||||
|
{
|
||||||
|
this.lastIndexedChangeSetIdBeforeHoles = lastIndexedChangeSetIdBeforeHoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRunning()
|
||||||
|
{
|
||||||
|
return running;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRunning(boolean running)
|
||||||
|
{
|
||||||
|
this.running = running;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCheckedFirstTransactionTime()
|
||||||
|
{
|
||||||
|
return checkedFirstTransactionTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCheckedFirstTransactionTime(boolean checkedFirstTransactionTime)
|
||||||
|
{
|
||||||
|
this.checkedFirstTransactionTime = checkedFirstTransactionTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCheck()
|
||||||
|
{
|
||||||
|
return check;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCheck(boolean check)
|
||||||
|
{
|
||||||
|
this.check = check;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTimeToStopIndexing()
|
||||||
|
{
|
||||||
|
return timeToStopIndexing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeToStopIndexing(long timeToStopIndexing)
|
||||||
|
{
|
||||||
|
this.timeToStopIndexing = timeToStopIndexing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastGoodChangeSetCommitTimeInIndex()
|
||||||
|
{
|
||||||
|
return lastGoodChangeSetCommitTimeInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastGoodChangeSetCommitTimeInIndex(long lastGoodChangeSetCommitTimeInIndex)
|
||||||
|
{
|
||||||
|
this.lastGoodChangeSetCommitTimeInIndex = lastGoodChangeSetCommitTimeInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastGoodTxCommitTimeInIndex()
|
||||||
|
{
|
||||||
|
return lastGoodTxCommitTimeInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastGoodTxCommitTimeInIndex(long lastGoodTxCommitTimeInIndex)
|
||||||
|
{
|
||||||
|
this.lastGoodTxCommitTimeInIndex = lastGoodTxCommitTimeInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTimeBeforeWhichThereCanBeNoHoles()
|
||||||
|
{
|
||||||
|
return timeBeforeWhichThereCanBeNoHoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeBeforeWhichThereCanBeNoHoles(long timeBeforeWhichThereCanBeNoHoles)
|
||||||
|
{
|
||||||
|
this.timeBeforeWhichThereCanBeNoHoles = timeBeforeWhichThereCanBeNoHoles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
package org.alfresco.solr.adapters;
|
||||||
|
|
||||||
|
public interface IOpenBitSet
|
||||||
|
{
|
||||||
|
|
||||||
|
void set(long txid);
|
||||||
|
|
||||||
|
void or(IOpenBitSet duplicatedTxInIndex);
|
||||||
|
|
||||||
|
long nextSetBit(long l);
|
||||||
|
|
||||||
|
long cardinality();
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
package org.alfresco.solr.adapters;
|
||||||
|
|
||||||
|
|
||||||
|
public interface ISimpleOrderedMap<T>
|
||||||
|
{
|
||||||
|
|
||||||
|
void add(String name, T val);
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,428 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.solr.tracker;
|
||||||
|
|
||||||
|
import org.alfresco.solr.InformationServer;
|
||||||
|
import org.alfresco.solr.adapters.IOpenBitSet;
|
||||||
|
|
||||||
|
|
||||||
|
public class IndexHealthReport
|
||||||
|
{
|
||||||
|
long dbTransactionCount;
|
||||||
|
|
||||||
|
IOpenBitSet missingTxFromIndex;
|
||||||
|
|
||||||
|
IOpenBitSet duplicatedTxInIndex;
|
||||||
|
|
||||||
|
IOpenBitSet txInIndexButNotInDb;
|
||||||
|
|
||||||
|
IOpenBitSet duplicatedLeafInIndex;
|
||||||
|
|
||||||
|
IOpenBitSet duplicatedAuxInIndex;
|
||||||
|
|
||||||
|
long transactionDocsInIndex;
|
||||||
|
|
||||||
|
long uniqueTransactionDocsInIndex;
|
||||||
|
|
||||||
|
long uniqueAclTransactionDocsInIndex;
|
||||||
|
|
||||||
|
long aclTransactionDocsInIndex;
|
||||||
|
|
||||||
|
long leafDocCountInIndex;
|
||||||
|
|
||||||
|
long auxDocCountInIndex;
|
||||||
|
|
||||||
|
long lastIndexedCommitTime;
|
||||||
|
|
||||||
|
long lastIndexedIdBeforeHoles;
|
||||||
|
|
||||||
|
long dbAclTransactionCount;
|
||||||
|
|
||||||
|
IOpenBitSet missingAclTxFromIndex;
|
||||||
|
|
||||||
|
IOpenBitSet duplicatedAclTxInIndex;
|
||||||
|
|
||||||
|
IOpenBitSet aclTxInIndexButNotInDb;
|
||||||
|
|
||||||
|
IOpenBitSet duplicatedErrorInIndex;
|
||||||
|
|
||||||
|
IOpenBitSet duplicatedUnindexedInIndex;
|
||||||
|
|
||||||
|
long errorDocCountInIndex;
|
||||||
|
|
||||||
|
long unindexedDocCountInIndex;
|
||||||
|
|
||||||
|
public IndexHealthReport(InformationServer srv)
|
||||||
|
{
|
||||||
|
this.missingTxFromIndex = srv.getOpenBitSetInstance();
|
||||||
|
this.duplicatedTxInIndex = srv.getOpenBitSetInstance();
|
||||||
|
this.txInIndexButNotInDb = srv.getOpenBitSetInstance();
|
||||||
|
this.duplicatedLeafInIndex = srv.getOpenBitSetInstance();
|
||||||
|
this.duplicatedAuxInIndex = srv.getOpenBitSetInstance();
|
||||||
|
|
||||||
|
this.missingAclTxFromIndex = srv.getOpenBitSetInstance();
|
||||||
|
this.duplicatedAclTxInIndex = srv.getOpenBitSetInstance();
|
||||||
|
this.aclTxInIndexButNotInDb = srv.getOpenBitSetInstance();
|
||||||
|
this.duplicatedErrorInIndex = srv.getOpenBitSetInstance();
|
||||||
|
this.duplicatedUnindexedInIndex = srv.getOpenBitSetInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the transactionDocsInIndex
|
||||||
|
*/
|
||||||
|
public long getTransactionDocsInIndex()
|
||||||
|
{
|
||||||
|
return transactionDocsInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getAclTransactionDocsInIndex()
|
||||||
|
{
|
||||||
|
return aclTransactionDocsInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param leafCount
|
||||||
|
*/
|
||||||
|
public void setLeafDocCountInIndex(long leafDocCountInIndex)
|
||||||
|
{
|
||||||
|
this.leafDocCountInIndex = leafDocCountInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the leafDocCountInIndex
|
||||||
|
*/
|
||||||
|
public long getLeafDocCountInIndex()
|
||||||
|
{
|
||||||
|
return leafDocCountInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param auxCount
|
||||||
|
*/
|
||||||
|
public void setAuxDocCountInIndex(long auxDocCountInIndex)
|
||||||
|
{
|
||||||
|
this.auxDocCountInIndex = auxDocCountInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the leafDocCountInIndex
|
||||||
|
*/
|
||||||
|
public long getAuxDocCountInIndex()
|
||||||
|
{
|
||||||
|
return auxDocCountInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param txid
|
||||||
|
*/
|
||||||
|
public void setDuplicatedLeafInIndex(long txid)
|
||||||
|
{
|
||||||
|
duplicatedLeafInIndex.set(txid);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the duplicatedLeafInIndex
|
||||||
|
*/
|
||||||
|
public IOpenBitSet getDuplicatedLeafInIndex()
|
||||||
|
{
|
||||||
|
return duplicatedLeafInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param txid
|
||||||
|
*/
|
||||||
|
public void setDuplicatedAuxInIndex(long txid)
|
||||||
|
{
|
||||||
|
duplicatedAuxInIndex.set(txid);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the duplicatedLeafInIndex
|
||||||
|
*/
|
||||||
|
public IOpenBitSet getDuplicatedAuxInIndex()
|
||||||
|
{
|
||||||
|
return duplicatedAuxInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param transactionDocsInIndex
|
||||||
|
* the transactionDocsInIndex to set
|
||||||
|
*/
|
||||||
|
public void setTransactionDocsInIndex(long transactionDocsInIndex)
|
||||||
|
{
|
||||||
|
this.transactionDocsInIndex = transactionDocsInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param transactionDocsInIndex
|
||||||
|
* the transactionDocsInIndex to set
|
||||||
|
*/
|
||||||
|
public void setAclTransactionDocsInIndex(long aclTransactionDocsInIndex)
|
||||||
|
{
|
||||||
|
this.aclTransactionDocsInIndex = aclTransactionDocsInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the missingFromIndex
|
||||||
|
*/
|
||||||
|
public IOpenBitSet getMissingTxFromIndex()
|
||||||
|
{
|
||||||
|
return missingTxFromIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the missingFromIndex
|
||||||
|
*/
|
||||||
|
public IOpenBitSet getMissingAclTxFromIndex()
|
||||||
|
{
|
||||||
|
return missingAclTxFromIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the duplicatedInIndex
|
||||||
|
*/
|
||||||
|
public IOpenBitSet getDuplicatedTxInIndex()
|
||||||
|
{
|
||||||
|
return duplicatedTxInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the duplicatedInIndex
|
||||||
|
*/
|
||||||
|
public IOpenBitSet getDuplicatedAclTxInIndex()
|
||||||
|
{
|
||||||
|
return duplicatedAclTxInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the inIndexButNotInDb
|
||||||
|
*/
|
||||||
|
public IOpenBitSet getTxInIndexButNotInDb()
|
||||||
|
{
|
||||||
|
return txInIndexButNotInDb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the inIndexButNotInDb
|
||||||
|
*/
|
||||||
|
public IOpenBitSet getAclTxInIndexButNotInDb()
|
||||||
|
{
|
||||||
|
return aclTxInIndexButNotInDb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the dbTransactionCount
|
||||||
|
*/
|
||||||
|
public long getDbTransactionCount()
|
||||||
|
{
|
||||||
|
return dbTransactionCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dbTransactionCount
|
||||||
|
* the dbTransactionCount to set
|
||||||
|
*/
|
||||||
|
public void setDbTransactionCount(long dbTransactionCount)
|
||||||
|
{
|
||||||
|
this.dbTransactionCount = dbTransactionCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMissingTxFromIndex(long txid)
|
||||||
|
{
|
||||||
|
missingTxFromIndex.set(txid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMissingAclTxFromIndex(long txid)
|
||||||
|
{
|
||||||
|
missingAclTxFromIndex.set(txid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDuplicatedTxInIndex(long txid)
|
||||||
|
{
|
||||||
|
duplicatedTxInIndex.set(txid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDuplicatedAclTxInIndex(long txid)
|
||||||
|
{
|
||||||
|
duplicatedAclTxInIndex.set(txid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTxInIndexButNotInDb(long txid)
|
||||||
|
{
|
||||||
|
txInIndexButNotInDb.set(txid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAclTxInIndexButNotInDb(long txid)
|
||||||
|
{
|
||||||
|
aclTxInIndexButNotInDb.set(txid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param lastIndexCommitTime
|
||||||
|
* the lastIndexCommitTime to set
|
||||||
|
*/
|
||||||
|
public void setLastIndexedCommitTime(long lastIndexedCommitTime)
|
||||||
|
{
|
||||||
|
this.lastIndexedCommitTime = lastIndexedCommitTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the lastIndexedIdBeforeHoles
|
||||||
|
*/
|
||||||
|
public long getLastIndexedIdBeforeHoles()
|
||||||
|
{
|
||||||
|
return lastIndexedIdBeforeHoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param lastIndexedIdBeforeHoles
|
||||||
|
* the lastIndexedIdBeforeHoles to set
|
||||||
|
*/
|
||||||
|
public void setLastIndexedIdBeforeHoles(long lastIndexedIdBeforeHoles)
|
||||||
|
{
|
||||||
|
this.lastIndexedIdBeforeHoles = lastIndexedIdBeforeHoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param cardinality
|
||||||
|
*/
|
||||||
|
public void setDbAclTransactionCount(long dbAclTransactionCount)
|
||||||
|
{
|
||||||
|
this.dbAclTransactionCount = dbAclTransactionCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the dbAclTransactionCount
|
||||||
|
*/
|
||||||
|
public long getDbAclTransactionCount()
|
||||||
|
{
|
||||||
|
return dbAclTransactionCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the uniqueTransactionDocsInIndex
|
||||||
|
*/
|
||||||
|
public long getUniqueTransactionDocsInIndex()
|
||||||
|
{
|
||||||
|
return uniqueTransactionDocsInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param uniqueTransactionDocsInIndex the uniqueTransactionDocsInIndex to set
|
||||||
|
*/
|
||||||
|
public void setUniqueTransactionDocsInIndex(long uniqueTransactionDocsInIndex)
|
||||||
|
{
|
||||||
|
this.uniqueTransactionDocsInIndex = uniqueTransactionDocsInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the uniqueAclTransactionDocsInIndex
|
||||||
|
*/
|
||||||
|
public long getUniqueAclTransactionDocsInIndex()
|
||||||
|
{
|
||||||
|
return uniqueAclTransactionDocsInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param uniqueAclTransactionDocsInIndex the uniqueAclTransactionDocsInIndex to set
|
||||||
|
*/
|
||||||
|
public void setUniqueAclTransactionDocsInIndex(long uniqueAclTransactionDocsInIndex)
|
||||||
|
{
|
||||||
|
this.uniqueAclTransactionDocsInIndex = uniqueAclTransactionDocsInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the lastIndexedCommitTime
|
||||||
|
*/
|
||||||
|
public long getLastIndexedCommitTime()
|
||||||
|
{
|
||||||
|
return lastIndexedCommitTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param unindexedCount
|
||||||
|
*/
|
||||||
|
public void setUnindexedDocCountInIndex(long unindexedDocCountInIndex)
|
||||||
|
{
|
||||||
|
this.unindexedDocCountInIndex = unindexedDocCountInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param txid
|
||||||
|
*/
|
||||||
|
public void setDuplicatedUnindexedInIndex(long txid)
|
||||||
|
{
|
||||||
|
duplicatedUnindexedInIndex.set(txid);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param errorCount
|
||||||
|
*/
|
||||||
|
public void setErrorDocCountInIndex(long errorDocCountInIndex)
|
||||||
|
{
|
||||||
|
this.errorDocCountInIndex = errorDocCountInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param txid
|
||||||
|
*/
|
||||||
|
public void setDuplicatedErrorInIndex(long txid)
|
||||||
|
{
|
||||||
|
duplicatedErrorInIndex.set(txid);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the duplicatedErrorInIndex
|
||||||
|
*/
|
||||||
|
public IOpenBitSet getDuplicatedErrorInIndex()
|
||||||
|
{
|
||||||
|
return duplicatedErrorInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the duplicatedUnindexedInIndex
|
||||||
|
*/
|
||||||
|
public IOpenBitSet getDuplicatedUnindexedInIndex()
|
||||||
|
{
|
||||||
|
return duplicatedUnindexedInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the errorDocCountInIndex
|
||||||
|
*/
|
||||||
|
public long getErrorDocCountInIndex()
|
||||||
|
{
|
||||||
|
return errorDocCountInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the unindexedDocCountInIndex
|
||||||
|
*/
|
||||||
|
public long getUnindexedDocCountInIndex()
|
||||||
|
{
|
||||||
|
return unindexedDocCountInIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.alfresco.solr.tracker;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.alfresco.httpclient.AuthenticationException;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.solr.AclReport;
|
||||||
|
import org.alfresco.solr.NodeReport;
|
||||||
|
import org.alfresco.solr.client.Node;
|
||||||
|
import org.alfresco.solr.client.NodeMetaData;
|
||||||
|
import org.alfresco.solr.client.NodeMetaDataParameters;
|
||||||
|
import org.alfresco.solr.client.SOLRAPIClient.GetTextContentResponse;
|
||||||
|
import org.json.JSONException;
|
||||||
|
|
||||||
|
public interface Tracker
|
||||||
|
{
|
||||||
|
|
||||||
|
int getMaxLiveSearchers();
|
||||||
|
|
||||||
|
void updateIndex();
|
||||||
|
|
||||||
|
void indexAclChangeSets() throws AuthenticationException, IOException, JSONException;
|
||||||
|
|
||||||
|
void indexAcls() throws AuthenticationException, IOException, JSONException;
|
||||||
|
|
||||||
|
void reindexAclChangeSets() throws AuthenticationException, IOException, JSONException;
|
||||||
|
|
||||||
|
void reindexAcls() throws AuthenticationException, IOException, JSONException;
|
||||||
|
|
||||||
|
void purgeAclChangeSets() throws AuthenticationException, IOException, JSONException;
|
||||||
|
|
||||||
|
void purgeAcls() throws AuthenticationException, IOException, JSONException;
|
||||||
|
|
||||||
|
void addTransactionToReindex(Long transactionToReindex);
|
||||||
|
|
||||||
|
void addTransactionToIndex(Long transactionToIndex);
|
||||||
|
|
||||||
|
void addTransactionToPurge(Long transactionToPurge);
|
||||||
|
|
||||||
|
void addNodeToReindex(Long nodeToReindex);
|
||||||
|
|
||||||
|
void addNodeToIndex(Long nodeToIndex);
|
||||||
|
|
||||||
|
void addNodeToPurge(Long nodeToPurge);
|
||||||
|
|
||||||
|
void addAclChangeSetToReindex(Long aclChangeSetToReindex);
|
||||||
|
|
||||||
|
void addAclChangeSetToIndex(Long aclChangeSetToIndex);
|
||||||
|
|
||||||
|
void addAclChangeSetToPurge(Long aclChangeSetToPurge);
|
||||||
|
|
||||||
|
void addAclToReindex(Long aclToReindex);
|
||||||
|
|
||||||
|
void addAclToIndex(Long aclToIndex);
|
||||||
|
|
||||||
|
void addAclToPurge(Long aclToPurge);
|
||||||
|
|
||||||
|
void trackRepository() throws IOException, AuthenticationException, JSONException;
|
||||||
|
|
||||||
|
IndexHealthReport checkIndex(Long fromTx, Long toTx, Long fromAclTx, Long toAclTx, Long fromTime,
|
||||||
|
Long toTime) throws AuthenticationException, IOException, JSONException;
|
||||||
|
|
||||||
|
NodeReport checkNode(Node node);
|
||||||
|
|
||||||
|
NodeReport checkNode(Long dbid);
|
||||||
|
|
||||||
|
List<Node> getFullNodesForDbTransaction(Long txid);
|
||||||
|
|
||||||
|
List<Long> getAclsForDbAclTransaction(Long acltxid);
|
||||||
|
|
||||||
|
AclReport checkAcl(Long aclid);
|
||||||
|
|
||||||
|
void close();
|
||||||
|
|
||||||
|
void trackModels(boolean onlyFirstTime) throws AuthenticationException, IOException, JSONException;
|
||||||
|
|
||||||
|
void ensureFirstModelSync();
|
||||||
|
|
||||||
|
void setShutdown(boolean shutdown);
|
||||||
|
|
||||||
|
List<NodeMetaData> getNodesMetaData(NodeMetaDataParameters params, int maxResults)
|
||||||
|
throws AuthenticationException, IOException, JSONException;
|
||||||
|
|
||||||
|
GetTextContentResponse getTextContent(Long nodeId, QName propertyQName, Long modifiedSince)
|
||||||
|
throws AuthenticationException, IOException;
|
||||||
|
|
||||||
|
boolean canAddContentPropertyToDoc();
|
||||||
|
|
||||||
|
TrackerStats getTrackerStats();
|
||||||
|
|
||||||
|
String getAlfrescoVersion();
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,857 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.solr.tracker;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import org.alfresco.solr.InformationServer;
|
||||||
|
import org.alfresco.solr.adapters.ISimpleOrderedMap;
|
||||||
|
import org.alfresco.util.Pair;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andy
|
||||||
|
*/
|
||||||
|
public class TrackerStats
|
||||||
|
{
|
||||||
|
public static final int TIME_SCALE = 1000000;
|
||||||
|
|
||||||
|
ConcurrentHashMap<String, IncrementalStats> modelTimes = new ConcurrentHashMap<String, IncrementalStats>();
|
||||||
|
|
||||||
|
ConcurrentHashMap<String, IncrementalStats> aclTimes = new ConcurrentHashMap<String, IncrementalStats>();
|
||||||
|
|
||||||
|
ConcurrentHashMap<String, IncrementalStats> changeSetAcls = new ConcurrentHashMap<String, IncrementalStats>();
|
||||||
|
|
||||||
|
ConcurrentHashMap<String, IncrementalStats> txDocs = new ConcurrentHashMap<String, IncrementalStats>();
|
||||||
|
|
||||||
|
ConcurrentHashMap<String, IncrementalStats> docTransformationTimes = new ConcurrentHashMap<String, IncrementalStats>();
|
||||||
|
|
||||||
|
ConcurrentHashMap<String, IncrementalStats> nodeTimes = new ConcurrentHashMap<String, IncrementalStats>();
|
||||||
|
|
||||||
|
private InformationServer infoSrv;
|
||||||
|
|
||||||
|
public TrackerStats(InformationServer server)
|
||||||
|
{
|
||||||
|
infoSrv = server;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the modelTimes
|
||||||
|
*/
|
||||||
|
public SimpleStats getModelTimes()
|
||||||
|
{
|
||||||
|
return aggregateResults(modelTimes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param modelTimes2
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private SimpleStats aggregateResults(ConcurrentHashMap<String, IncrementalStats> all)
|
||||||
|
{
|
||||||
|
SimpleStats answer = null;
|
||||||
|
|
||||||
|
for (String key : all.keySet())
|
||||||
|
{
|
||||||
|
IncrementalStats next = all.get(key);
|
||||||
|
IncrementalStats stats = next.copy();
|
||||||
|
if (answer == null)
|
||||||
|
{
|
||||||
|
answer = new SimpleStats(stats.scale, this.infoSrv);
|
||||||
|
answer .start = stats.start;
|
||||||
|
answer.moments[0] = stats.moments[0];
|
||||||
|
answer.moments[1] = stats.moments[1];
|
||||||
|
answer.moments[2] = stats.moments[2];
|
||||||
|
answer.max = stats.max;
|
||||||
|
answer.min = stats.min;
|
||||||
|
answer.copies.put(key, stats);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SimpleStats newAnswer = new SimpleStats(answer.scale, this.infoSrv);
|
||||||
|
|
||||||
|
newAnswer.moments[0] = answer.moments[0] + stats.moments[0];
|
||||||
|
|
||||||
|
newAnswer.moments[1] = answer.moments[1] * answer.moments[0] + stats.moments[1] * stats.moments[0];
|
||||||
|
newAnswer.moments[1] /= answer.moments[0] + stats.moments[0];
|
||||||
|
|
||||||
|
newAnswer.moments[2] = answer.moments[2] * answer.moments[0];
|
||||||
|
newAnswer.moments[2] += (answer.moments[1] - newAnswer.moments[1]) * (answer.moments[1] - newAnswer.moments[1]) * answer.moments[0];
|
||||||
|
newAnswer.moments[2] += stats.moments[2] * stats.moments[0];
|
||||||
|
newAnswer.moments[2] += (stats.moments[1] - newAnswer.moments[1]) * (stats.moments[1] - newAnswer.moments[1]) * stats.moments[0];
|
||||||
|
newAnswer.moments[2] /= answer.moments[0] + stats.moments[0];
|
||||||
|
|
||||||
|
newAnswer.min = (stats.min < answer.min) ? stats.min : answer.min;
|
||||||
|
newAnswer.max = (stats.max > answer.max) ? stats.max : answer.max;
|
||||||
|
|
||||||
|
newAnswer.start = (stats.start.compareTo(answer.start) < 1) ? stats.start : answer.start;
|
||||||
|
|
||||||
|
newAnswer.copies.putAll(answer.copies);
|
||||||
|
newAnswer.copies.put(key, stats);
|
||||||
|
|
||||||
|
answer = newAnswer;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (answer == null)
|
||||||
|
{
|
||||||
|
answer = new SimpleStats(1, this.infoSrv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the aclTxTimes
|
||||||
|
*/
|
||||||
|
public SimpleStats getAclTimes()
|
||||||
|
{
|
||||||
|
return aggregateResults(aclTimes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleStats getChangeSetAcls()
|
||||||
|
{
|
||||||
|
return aggregateResults(changeSetAcls);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleStats getNodeTimes()
|
||||||
|
{
|
||||||
|
return aggregateResults(nodeTimes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the txDocs
|
||||||
|
*/
|
||||||
|
public SimpleStats getTxDocs()
|
||||||
|
{
|
||||||
|
return aggregateResults(txDocs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the docTransformationTimes
|
||||||
|
*/
|
||||||
|
public SimpleStats getDocTransformationTimes()
|
||||||
|
{
|
||||||
|
return aggregateResults(docTransformationTimes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMeanModelSyncTime()
|
||||||
|
{
|
||||||
|
return aggregateResults(modelTimes).getMean();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMeanNodeIndexTime()
|
||||||
|
{
|
||||||
|
return aggregateResults(nodeTimes).getMean();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getNodeIndexingThreadCount()
|
||||||
|
{
|
||||||
|
return nodeTimes.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMeanAclIndexTime()
|
||||||
|
{
|
||||||
|
return aggregateResults(nodeTimes).getMean();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMeanDocsPerTx()
|
||||||
|
{
|
||||||
|
return aggregateResults(txDocs).getMean();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMeanAclsPerChangeSet()
|
||||||
|
{
|
||||||
|
return aggregateResults(changeSetAcls).getMean();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SimpleStats
|
||||||
|
{
|
||||||
|
HashMap<String, IncrementalStats> copies = new HashMap<String, IncrementalStats>();
|
||||||
|
private InformationServer server;
|
||||||
|
int scale;
|
||||||
|
|
||||||
|
SimpleStats(int scale, InformationServer server)
|
||||||
|
{
|
||||||
|
this.scale = scale;
|
||||||
|
this.server = server;
|
||||||
|
}
|
||||||
|
|
||||||
|
double[] moments = new double[3];
|
||||||
|
|
||||||
|
double min = 0D;
|
||||||
|
|
||||||
|
double max = 0D;
|
||||||
|
|
||||||
|
Date start = null;
|
||||||
|
|
||||||
|
synchronized long getN()
|
||||||
|
{
|
||||||
|
return (long) moments[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized double getMin()
|
||||||
|
{
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized double getMax()
|
||||||
|
{
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized double getMean()
|
||||||
|
{
|
||||||
|
return moments[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized double getVarience()
|
||||||
|
{
|
||||||
|
if (moments[0] > 1)
|
||||||
|
{
|
||||||
|
return moments[2] * moments[0] / (moments[0] - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Double.NaN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized double getStandardDeviation()
|
||||||
|
{
|
||||||
|
return Math.sqrt(getVarience());
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized ISimpleOrderedMap<Object> getNamedList(boolean incdludeDetail, boolean includeHist, boolean includeValues)
|
||||||
|
{
|
||||||
|
ISimpleOrderedMap<Object> map = this.server.getSimpleOrderedMapInstance();
|
||||||
|
map.add("Start", start);
|
||||||
|
map.add("N", getN());
|
||||||
|
map.add("Min", getMin());
|
||||||
|
map.add("Max", getMax());
|
||||||
|
map.add("Mean", getMean());
|
||||||
|
map.add("Varience", getVarience());
|
||||||
|
map.add("StdDev", getStandardDeviation());
|
||||||
|
if (incdludeDetail)
|
||||||
|
{
|
||||||
|
for (String key : copies.keySet())
|
||||||
|
{
|
||||||
|
IncrementalStats value = copies.get(key);
|
||||||
|
map.add(key, value.getNamedList(includeHist, includeValues));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return "SimpleStats ["
|
||||||
|
+ "\n getN()=" + getN() + ",\n getMin()=" + getMin() + ",\n getMax()=" + getMax() + ",\n getMean()="
|
||||||
|
+ getMean() + ",\n getVarience()=" + getVarience() + ",\n getStandardDeviation()=" + getStandardDeviation() + ",\n copies="
|
||||||
|
+ copies + ",\n]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Bucket
|
||||||
|
{
|
||||||
|
IncrementalStats incrementalStats;
|
||||||
|
|
||||||
|
double leftBoundary;
|
||||||
|
|
||||||
|
double rightBoundary;
|
||||||
|
|
||||||
|
double countLeft;
|
||||||
|
|
||||||
|
double countRight;
|
||||||
|
|
||||||
|
Bucket(IncrementalStats incrementalStats, double leftBoundary, double rightBoundary)
|
||||||
|
{
|
||||||
|
this(incrementalStats, leftBoundary, rightBoundary, 0D, 0D);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bucket(IncrementalStats incrementalStats, double leftBoundary, double rightBoundary, double countLeft, double countRight)
|
||||||
|
{
|
||||||
|
this.incrementalStats = incrementalStats;
|
||||||
|
this.leftBoundary = leftBoundary;
|
||||||
|
this.rightBoundary = rightBoundary;
|
||||||
|
this.countLeft = countLeft;
|
||||||
|
this.countRight = countRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(double x)
|
||||||
|
{
|
||||||
|
if ((x - leftBoundary) < (rightBoundary - x))
|
||||||
|
{
|
||||||
|
countLeft++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
countRight++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public double mergeError(Bucket o)
|
||||||
|
{
|
||||||
|
double f_m = (this.countLeft + this.countRight + o.countLeft + o.countRight) / 4.0d;
|
||||||
|
double t1 = this.countLeft - f_m;
|
||||||
|
double t2 = this.countRight - f_m;
|
||||||
|
double o1 = o.countLeft - f_m;
|
||||||
|
double o2 = o.countRight - f_m;
|
||||||
|
|
||||||
|
return (t1 * t1) + (t2 * t2) + (o1 * o1) + (o2 * o2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double error()
|
||||||
|
{
|
||||||
|
double f_m = (this.countLeft + this.countRight) / 2.0d;
|
||||||
|
double t1 = this.countLeft - f_m;
|
||||||
|
double t2 = this.countRight - f_m;
|
||||||
|
return (t1 * t1) + (t2 * t2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
double mark = (leftBoundary + rightBoundary) / 2.0D;
|
||||||
|
double width = rightBoundary - leftBoundary;
|
||||||
|
return "Bucket [("
|
||||||
|
+ leftBoundary + " TO " + mark + " = " + countLeft / incrementalStats.getN() / width + ") : (" + mark + " TO " + rightBoundary + " = " + countRight
|
||||||
|
/ incrementalStats.getN() / width + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class IncrementalStats
|
||||||
|
{
|
||||||
|
Date start = new Date();
|
||||||
|
|
||||||
|
int scale;
|
||||||
|
|
||||||
|
int buckets;
|
||||||
|
|
||||||
|
double[] moments = new double[5];
|
||||||
|
|
||||||
|
double min = 0D;
|
||||||
|
|
||||||
|
double max = 0D;
|
||||||
|
|
||||||
|
List<Double> values;
|
||||||
|
|
||||||
|
List<Bucket> hist;
|
||||||
|
|
||||||
|
InformationServer server;
|
||||||
|
|
||||||
|
IncrementalStats(int scale, int buckets, InformationServer infoSrv)
|
||||||
|
{
|
||||||
|
this.scale = scale;
|
||||||
|
this.buckets = buckets;
|
||||||
|
values = new ArrayList<Double>(buckets);
|
||||||
|
hist = new ArrayList<Bucket>(buckets + 1);
|
||||||
|
this.server = infoSrv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ISimpleOrderedMap<Object> getNamedList(boolean includeHist, boolean includeValues)
|
||||||
|
{
|
||||||
|
ISimpleOrderedMap<Object> map = this.server.getSimpleOrderedMapInstance();
|
||||||
|
map.add("Start", start);
|
||||||
|
map.add("N", getN());
|
||||||
|
map.add("Min", getMin());
|
||||||
|
map.add("Max", getMax());
|
||||||
|
map.add("Mean", getMean());
|
||||||
|
map.add("Varience", getVarience());
|
||||||
|
map.add("StdDev", getStandardDeviation());
|
||||||
|
map.add("Skew", getSkew());
|
||||||
|
map.add("Kurtosis", getKurtosis());
|
||||||
|
|
||||||
|
if (includeHist)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
ISimpleOrderedMap<Object> buckets = this.server.getSimpleOrderedMapInstance();
|
||||||
|
for (Bucket b : hist)
|
||||||
|
{
|
||||||
|
double mark = (b.leftBoundary + b.rightBoundary) / 2.0D;
|
||||||
|
double width = b.rightBoundary - b.leftBoundary;
|
||||||
|
|
||||||
|
// SimpleOrderedMap<Object> bucket = new SimpleOrderedMap<Object>();
|
||||||
|
// bucket.add("Lower", b.leftBoundary);
|
||||||
|
// bucket.add("Upper", mark);
|
||||||
|
// bucket.add("ProbabilityDensity", b.countLeft/b.incrementalStats.getN()/width);
|
||||||
|
buckets.add("" + i++, (b.leftBoundary + mark) / 2.0D + "," + b.countLeft / b.incrementalStats.getN() / width);
|
||||||
|
|
||||||
|
// bucket = new SimpleOrderedMap<Object>();
|
||||||
|
// bucket.add("Lower", mark);
|
||||||
|
// bucket.add("Upper", b.rightBoundary);
|
||||||
|
// bucket.add("ProbabilityDensity", b.countRight/b.incrementalStats.getN()/width);
|
||||||
|
buckets.add("" + i++, (mark + b.rightBoundary) / 2.0D + "," + b.countRight / b.incrementalStats.getN() / width);
|
||||||
|
}
|
||||||
|
map.add("Buckets", buckets);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (includeValues)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
ISimpleOrderedMap<Object> valuesMap = this.server.getSimpleOrderedMapInstance();
|
||||||
|
for (Double value : values)
|
||||||
|
{
|
||||||
|
valuesMap.add("" + i++, value);
|
||||||
|
}
|
||||||
|
map.add("Values", valuesMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized void reset()
|
||||||
|
{
|
||||||
|
moments = new double[5];
|
||||||
|
|
||||||
|
min = 0D;
|
||||||
|
|
||||||
|
max = 0D;
|
||||||
|
|
||||||
|
values = new ArrayList<Double>(buckets);
|
||||||
|
|
||||||
|
hist = new ArrayList<Bucket>(buckets + 1);
|
||||||
|
|
||||||
|
start = new Date();
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized void add(double xUnscaled)
|
||||||
|
{
|
||||||
|
double x = xUnscaled / scale;
|
||||||
|
if ((moments[0] == 0) || (x > max))
|
||||||
|
{
|
||||||
|
max = x;
|
||||||
|
}
|
||||||
|
if ((moments[0] == 0L) || (x < min))
|
||||||
|
{
|
||||||
|
min = x;
|
||||||
|
}
|
||||||
|
double n = moments[0];
|
||||||
|
double nPlus1 = n + 1;
|
||||||
|
double n2 = n * n;
|
||||||
|
double d = (moments[1] - x) / nPlus1;
|
||||||
|
double d2 = d * d;
|
||||||
|
double d3 = d2 * d;
|
||||||
|
double n_nPlus1 = n / nPlus1;
|
||||||
|
|
||||||
|
moments[4] += 4 * d * moments[3] + 6 * d2 * moments[2] + (1 + n * n2) * d2 * d2;
|
||||||
|
moments[4] *= n_nPlus1;
|
||||||
|
|
||||||
|
moments[3] += 3 * d * moments[2] + (1 - n2) * d3;
|
||||||
|
moments[3] *= n_nPlus1;
|
||||||
|
|
||||||
|
moments[2] += (1 + n) * d2;
|
||||||
|
moments[2] *= n_nPlus1;
|
||||||
|
|
||||||
|
moments[1] -= d;
|
||||||
|
|
||||||
|
moments[0] = nPlus1;
|
||||||
|
|
||||||
|
if (buckets > 1)
|
||||||
|
{
|
||||||
|
if (moments[0] < buckets)
|
||||||
|
{
|
||||||
|
values.add(Double.valueOf(x));
|
||||||
|
}
|
||||||
|
else if (moments[0] == buckets)
|
||||||
|
{
|
||||||
|
values.add(Double.valueOf(x));
|
||||||
|
|
||||||
|
// generate initial bucket list
|
||||||
|
Collections.sort(values);
|
||||||
|
FOUND: for (int i = 0; i < values.size(); i++)
|
||||||
|
{
|
||||||
|
for (Bucket b : hist)
|
||||||
|
{
|
||||||
|
if ((b.leftBoundary <= values.get(i)) && (values.get(i) < b.rightBoundary))
|
||||||
|
{
|
||||||
|
b.add(values.get(i));
|
||||||
|
continue FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (i < values.size() - 1)
|
||||||
|
{
|
||||||
|
double start = values.get(i);
|
||||||
|
double end = start + 1.0D;
|
||||||
|
|
||||||
|
END: for (int j = i + 1; j < values.size(); j++)
|
||||||
|
{
|
||||||
|
if (values.get(j) > start)
|
||||||
|
{
|
||||||
|
end = values.get(j);
|
||||||
|
break END;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bucket b = new Bucket(this, start, end);
|
||||||
|
hist.add(b);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double first = values.get(0);
|
||||||
|
double last = values.get(values.size() - 1);
|
||||||
|
double width = 1.0D;
|
||||||
|
if (values.size() > 1)
|
||||||
|
{
|
||||||
|
width = (last - first) / (values.size() - 1);
|
||||||
|
}
|
||||||
|
Bucket b = new Bucket(this, last, last + width);
|
||||||
|
hist.add(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
values.set((int) moments[0] % buckets, x);
|
||||||
|
if (x < hist.get(0).leftBoundary)
|
||||||
|
{
|
||||||
|
double delta = (hist.get(0).leftBoundary - x) / 3.0;
|
||||||
|
Bucket b = new Bucket(this, x - delta, hist.get(0).leftBoundary);
|
||||||
|
hist.add(0, b);
|
||||||
|
b.add(x);
|
||||||
|
Pair<Integer, Double> bestToMerge = findBestToMerge();
|
||||||
|
if (hist.size() > buckets)
|
||||||
|
{
|
||||||
|
merge(bestToMerge.getFirst());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (x > hist.get(hist.size() - 1).rightBoundary)
|
||||||
|
{
|
||||||
|
double delta = (x - hist.get(hist.size() - 1).rightBoundary) / 3.0;
|
||||||
|
Bucket b = new Bucket(this, hist.get(hist.size() - 1).rightBoundary, x + delta);
|
||||||
|
hist.add(b);
|
||||||
|
b.add(x);
|
||||||
|
Pair<Integer, Double> bestToMerge = findBestToMerge();
|
||||||
|
if (hist.size() > buckets)
|
||||||
|
{
|
||||||
|
merge(bestToMerge.getFirst());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// find existing
|
||||||
|
for (Bucket b : hist)
|
||||||
|
{
|
||||||
|
if ((b.leftBoundary <= x) && (x < b.rightBoundary))
|
||||||
|
{
|
||||||
|
b.add(x);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Pair<Integer, Double> bestToMerge = findBestToMerge();
|
||||||
|
Pair<Integer, Double> bestToSplit = findBestToSplit();
|
||||||
|
if (bestToMerge.getSecond() - bestToSplit.getSecond() < 0)
|
||||||
|
{
|
||||||
|
merge(bestToMerge.getFirst());
|
||||||
|
split(bestToMerge.getFirst() < bestToSplit.getFirst() ? bestToSplit.getFirst() - 1 : bestToSplit.getFirst());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void merge(int position)
|
||||||
|
{
|
||||||
|
Bucket lower = hist.get(position);
|
||||||
|
Bucket upper = hist.get(position + 1);
|
||||||
|
Bucket merged = new Bucket(this, lower.leftBoundary, upper.rightBoundary, lower.countLeft + lower.countRight, upper.countLeft + upper.countRight);
|
||||||
|
hist.remove(position);
|
||||||
|
hist.set(position, merged);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void split(int position)
|
||||||
|
{
|
||||||
|
Bucket toSplit = hist.get(position);
|
||||||
|
double mark = (toSplit.leftBoundary + toSplit.rightBoundary) / 2.0D;
|
||||||
|
Bucket lower = new Bucket(this, toSplit.leftBoundary, mark, toSplit.countLeft / 2.0D, toSplit.countLeft / 2.0D);
|
||||||
|
Bucket upper = new Bucket(this, mark, toSplit.rightBoundary, toSplit.countRight / 2.0D, toSplit.countRight / 2.0D);
|
||||||
|
hist.set(position, upper);
|
||||||
|
hist.add(position, lower);
|
||||||
|
}
|
||||||
|
|
||||||
|
Pair<Integer, Double> findBestToMerge()
|
||||||
|
{
|
||||||
|
double minMergeError = Double.MAX_VALUE;
|
||||||
|
int bucket = 0;
|
||||||
|
for (int i = 0; i < hist.size() - 1; i++)
|
||||||
|
{
|
||||||
|
double mergeError = hist.get(i).mergeError(hist.get(i + 1));
|
||||||
|
if (mergeError < minMergeError)
|
||||||
|
{
|
||||||
|
minMergeError = mergeError;
|
||||||
|
bucket = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Pair<Integer, Double>(bucket, minMergeError);
|
||||||
|
}
|
||||||
|
|
||||||
|
Pair<Integer, Double> findBestToSplit()
|
||||||
|
{
|
||||||
|
double maxError = Double.MIN_VALUE;
|
||||||
|
int bucket = 0;
|
||||||
|
for (int i = 0; i < hist.size(); i++)
|
||||||
|
{
|
||||||
|
double error = hist.get(i).error();
|
||||||
|
if (error > maxError)
|
||||||
|
{
|
||||||
|
maxError = error;
|
||||||
|
bucket = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Pair<Integer, Double>(bucket, maxError);
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized long getN()
|
||||||
|
{
|
||||||
|
return (long) moments[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized double getMin()
|
||||||
|
{
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized double getMax()
|
||||||
|
{
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized double getMean()
|
||||||
|
{
|
||||||
|
return moments[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized double getVarience()
|
||||||
|
{
|
||||||
|
if (moments[0] > 1)
|
||||||
|
{
|
||||||
|
return moments[2] * moments[0] / (moments[0] - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Double.NaN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized double getStandardDeviation()
|
||||||
|
{
|
||||||
|
return Math.sqrt(getVarience());
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized double getSkew()
|
||||||
|
{
|
||||||
|
if (moments[0] > 2)
|
||||||
|
{
|
||||||
|
double v = getVarience();
|
||||||
|
return moments[3] * moments[0] * moments[0] / (Math.sqrt(v) * v * (moments[0] - 1) * (moments[0] - 2));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Double.NaN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized double getKurtosis()
|
||||||
|
{
|
||||||
|
if (moments[0] > 3)
|
||||||
|
{
|
||||||
|
double div = (moments[0] - 2) * (moments[0] - 3);
|
||||||
|
double nMinus1 = moments[0] - 1;
|
||||||
|
double v = getVarience();
|
||||||
|
double z = ((moments[4] * moments[0] * moments[0] * (moments[0] + 1)) / (v * v * nMinus1));
|
||||||
|
z -= 3 * nMinus1 * nMinus1;
|
||||||
|
z /= div;
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Double.NaN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized IncrementalStats copy()
|
||||||
|
{
|
||||||
|
IncrementalStats copy = new IncrementalStats(this.scale, this.buckets, this.server);
|
||||||
|
copy.start = this.start;
|
||||||
|
copy.max = this.max;
|
||||||
|
copy.min = this.min;
|
||||||
|
copy.moments[0] = this.moments[0];
|
||||||
|
copy.moments[1] = this.moments[1];
|
||||||
|
copy.moments[2] = this.moments[2];
|
||||||
|
copy.moments[3] = this.moments[3];
|
||||||
|
copy.moments[4] = this.moments[4];
|
||||||
|
for (Double x : this.values)
|
||||||
|
{
|
||||||
|
copy.values.add(x);
|
||||||
|
}
|
||||||
|
for (Bucket b : this.hist)
|
||||||
|
{
|
||||||
|
copy.hist.add(new Bucket(copy, b.leftBoundary, b.rightBoundary, b.countLeft, b.countRight));
|
||||||
|
}
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return "IncrementalStats [getN()="
|
||||||
|
+ getN() + ", getMin()=" + getMin() + ", getMax()=" + getMax() + ", getMean()=" + getMean() + ", getVarience()=" + getVarience() + ", getStandardDeviation()="
|
||||||
|
+ getStandardDeviation() + ", getSkew()=" + getSkew() + ", getKurtosis()=" + getKurtosis() + ", values=" + values + ", hist=" + hist + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param l
|
||||||
|
*/
|
||||||
|
public void addModelTime(long time)
|
||||||
|
{
|
||||||
|
IncrementalStats stats = modelTimes.get(Thread.currentThread().getName());
|
||||||
|
if (stats == null)
|
||||||
|
{
|
||||||
|
stats = new IncrementalStats(TIME_SCALE, 50, this.infoSrv);
|
||||||
|
modelTimes.put(Thread.currentThread().getName(), stats);
|
||||||
|
}
|
||||||
|
stats.add(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param l
|
||||||
|
*/
|
||||||
|
public void addAclTime(long time)
|
||||||
|
{
|
||||||
|
IncrementalStats stats = aclTimes.get(Thread.currentThread().getName());
|
||||||
|
if (stats == null)
|
||||||
|
{
|
||||||
|
stats = new IncrementalStats(TIME_SCALE, 50, this.infoSrv);
|
||||||
|
aclTimes.put(Thread.currentThread().getName(), stats);
|
||||||
|
}
|
||||||
|
stats.add(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param l
|
||||||
|
*/
|
||||||
|
public void addNodeTime(long time)
|
||||||
|
{
|
||||||
|
IncrementalStats stats = nodeTimes.get(Thread.currentThread().getName());
|
||||||
|
if (stats == null)
|
||||||
|
{
|
||||||
|
stats = new IncrementalStats(TIME_SCALE, 50, this.infoSrv);
|
||||||
|
nodeTimes.put(Thread.currentThread().getName(), stats);
|
||||||
|
}
|
||||||
|
stats.add(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param size
|
||||||
|
*/
|
||||||
|
public void addTxDocs(int size)
|
||||||
|
{
|
||||||
|
IncrementalStats stats = txDocs.get(Thread.currentThread().getName());
|
||||||
|
if (stats == null)
|
||||||
|
{
|
||||||
|
stats = new IncrementalStats(1, 50, this.infoSrv);
|
||||||
|
txDocs.put(Thread.currentThread().getName(), stats);
|
||||||
|
}
|
||||||
|
stats.add(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param size
|
||||||
|
*/
|
||||||
|
public void addChangeSetAcls(int size)
|
||||||
|
{
|
||||||
|
IncrementalStats stats = changeSetAcls.get(Thread.currentThread().getName());
|
||||||
|
if (stats == null)
|
||||||
|
{
|
||||||
|
stats = new IncrementalStats(1, 50, this.infoSrv);
|
||||||
|
changeSetAcls.put(Thread.currentThread().getName(), stats);
|
||||||
|
}
|
||||||
|
stats.add(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param l
|
||||||
|
*/
|
||||||
|
public void addDocTransformationTime(long time)
|
||||||
|
{
|
||||||
|
IncrementalStats stats = docTransformationTimes.get(Thread.currentThread().getName());
|
||||||
|
if (stats == null)
|
||||||
|
{
|
||||||
|
stats = new IncrementalStats(TIME_SCALE, 50, this.infoSrv);
|
||||||
|
docTransformationTimes.put(Thread.currentThread().getName(), stats);
|
||||||
|
}
|
||||||
|
stats.add(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return "TrackerStats [modelTimes="
|
||||||
|
+ modelTimes + ", aclTimes=" + aclTimes + ", changeSetAcls=" + changeSetAcls + ", txDocs=" + txDocs + ", docTransformationTimes=" + docTransformationTimes
|
||||||
|
+ ", nodeTimes=" + nodeTimes + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
modelTimes.clear();
|
||||||
|
aclTimes.clear();
|
||||||
|
changeSetAcls.clear();
|
||||||
|
txDocs.clear();
|
||||||
|
docTransformationTimes.clear();
|
||||||
|
nodeTimes.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user