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:
Mark Rogers
2014-07-23 10:50:14 +00:00
parent 9a053bf9b9
commit 45aff692fb
11 changed files with 2096 additions and 0 deletions

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,11 @@
package org.alfresco.solr;
public class IndexTrackingShutdownException extends RuntimeException
{
/**
*
*/
private static final long serialVersionUID = -1294455847013444397L;
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}

View File

@@ -0,0 +1,9 @@
package org.alfresco.solr.adapters;
public interface ISimpleOrderedMap<T>
{
void add(String name, T val);
}

View File

@@ -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;
}
}

View File

@@ -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();
}

View File

@@ -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();
}
}