Project

General

Profile

« Previous | Next » 

Revision 6f59693f

Added by Andreas Müller over 7 years ago

rel #6086 Improve rounding for progress monitor

  • fix error in rounding by using round not ceil
  • add method for user defined scaled rounding

View differences:

cdmlib-commons/src/main/java/eu/etaxonomy/cdm/common/monitor/DefaultProgressMonitor.java
10 10
package eu.etaxonomy.cdm.common.monitor;
11 11

  
12 12
import java.io.Serializable;
13
import java.math.BigDecimal;
13 14

  
14 15
import org.apache.log4j.Level;
15 16
import org.apache.log4j.Logger;
......
50 51

  
51 52
    }
52 53

  
53

  
54
    /* (non-Javadoc)
55
     * @see eu.etaxonomy.cdm.common.IProgressMonitor#beginTask(java.lang.String, int)
56
     */
57 54
    @Override
58 55
    public void beginTask(String taskName, int totalWork) {
59 56
        logger.info("Start " + taskName);
......
61 58
        this.totalWork = totalWork;
62 59
    }
63 60

  
64
    /* (non-Javadoc)
65
     * @see eu.etaxonomy.cdm.common.IProgressMonitor#done()
66
     */
67 61
    @Override
68 62
    public void done() {
69 63
        logger.info(taskName + "...Done");
70 64
    }
71 65

  
72
    /* (non-Javadoc)
73
     * @see eu.etaxonomy.cdm.common.IProgressMonitor#isCanceled()
74
     */
75 66
    @Override
76 67
    public boolean isCanceled() {
77 68
        return isCanceled;
78 69
    }
79 70

  
80
    /* (non-Javadoc)
81
     * @see eu.etaxonomy.cdm.common.IProgressMonitor#setCanceled(boolean)
82
     */
83 71
    @Override
84 72
    public void setCanceled(boolean isCanceled) {
85 73
        this.isCanceled = isCanceled;
86 74
    }
87 75

  
88
    /* (non-Javadoc)
89
     * @see eu.etaxonomy.cdm.common.IProgressMonitor#setTaskName(java.lang.String)
90
     */
91 76
    @Override
92 77
    public void setTaskName(String taskName) {
93 78
        this.taskName = taskName;
94 79
    }
95 80

  
96
    /* (non-Javadoc)
97
     * @see eu.etaxonomy.cdm.common.IProgressMonitor#subTask(java.lang.String)
98
     */
99 81
    @Override
100 82
    public void subTask(String subTask) {
101 83
        this.subTask = subTask;
102 84
        logger.info(/*getPercentage() + "% done." + */  " Next Task: " + subTask);
103 85
    }
104 86

  
105
    /* (non-Javadoc)
106
     * @see eu.etaxonomy.cdm.common.IProgressMonitor#worked(int)
107
     */
108 87
    @Override
109 88
    public void worked(int work) {
110 89
        computeWorked(work);
......
120 99

  
121 100
    private void computeWorked(double work){
122 101
        this.workDone = this.workDone +  work;
123
        logger.info(getPercentage() + "% done (Completed Task: " + subTask + ")");
102
        if (logger.isInfoEnabled()){ logger.info(getPercentage() + "% done (Completed Task: " + subTask + ")");}
124 103
    }
125 104

  
126
    /* (non-Javadoc)
127
     * @see eu.etaxonomy.cdm.common.IProgressMonitor#warning(java.lang.String)
128
     */
129 105
    @Override
130 106
    public void warning(String warning) {
131 107
        logger.warn(warning);
132 108
    }
133 109

  
134
    /* (non-Javadoc)
135
     * @see eu.etaxonomy.cdm.common.IProgressMonitor#warning(java.lang.String, java.lang.Exception)
136
     */
137 110
    @Override
138 111
    public void warning(String warning, Throwable exception) {
139 112
        logger.warn(warning);
140 113
        exception.printStackTrace();
141 114
    }
142 115

  
116
    /**
117
     * Percentage of work done. With all work done = 100.0d.
118
     * As rounding errors may occur especially when using
119
     * {@link SubProgressMonitor} the result is rounded to 5 digits.
120
     * So do not use the result for additive percentages.
121
     */
143 122
    public Double getPercentage(){
144 123
        if(totalWork == 0 ){
145 124
            return null;
146 125
        }
147 126

  
148 127
        double result = this.workDone * 100 / this.totalWork ;
149
        result = Math.ceil((result * 100.0)) / 100.0;
128
        //as double may have rounding errors especially when using subprogressmonitors
129
        //we do round the result slightly
130
        result = Math.round((result * 100000.0)) / 100000.0;
131
        return result;
132
    }
133

  
134
    public BigDecimal getPercentageRounded(int scale){
135
        if(totalWork == 0 ){
136
            return null;
137
        }
138
        double percentage = this.workDone * 100 / this.totalWork ;
139
        BigDecimal result = new BigDecimal(percentage).setScale( scale, BigDecimal.ROUND_HALF_UP );
150 140
        return result;
151 141
    }
152 142

  
cdmlib-commons/src/test/java/eu/etaxonomy/cdm/common/monitor/DefaultProgressMonitorTest.java
1
// $Id$
2
/**
3
* Copyright (C) 2016 EDIT
4
* European Distributed Institute of Taxonomy
5
* http://www.e-taxonomy.eu
6
*
7
* The contents of this file are subject to the Mozilla Public License Version 1.1
8
* See LICENSE.TXT at the top of this package for the full license terms.
9
*/
10
package eu.etaxonomy.cdm.common.monitor;
11

  
12
import org.junit.Test;
13

  
14
/**
15
 * @author a.mueller
16
 * @date 15.09.2016
17
 *
18
 */
19
public class DefaultProgressMonitorTest {
20

  
21
    int steps = 739893;
22

  
23
    @Test
24
    public void testRoundingWithoutSubProgressMonitor() {
25
        DefaultProgressMonitor monitor = new DefaultProgressMonitor();
26
        int subTaskTicks = 3273;
27

  
28
        int subTasks = 130;
29
        monitor.beginTask("Hallo", steps);
30
        for (int i = 0; i<steps; i++){
31
            monitor.worked(1);
32
//            System.out.println(monitor.getPercentage());
33
        }
34

  
35
        monitor.done();
36
        System.out.println(monitor.getPercentage());
37
        System.out.println(monitor.getPercentageRounded(3));
38
    }
39

  
40
    @Test
41
    public void testRoundingWithSubProgressMonitor() {
42
        DefaultProgressMonitor monitor = new DefaultProgressMonitor();
43
        int subTaskTicks = 3273;
44

  
45
        int subTasks = 130;
46
        monitor.beginTask("Hallo", steps);
47
        for (int i = 0; i<steps-(subTaskTicks*subTasks); i++){
48
            monitor.worked(1);
49
//            System.out.println(monitor.getPercentage());
50
        }
51

  
52
        for (int i = 0; i < subTasks; i++){
53
            SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, subTaskTicks);
54
            int subTicks = 2457;
55
            subMonitor.beginTask("SubMonitor", subTicks);
56
            monitor.beginTask("Hallo", steps);
57
            for (int j = 0; j < subTicks; j++){
58
                subMonitor.worked(1);
59
//            System.out.println(monitor.getPercentage());
60
            }
61
        }
62

  
63
        monitor.done();
64
        System.out.println(monitor.getPercentage());
65
        System.out.println(monitor.getPercentageRounded(3));
66
    }
67

  
68

  
69

  
70
}

Also available in: Unified diff