changeset 1624:affa18455541

Thread Monitor fixes part II review-thread: http://icedtea.classpath.org/pipermail/thermostat/2014-December/012135.html reviewed-by: omajid
author Mario Torre <neugens.limasoftware@gmail.com>
date Thu, 11 Dec 2014 11:44:43 +0100
parents b1306c7c7422
children 2c54f59361f0
files thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/view/ThreadTableView.java thread/client-controllers/src/main/java/com/redhat/thermostat/thread/client/controller/impl/ThreadTableController.java thread/client-controllers/src/main/java/com/redhat/thermostat/thread/client/controller/impl/ThreadTimelineController.java thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadTableView.java thread/client-swing/src/test/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadViewTest.java thread/collector/src/main/java/com/redhat/thermostat/thread/model/ThreadState.java thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDAOCategoryRegistrationTest.java thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDAOImplStatementBeanAdapterRegistrationTest.java thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/HarvesterHelper.java thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/ThreadContentionHelper.java thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/ThreadStateHelper.java thread/harvester/src/test/java/com/redhat/thermostat/thread/harvester/HarvesterHelperTest.java
diffstat 12 files changed, 237 insertions(+), 248 deletions(-) [+]
line wrap: on
line diff
--- a/thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/view/ThreadTableView.java	Thu Dec 11 11:44:42 2014 +0100
+++ b/thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/view/ThreadTableView.java	Thu Dec 11 11:44:43 2014 +0100
@@ -36,8 +36,6 @@
 
 package com.redhat.thermostat.thread.client.common.view;
 
-import java.util.List;
-
 import com.redhat.thermostat.client.core.views.BasicView;
 import com.redhat.thermostat.common.ActionListener;
 import com.redhat.thermostat.common.ActionNotifier;
@@ -45,6 +43,8 @@
 
 public abstract class ThreadTableView extends BasicView {
 
+    public abstract void clear();
+
     public static enum ThreadSelectionAction {
         SHOW_THREAD_DETAILS
     }
@@ -61,7 +61,9 @@
     public void removeThreadSelectionActionListener(ActionListener<ThreadSelectionAction> listener) {
         threadTableNotifier.removeActionListener(listener);
     }
-    
-    public abstract void display(List<ThreadTableBean> arrayList);
+
+    public abstract void submitChanges();
+
+    public abstract void display(ThreadTableBean tableBean);
 }
 
--- a/thread/client-controllers/src/main/java/com/redhat/thermostat/thread/client/controller/impl/ThreadTableController.java	Thu Dec 11 11:44:42 2014 +0100
+++ b/thread/client-controllers/src/main/java/com/redhat/thermostat/thread/client/controller/impl/ThreadTableController.java	Thu Dec 11 11:44:43 2014 +0100
@@ -38,156 +38,154 @@
 
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.model.Range;
+import com.redhat.thermostat.storage.core.experimental.statement.ResultHandler;
 import com.redhat.thermostat.thread.client.common.ThreadTableBean;
 import com.redhat.thermostat.thread.client.common.collector.ThreadCollector;
+import com.redhat.thermostat.thread.client.common.model.timeline.ThreadInfo;
 import com.redhat.thermostat.thread.client.common.view.ThreadTableView;
+import com.redhat.thermostat.thread.model.SessionID;
+import com.redhat.thermostat.thread.model.ThreadState;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
 
 public class ThreadTableController extends CommonController {
     
     private ThreadTableView threadTableView;
     private ThreadCollector collector;
 
-    private Range<Long> lastRangeChecked;
-//    private Map<ThreadHeader, ThreadTableBean> threadStates;
-
     public ThreadTableController(ThreadTableView threadTableView,
                                  ThreadCollector collector,
                                  Timer timer)
     {
         super(timer, threadTableView);
+        this.threadTableView = threadTableView;
+        this.collector = collector;
         timer.setAction(new ThreadTableControllerAction());
-
-//        threadStates = new HashMap<>();
-        this.collector = collector;
-        this.threadTableView = threadTableView;
     }
 
-    
     private class ThreadTableControllerAction implements Runnable {
+
+        private ThreadResultHandler handler;
+        private Range<Long> range;
+        private SessionID lastSession;
+        private long lastUpdate;
+
+        public ThreadTableControllerAction() {
+            handler = new ThreadResultHandler();
+            resetState();
+        }
+
+        private void resetState() {
+            handler.threadStates.clear();
+            threadTableView.clear();
+            range = null;
+            lastUpdate = System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1);
+        }
+
         @Override
         public void run() {
 
-//            if (lastRangeChecked == null) {
-//                lastRangeChecked = collector.getThreadStateTotalTimeRange();
-//            } else {
-//                lastRangeChecked = new Range<>(lastRangeChecked.getMax(),
-//                                               System.currentTimeMillis());
-//            }
-//
-//            List<ThreadTableBean> tableBeans = new ArrayList<>();
-//
-//            List<ThreadHeader> threads = collector.getThreads();
-//
-//            for (ThreadHeader thread : threads) {
-//
-//                ThreadTableBean bean = threadStates.get(thread);
-//                if (bean == null) {
-//                    bean = new ThreadTableBean();
-//                    bean.setName(thread.getThreadName());
-//                    bean.setId(thread.getThreadId());
-//
-//                    threadStates.put(thread, bean);
-//                }
-//
-//                List<ThreadState> states = collector.getThreadStates(thread, lastRangeChecked);
-//                for (ThreadState state : states) {
-//
-//                    Thread.State threadState = Thread.State.valueOf(state.getState());
-//
-//                    Range<Long> range = state.getRange();
-//                    long currentRangeInCollection = range.getMax() - range.getMin();
-//                    long currentStateInBean = getCurrentStateInBean(bean, threadState);
-//
-//                    currentStateInBean += currentRangeInCollection;
-//                    setCurrentStateInBean(bean, threadState, currentStateInBean);
-//
-//                    double totalRunningTime = bean.getRunningTime()  +
-//                                              bean.getMonitorTime()  +
-//                                              bean.getSleepingTime() +
-//                                              bean.getWaitingTime();
-//
-//                    if (totalRunningTime > 0) {
-//                        double percent = (bean.getRunningTime() / totalRunningTime) * 100;
-//                        bean.setRunningPercent(percent);
-//
-//                        percent = (bean.getWaitingTime() / totalRunningTime) * 100;
-//                        bean.setWaitingPercent(percent);
-//
-//                        percent = (bean.getMonitorTime() / totalRunningTime) * 100;
-//                        bean.setMonitorPercent(percent);
-//
-//                        percent = (bean.getSleepingTime() / totalRunningTime) * 100;
-//                        bean.setSleepingPercent(percent);
-//                    }
-//                }
-//
-//                // check the latest stat regarding wait and block count
-//                ThreadContentionSample sample = collector.getLatestContentionSample(thread);
-//                if (sample != null) {
-//                    bean.setBlockedCount(sample.getBlockedCount());
-//                    bean.setWaitedCount(sample.getWaitedCount());
-//                }
-//
-//                // finally, the time range for this thread
-//                Range<Long> dataRange = collector.getThreadStateRange(thread);
-//                if (dataRange != null) {
-//                    bean.setStartTimeStamp(dataRange.getMin());
-//                    bean.setStopTimeStamp(dataRange.getMax());
-//                }
-//
-//                tableBeans.add(bean);
-//            }
-//
-//            threadTableView.display(tableBeans);
+            SessionID session = collector.getLastThreadSession();
+            if (session == null) {
+                // ok, no data, let's skip this round
+                return;
+            }
+            if (lastSession == null ||
+                    !session.get().equals(lastSession.get())) {
+                // since we only visualise one sessions at a time and this
+                // is a new session needs, let's clear the view
+                resetState();
+            }
+            lastSession = session;
+
+            // get the full range of known timelines per vm
+            Range<Long> totalRange = collector.getThreadRange(session);
+            if (totalRange == null) {
+                // this just means we don't have any data yet
+                return;
+            }
+
+            range = new Range<>(lastUpdate, totalRange.getMax());
+            lastUpdate = totalRange.getMax();
+
+            collector.getThreadStates(session,
+                                      handler,
+                                      range);
+            threadTableView.submitChanges();
         }
     }
 
-    long getCurrentStateInBean(ThreadTableBean bean, Thread.State threadState) {
-        long currentStateInBean = 0l;
+    private class ThreadResultHandler implements ResultHandler<ThreadState> {
+        private Map<ThreadInfo, ThreadTableBean> threadStates;
+
+        public ThreadResultHandler() {
+            this.threadStates = new HashMap<>();
+        }
+
+        @Override
+        public void onResult(ThreadState thread) {
+
+            ThreadInfo key = new ThreadInfo();
+            key.setName(thread.getName());
+            key.setId(thread.getId());
+
+            ThreadTableBean bean = threadStates.get(key);
+            if (bean == null) {
+                bean = new ThreadTableBean();
+                bean.setName(thread.getName());
+                bean.setId(thread.getId());
+                bean.setStartTimeStamp(thread.getTimeStamp());
+                threadStates.put(key, bean);
+            }
+
+            setCurrentStateTime(bean, thread);
+
+            double totalRunningTime = bean.getRunningTime()  +
+                                      bean.getMonitorTime()  +
+                                      bean.getSleepingTime() +
+                                      bean.getWaitingTime();
+            if (totalRunningTime > 0) {
+                double percent = (bean.getRunningTime() / totalRunningTime) * 100;
+                bean.setRunningPercent(percent);
+
+                percent = (bean.getWaitingTime() / totalRunningTime) * 100;
+                bean.setWaitingPercent(percent);
+
+                percent = (bean.getMonitorTime() / totalRunningTime) * 100;
+                bean.setMonitorPercent(percent);
+
+                percent = (bean.getSleepingTime() / totalRunningTime) * 100;
+                bean.setSleepingPercent(percent);
+            }
+
+            bean.setBlockedCount(thread.getBlockedCount());
+            bean.setWaitedCount(thread.getWaitedCount());
+
+            bean.setStopTimeStamp(thread.getTimeStamp());
+
+            threadTableView.display(bean);
+        }
+    }
+
+    void setCurrentStateTime(ThreadTableBean bean, ThreadState thread) {
+        Thread.State threadState = Thread.State.valueOf(thread.getState());
 
         switch (threadState) {
             case RUNNABLE:
-                currentStateInBean = bean.getRunningTime();
+                bean.setRunningTime(bean.getRunningTime() + 1);
                 break;
 
             case BLOCKED:
-                currentStateInBean = bean.getMonitorTime();
+                bean.setMonitorTime(bean.getMonitorTime() + 1);
                 break;
 
             case TIMED_WAITING:
-                currentStateInBean = bean.getSleepingTime();
+                bean.setSleepingTime(bean.getSleepingTime() + 1);
                 break;
 
             case WAITING:
-                currentStateInBean = bean.getWaitingTime();
-                break;
-
-            case NEW:
-            case TERMINATED:
-            default:
-                break;
-        }
-
-        return currentStateInBean;
-    }
-
-    void setCurrentStateInBean(ThreadTableBean bean, Thread.State threadState, long range) {
-
-        switch (threadState) {
-            case RUNNABLE:
-                bean.setRunningTime(range);
-                break;
-
-            case BLOCKED:
-                bean.setMonitorTime(range);
-                break;
-
-            case TIMED_WAITING:
-                bean.setSleepingTime(range);
-                break;
-
-            case WAITING:
-                bean.setWaitingTime(range);
+                bean.setWaitingTime(bean.getWaitingTime() + 1);
                 break;
 
             case NEW:
--- a/thread/client-controllers/src/main/java/com/redhat/thermostat/thread/client/controller/impl/ThreadTimelineController.java	Thu Dec 11 11:44:42 2014 +0100
+++ b/thread/client-controllers/src/main/java/com/redhat/thermostat/thread/client/controller/impl/ThreadTimelineController.java	Thu Dec 11 11:44:43 2014 +0100
@@ -133,7 +133,6 @@
                 collector.getThreadStates(session,
                                           threadStateResultHandler,
                                           range);
-                threadStateResultHandler.results = 0;
             }
         }
     }
@@ -142,8 +141,6 @@
         private ThreadInfo key;
         private Set<ThreadInfo> knownStates;
 
-        int results;
-
         public ThreadStateResultHandler() {
             this.key = new ThreadInfo();
             knownStates = new HashSet<>();
@@ -152,8 +149,6 @@
         @Override
         public void onResult(ThreadState state) {
 
-            results++;
-
             key.setName(state.getName());
             key.setId(state.getId());
 
--- a/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadTableView.java	Thu Dec 11 11:44:42 2014 +0100
+++ b/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadTableView.java	Thu Dec 11 11:44:43 2014 +0100
@@ -36,28 +36,28 @@
 
 package com.redhat.thermostat.thread.client.swing.impl;
 
+import com.redhat.thermostat.client.swing.SwingComponent;
+import com.redhat.thermostat.client.swing.components.ThermostatTable;
+import com.redhat.thermostat.client.swing.experimental.ComponentVisibilityNotifier;
+import com.redhat.thermostat.shared.locale.Translate;
+import com.redhat.thermostat.thread.client.common.ThreadTableBean;
+import com.redhat.thermostat.thread.client.common.locale.LocaleResources;
+import com.redhat.thermostat.thread.client.common.view.ThreadTableView;
 import java.awt.Component;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.text.DecimalFormat;
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
-
+import java.util.Map;
 import javax.swing.SwingUtilities;
 import javax.swing.SwingWorker;
 import javax.swing.event.TableModelEvent;
 import javax.swing.event.TableModelListener;
 import javax.swing.table.DefaultTableModel;
 
-import com.redhat.thermostat.client.swing.SwingComponent;
-import com.redhat.thermostat.client.swing.components.ThermostatTable;
-import com.redhat.thermostat.client.swing.experimental.ComponentVisibilityNotifier;
-import com.redhat.thermostat.shared.locale.Translate;
-import com.redhat.thermostat.thread.client.common.locale.LocaleResources;
-import com.redhat.thermostat.thread.client.common.view.ThreadTableView;
-import com.redhat.thermostat.thread.client.common.ThreadTableBean;
-
 public class SwingThreadTableView extends ThreadTableView implements SwingComponent {
 
     private boolean tableRepacked = false; 
@@ -66,14 +66,18 @@
     
     private ThermostatTable table;
     private ThreadTable tablePanel;
-    
+
+    private Map<ThreadTableBean, Integer> beans;
+
     private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
     
     public SwingThreadTableView() {
+
+        beans = new HashMap<>();
         tablePanel = new ThreadTable();
         new ComponentVisibilityNotifier().initialize(tablePanel, notifier);
         
-        table = new ThermostatTable(new ThreadViewTableModel(new ArrayList<ThreadTableBean>()));
+        table = new ThermostatTable(new ThreadViewTableModel());
         table.setName("threadBeansTable");
         table.getModel().addTableModelListener(new TableModelListener() {
             @Override
@@ -117,14 +121,26 @@
             }
         });
     }
-    
+
+    @Override
+    public void clear() {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                ThreadViewTableModel model = (ThreadViewTableModel) table.getModel();
+                model.setRowCount(0);
+                beans.clear();
+            }
+        });
+    }
+
     @Override
     public Component getUiComponent() {
         return tablePanel;
     }
     
     @Override
-    public void display(final List<ThreadTableBean> infos) {
+    public void display(final ThreadTableBean tableBean) {
         SwingUtilities.invokeLater(new Runnable() {
             @Override
             public void run() {
@@ -140,8 +156,14 @@
                 if (selectedRow != -1) {
                     info = model.infos.get(selectedRow);
                 }
-                
-                model.infos = infos;
+
+                // update the infos
+                Integer beanIndex = beans.get(tableBean);
+                if (beanIndex == null) {
+                    beanIndex = Integer.valueOf(model.infos.size());
+                    beans.put(tableBean, beanIndex);
+                    model.infos.add(tableBean);
+                }
 
                 if (info != null) {
                     int index = 0;
@@ -159,7 +181,17 @@
                     table.repackCells();
                     tableRepacked = true;
                 }
-                
+            }
+        });
+    }
+
+    @Override
+    public void submitChanges() {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                ThreadViewTableModel model =
+                        (ThreadViewTableModel) table.getModel();
                 model.fireTableDataChanged();
             }
         });
@@ -180,10 +212,10 @@
                 t.localize(LocaleResources.SLEEPING).getContents(),
                 t.localize(LocaleResources.MONITOR).getContents(), //, "Heap", "CPU Time", "User CPU Time"
         };
-        
+
         private List<ThreadTableBean> infos;
-        public ThreadViewTableModel(List<ThreadTableBean> infos) {
-            this.infos = infos;
+        public ThreadViewTableModel() {
+            this.infos = new ArrayList<>();
         }
     
         @Override
--- a/thread/client-swing/src/test/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadViewTest.java	Thu Dec 11 11:44:42 2014 +0100
+++ b/thread/client-swing/src/test/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadViewTest.java	Thu Dec 11 11:44:43 2014 +0100
@@ -148,7 +148,7 @@
 //    @GUITest
 //    @Test
 //    public void verifTableViewLinksToDetailsView() throws InvocationTargetException, InterruptedException {
-//        
+//
 //        final boolean listenerCalled[] = new boolean[1];
 //
 //        ThreadTableBean bean1 = mock(ThreadTableBean.class);
--- a/thread/collector/src/main/java/com/redhat/thermostat/thread/model/ThreadState.java	Thu Dec 11 11:44:42 2014 +0100
+++ b/thread/collector/src/main/java/com/redhat/thermostat/thread/model/ThreadState.java	Thu Dec 11 11:44:43 2014 +0100
@@ -59,6 +59,10 @@
     private long id;
     private boolean suspended;
     private boolean inNative;
+    private long blockedCount;
+    private long blockedTime;
+    private long waitedCount;
+    private long waitedTime;
 
     public ThreadState() {
         this(null);
@@ -192,4 +196,44 @@
         result = 31 * result + (inNative ? 1 : 0);
         return result;
     }
+
+    @Persist
+    public void setBlockedCount(long blockedCount) {
+        this.blockedCount = blockedCount;
+    }
+
+    @Persist
+    public long getBlockedCount() {
+        return blockedCount;
+    }
+
+    @Persist
+    public void setBlockedTime(long blockedTime) {
+        this.blockedTime = blockedTime;
+    }
+
+    @Persist
+    public long getBlockedTime() {
+        return blockedTime;
+    }
+
+    @Persist
+    public void setWaitedCount(long waitedCount) {
+        this.waitedCount = waitedCount;
+    }
+
+    @Persist
+    public long getWaitedCount() {
+        return waitedCount;
+    }
+
+    @Persist
+    public void setWaitedTime(long waitedTime) {
+        this.waitedTime = waitedTime;
+    }
+
+    @Persist
+    public long getWaitedTime() {
+        return waitedTime;
+    }
 }
--- a/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDAOCategoryRegistrationTest.java	Thu Dec 11 11:44:42 2014 +0100
+++ b/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDAOCategoryRegistrationTest.java	Thu Dec 11 11:44:43 2014 +0100
@@ -53,7 +53,7 @@
 
 public class ThreadDAOCategoryRegistrationTest {
 
-    private static final int EXPECTED_CATEGORIES = 7;
+    private static final int EXPECTED_CATEGORIES = 6;
 
     @Test
     public void registersAllCategories() {
--- a/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDAOImplStatementBeanAdapterRegistrationTest.java	Thu Dec 11 11:44:42 2014 +0100
+++ b/thread/collector/src/test/java/com/redhat/thermostat/thread/dao/impl/ThreadDAOImplStatementBeanAdapterRegistrationTest.java	Thu Dec 11 11:44:43 2014 +0100
@@ -36,21 +36,19 @@
 
 package com.redhat.thermostat.thread.dao.impl;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
+import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration;
+import com.redhat.thermostat.storage.internal.dao.DAOImplStatementDescriptorRegistration;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.ServiceLoader;
 import java.util.Set;
-
 import org.junit.Test;
 
-import com.redhat.thermostat.storage.core.auth.StatementDescriptorRegistration;
-import com.redhat.thermostat.storage.internal.dao.DAOImplStatementDescriptorRegistration;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 public class ThreadDAOImplStatementBeanAdapterRegistrationTest {
     
@@ -58,7 +56,7 @@
     public void registersAllDescriptors() {
         ThreadDaoImplStatementDescriptorRegistration reg = new ThreadDaoImplStatementDescriptorRegistration();
         Set<String> descriptors = reg.getStatementDescriptors();
-        assertEquals(20, descriptors.size());
+        assertEquals(14, descriptors.size());
         assertFalse("null statement not allowed", descriptors.contains(null));
     }
     
@@ -86,7 +84,7 @@
         // storage-core + this module
         assertEquals(2, registrations.size());
         assertNotNull(threadDaoReg);
-        assertEquals(20, threadDaoReg.getStatementDescriptors().size());
+        assertEquals(14, threadDaoReg.getStatementDescriptors().size());
     }
 
 }
--- a/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/HarvesterHelper.java	Thu Dec 11 11:44:42 2014 +0100
+++ b/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/HarvesterHelper.java	Thu Dec 11 11:44:43 2014 +0100
@@ -54,7 +54,6 @@
 
     private ThreadSummaryHelper summaryHelper;
     private ThreadStateHelper stateHelper;
-    private ThreadContentionHelper contentionHelper;
     private ThreadSessionHelper sessionHelper;
 
     HarvesterHelper(ThreadDao threadDao, Clock clock, String vmId, WriterID writerId)
@@ -62,14 +61,12 @@
         this(clock, vmId,
              new ThreadSummaryHelper(threadDao, writerId, vmId),
              new ThreadStateHelper(threadDao, writerId, vmId),
-             new ThreadContentionHelper(threadDao, writerId, vmId),
              new ThreadSessionHelper(threadDao, writerId, vmId, clock));
     }
 
     HarvesterHelper(Clock clock, String vmId,
                     ThreadSummaryHelper summaryHelper,
                     ThreadStateHelper stateHelper,
-                    ThreadContentionHelper contentionHelper,
                     ThreadSessionHelper sessionHelper)
     {
         this.vmId = vmId;
@@ -77,8 +74,6 @@
 
         this.summaryHelper = summaryHelper;
         this.stateHelper = stateHelper;
-
-        this.contentionHelper = contentionHelper;
         this.sessionHelper = sessionHelper;
     }
 
@@ -116,13 +111,6 @@
                                                   session.getSessionID(),
                                                   timestamp);
             stateHelper.saveThreadState(state);
-//
-//            // contention information
-//            ThreadContentionSample contentionSample =
-//                    contentionHelper.createThreadContentionSample(header,
-//                                                                  beanInfo,
-//                                                                  timestamp);
-//            contentionHelper.saveContentionSample(contentionSample);
         }
     }
 
--- a/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/ThreadContentionHelper.java	Thu Dec 11 11:44:42 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * Copyright 2012-2014 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat 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
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.thread.harvester;
-
-import com.redhat.thermostat.storage.core.WriterID;
-import com.redhat.thermostat.thread.dao.ThreadDao;
-
-/**
- */
-public class ThreadContentionHelper {
-
-    private final ThreadDao threadDao;
-    private final WriterID writerId;
-    private final String vmId;
-
-    ThreadContentionHelper(ThreadDao threadDao, WriterID writerId, String vmId) {
-        this.threadDao = threadDao;
-        this.writerId = writerId;
-        this.vmId = vmId;
-    }
-
-//    public ThreadContentionSample createThreadContentionSample(ThreadHeader header,
-//                                                               ThreadInfo beanInfo,
-//                                                               long timestamp)
-//    {
-//        String wId = writerId.getWriterID();
-//
-//        ThreadContentionSample sample = new ThreadContentionSample(wId);
-//        sample.setTimeStamp(timestamp);
-//        sample.setBlockedCount(beanInfo.getBlockedCount());
-//        sample.setBlockedTime(beanInfo.getBlockedTime());
-//        sample.setWaitedCount(beanInfo.getWaitedCount());
-//        sample.setWaitedTime(beanInfo.getWaitedTime());
-//
-//        return sample;
-//    }
-//
-//    public void saveContentionSample(ThreadContentionSample contentionSample) {
-//        threadDao.saveContentionSample(contentionSample);
-//    }
-}
--- a/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/ThreadStateHelper.java	Thu Dec 11 11:44:42 2014 +0100
+++ b/thread/harvester/src/main/java/com/redhat/thermostat/thread/harvester/ThreadStateHelper.java	Thu Dec 11 11:44:43 2014 +0100
@@ -62,15 +62,28 @@
     {
         ThreadState state = new ThreadState(writerId.getWriterID());
 
-        state.setState(beanInfo.getThreadState().name());
+        // generic information
         state.setTimeStamp(timestamp);
         state.setSession(sessionID.get());
         state.setVmId(vmId);
+
+        // ids
         state.setName(beanInfo.getThreadName());
         state.setId(beanInfo.getThreadId());
+
+        // execution information
+        state.setState(beanInfo.getThreadState().name());
         state.setSuspended(beanInfo.isSuspended());
         state.setInNative(beanInfo.isInNative());
 
+        // synchronization statistics
+        state.setBlockedCount(beanInfo.getBlockedCount());
+        state.setBlockedTime(beanInfo.getBlockedTime());
+        state.setWaitedCount(beanInfo.getWaitedCount());
+        state.setWaitedTime(beanInfo.getWaitedTime());
+
+        // TODO: lock information
+
         return state;
     }
 
--- a/thread/harvester/src/test/java/com/redhat/thermostat/thread/harvester/HarvesterHelperTest.java	Thu Dec 11 11:44:42 2014 +0100
+++ b/thread/harvester/src/test/java/com/redhat/thermostat/thread/harvester/HarvesterHelperTest.java	Thu Dec 11 11:44:43 2014 +0100
@@ -65,7 +65,6 @@
 
     private ThreadSummaryHelper summaryHelper;
     private ThreadStateHelper stateHelper;
-    private ThreadContentionHelper contentionHelper;
     private ThreadSessionHelper threadSessionHelper;
 
     private ThreadMXBean collectorBean;
@@ -75,8 +74,6 @@
         summaryHelper = mock(ThreadSummaryHelper.class);
         stateHelper = mock(ThreadStateHelper.class);
 
-        contentionHelper = mock(ThreadContentionHelper.class);
-
         threadDao = mock(ThreadDao.class);
         collectorBean = mock(ThreadMXBean.class);
 
@@ -103,7 +100,6 @@
         HarvesterHelper harvester = new HarvesterHelper(clock, vmId,
                                                         summaryHelper,
                                                         stateHelper,
-                                                        contentionHelper,
                                                         threadSessionHelper);
         harvester.collectAndSaveThreadData(session, collectorBean);
 
@@ -123,7 +119,6 @@
         HarvesterHelper harvester = new HarvesterHelper(clock, vmId,
                                                         summaryHelper,
                                                         stateHelper,
-                                                        contentionHelper,
                                                         threadSessionHelper);
         harvester.collectAndSaveThreadData(session, collectorBean);
         verify(collectorBean).getAllThreadIds();
@@ -156,7 +151,6 @@
         HarvesterHelper harvester = new HarvesterHelper(clock, vmId,
                                                         summaryHelper,
                                                         stateHelper,
-                                                        contentionHelper,
                                                         threadSessionHelper);
         harvester.collectAndSaveThreadData(session, collectorBean);