resolve diffs with committs for status; some Gold changes in test.

This commit is contained in:
Marty Kraimer
2010-12-20 06:53:49 -05:00
17 changed files with 568 additions and 380 deletions
+7
View File
@@ -25,6 +25,8 @@ INC += timer.h
INC += queueVoid.h
INC += queue.h
INC += messageQueue.h
INC += destroyable.h
INC += status.h
LIBSRCS += byteBuffer.cpp
LIBSRCS += bitSet.cpp
@@ -81,6 +83,7 @@ LIBSRCS += PVDataCreateFactory.cpp
LIBSRCS += Convert.cpp
LIBSRCS += StandardField.cpp
LIBSRCS += StandardPVField.cpp
LIBSRCS += StatusCreateFactory.cpp
SRC_DIRS += $(PVDATA)/property
@@ -106,6 +109,10 @@ SRC_DIRS += $(PVDATA)/pvMisc
INC += bitSetUtil.h
LIBSRCS += bitSetUtil.cpp
SRC_DIRS += $(PVDATA)/monitor
INC += monitor.h
LIBRARY=pvData
pvData_LIBS += Com
+198
View File
@@ -0,0 +1,198 @@
/*StatusCreateFactory.cpp*/
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <cstddef>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <lock.h>
#include "factory.h"
#include "byteBuffer.h"
#include "showConstructDestruct.h"
#include "status.h"
#include "serializeHelper.h"
namespace epics { namespace pvData {
//static DebugLevel debugLevel = lowDebug;
static volatile int64 totalConstruct = 0;
static volatile int64 totalDestruct = 0;
static Mutex *globalMutex = 0;
static int64 getTotalConstruct()
{
Lock xx(globalMutex);
return totalConstruct;
}
static int64 getTotalDestruct()
{
Lock xx(globalMutex);
return totalDestruct;
}
static ConstructDestructCallback *pConstructDestructCallback;
static void init()
{
static Mutex mutex = Mutex();
Lock xx(&mutex);
if(globalMutex==0) {
globalMutex = new Mutex();
pConstructDestructCallback = new ConstructDestructCallback(
String("status"),
getTotalConstruct,getTotalDestruct,0);
}
}
class StatusImpl : public Status
{
public:
StatusImpl(StatusType type, String message, String stackDump) :
m_type(type), m_message(message), m_stackDump(stackDump)
{
Lock xx(globalMutex);
totalConstruct++;
}
~StatusImpl() {
Lock xx(globalMutex);
totalDestruct++;
}
virtual StatusType getType()
{
return m_type;
}
virtual epics::pvData::String getMessage()
{
return m_message;
}
virtual epics::pvData::String getStackDump()
{
return m_stackDump;
}
virtual bool isOK()
{
return (m_type == STATUSTYPE_OK);
}
virtual bool isSuccess()
{
return (m_type == STATUSTYPE_OK || m_type == STATUSTYPE_WARNING);
}
virtual void serialize(ByteBuffer *buffer, SerializableControl *flusher)
{
flusher->ensureBuffer(1);
if (this == getStatusCreate()->getStatusOK())
{
// special code for okStatus (optimization)
buffer->putByte((int8)-1);
}
else
{
buffer->putByte((int8)m_type);
SerializeHelper::serializeString(m_message, buffer, flusher);
SerializeHelper::serializeString(m_stackDump, buffer, flusher);
}
}
virtual void deserialize(ByteBuffer *pbuffer, DeserializableControl *pflusher)
{
throw new std::runtime_error("use getStatusCreate()->deserialize()");
}
virtual void toString(StringBuilder buffer, int indentLevel)
{
*buffer += "StatusImpl [type=";
*buffer += StatusTypeName[m_type];
if (!m_message.empty())
{
*buffer += ", message=";
*buffer += m_message;
}
if (!m_stackDump.empty())
{
*buffer += ", stackDump=";
*buffer += '\n';
*buffer += m_stackDump;
}
*buffer += ']';
}
private:
StatusType m_type;
String m_message;
String m_stackDump;
};
class StatusCreateImpl : public StatusCreate {
public:
StatusCreateImpl()
{
init();
m_ok = createStatus(STATUSTYPE_OK, "OK", 0);
}
virtual Status* getStatusOK() {
return m_ok;
}
virtual Status* createStatus(StatusType type, String message, BaseException* cause) {
if (cause == 0)
return new StatusImpl(type, message, "");
else
{
std::string stackDump;
cause->toString(stackDump);
return new StatusImpl(type, message, stackDump);
}
}
virtual Status* deserializeStatus(ByteBuffer* buffer, DeserializableControl* control) {
control->ensureData(1);
int8 typeCode = buffer->getByte();
if (typeCode == (int8)-1)
return m_ok;
else {
String message = SerializeHelper::deserializeString(buffer, control);
String stackDump = SerializeHelper::deserializeString(buffer, control);
return new StatusImpl((StatusType)typeCode, message, stackDump);
}
}
private:
Status* m_ok;
};
static StatusCreate* statusCreate = 0;
StatusCreate* getStatusCreate() {
static Mutex mutex = Mutex();
Lock xx(&mutex);
if(statusCreate==0) statusCreate = new StatusCreateImpl();
return statusCreate;
}
}}
+31
View File
@@ -0,0 +1,31 @@
/* destroyable.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef DESTROYABLE_H
#define DESTROYABLE_H
namespace epics { namespace pvData {
/**
* Instance declaring destroy method.
* @author mse
*/
class Destroyable {
public:
/**
* Destroy this instance.
*/
virtual void destroy() = 0;
private:
/**
* Do not allow delete on this instance.
*/
//~Destroyable() {};
};
}}
#endif /* DESTROYABLE_H */
+114
View File
@@ -0,0 +1,114 @@
/* status.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef STATUS_H
#define STATUS_H
#include "serialize.h"
#include "epicsException.h"
#include "byteBuffer.h"
namespace epics { namespace pvData {
/**
* Status type enum.
*/
enum StatusType {
/** Operation completed successfully. */
STATUSTYPE_OK,
/** Operation completed successfully, but there is a warning message. */
STATUSTYPE_WARNING,
/** Operation failed due to an error. */
STATUSTYPE_ERROR,
/** Operation failed due to an unexpected error. */
STATUSTYPE_FATAL
};
const char* StatusTypeName[] = { "OK", "WARNING", "ERROR", "FATAL" };
/**
* Status interface.
* @author mse
*/
class Status : public epics::pvData::Serializable {
public:
/**
* Get status type.
* @return status type, non-<code>null</code>.
*/
virtual StatusType getType() = 0;
/**
* Get error message describing an error. Required if error status.
* @return error message.
*/
virtual epics::pvData::String getMessage() = 0;
/**
* Get stack dump where error (exception) happened. Optional.
* @return stack dump.
*/
virtual epics::pvData::String getStackDump() = 0;
/**
* Convenient OK test. Same as <code>(getType() == StatusType.OK)</code>.
* NOTE: this will return <code>false</code> on WARNING message although operation succeeded.
* To check if operation succeeded, use <code>isSuccess</code>.
* @return OK status.
* @see #isSuccess()
*/
virtual bool isOK() = 0;
/**
* Check if operation succeeded.
* @return operation success status.
*/
virtual bool isSuccess() = 0;
virtual void toString(StringBuilder buffer, int indentLevel = 0) = 0;
};
/**
* Interface for creating status.
* @author mse
*/
class StatusCreate : private epics::pvData::NoDefaultMethods {
public:
/**
* Get OK status. Static instance should be returned.
* @return OK <code>Status</code> instance.
*/
virtual Status* getStatusOK() = 0;
/**
* Create status.
* @param type status type, non-<code>null</code>.
* @param message message describing an error, non-<code>null</code>.
* NOTE: Do NOT use <code>throwable.getMessage()</code> as message, since it will be supplied with the <code>cause</code>.
* @param cause exception that caused an error. Optional.
* @return status instance.
*/
virtual Status* createStatus(StatusType type, String message, BaseException* cause) = 0;
/**
* Deserialize status.
* NOTE: use this method instead of <code>Status.deserialize()</code>, since this allows OK status optimization.
* @param buffer deserialization buffer.
* @param control deserialization control.
* @return status instance.
*/
virtual Status* deserializeStatus(ByteBuffer* buffer, DeserializableControl* control) = 0;
};
extern StatusCreate* getStatusCreate();
}}
#endif /* STATUS_H */
+94
View File
@@ -0,0 +1,94 @@
/* monitor.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef MONITOR_H
#define MONITOR_H
#include <status.h>
#include <destroyable.h>
namespace epics { namespace pvData {
/**
* Class instance representing monitor element.
* @author mrk
*/
class MonitorElement {
public:
/**
* Get the PVStructure.
* @return The PVStructure.
*/
virtual PVStructure* getPVStructure() = 0;
/**
* Get the bitSet showing which fields have changed.
* @return The bitSet.
*/
virtual BitSet* getChangedBitSet() = 0;
/**
* Get the bitSet showing which fields have been changed more than once.
* @return The bitSet.
*/
virtual BitSet* getOverrunBitSet() = 0;
};
/**
* Interface for Monitor.
* @author mrk
*/
class Monitor : public Destroyable, private NoDefaultMethods {
public:
/**
* Start monitoring.
* @return completion status.
*/
virtual Status* start() = 0;
/**
* Stop Monitoring.
* @return completion status.
*/
virtual Status* stop() = 0;
/**
* If monitor has occurred return data.
* @return monitorElement for modified data on null if no monitors have occurred.
*/
virtual MonitorElement* poll() = 0;
/**
* Release a MonitorElement that was returned by poll.
* @param monitorElement
*/
virtual void release(MonitorElement* monitorElement) = 0;
};
/**
* Requester for ChannelMonitor.
* @author mrk
*/
class MonitorRequester : public Requester {
public:
/**
* The client and server have both completed the createMonitor request.
* @param status Completion status.
* @param monitor The monitor
* @param structure The structure defining the data.
*/
virtual void monitorConnect(Status* status, Monitor* monitor, Structure* structure) = 0;
/**
* A monitor event has occurred. The requester must call Monitor.poll to get data.
* @param monitor The monitor.
*/
virtual void monitorEvent(Monitor* monitor) = 0;
/**
* The data source is no longer available.
* @param monitor The monitor.
*/
virtual void unlisten(Monitor* monitor) = 0;
};
}}
#endif /* MONITOR_H */
-22
View File
@@ -1,22 +0,0 @@
13,20c13,20
< boolean[] boolean
< byte[] byte
< short[] short
< int[] int
< long[] long
< float[] float
< double[] double
< string[] string
---
> booleanArray boolean
> byteArray byte
> shortArray short
> intArray int
> longArray long
> floatArray float
> doubleArray double
> stringArray string
57c57
< structure[] value
---
> structureArray value
+9 -9
View File
@@ -10,14 +10,14 @@ double double
string string
testScalarArray
booleanArray boolean
byteArray byte
shortArray short
intArray int
longArray long
floatArray float
doubleArray double
stringArray string
boolean[] boolean
byte[] byte
short[] short
int[] int
long[] long
float[] float
double[] double
string[] string
testSimpleStructure
structure value
@@ -54,7 +54,7 @@ structure value
testStructureArray
structure value
structureArray value
structure[] value
structure powerSupply
structure voltage
double value
+12 -12
View File
@@ -1,20 +1,20 @@
Time test
diff 27.283014 milliSeconds
time per iteration 27.283014 microseconds
time per addTail/removeHead 0.013642 microseconds
diff 30.476650 milliSeconds
time per iteration 30.476650 microseconds
time per addTail/removeHead 0.015238 microseconds
Time test locked
diff 174.127278 milliSeconds
time per iteration 174.127278 microseconds
time per addTail/removeHead 0.087064 microseconds
diff 182.684171 milliSeconds
time per iteration 182.684171 microseconds
time per addTail/removeHead 0.091342 microseconds
Time std::list test
diff 651.121969 milliSeconds
time per iteration 651.121969 microseconds
time per addTail/removeHead 0.325561 microseconds
diff 649.338813 milliSeconds
time per iteration 649.338813 microseconds
time per addTail/removeHead 0.324669 microseconds
Time std::list test locked
diff 800.277269 milliSeconds
time per iteration 800.277269 microseconds
time per addTail/removeHead 0.400139 microseconds
diff 803.852839 milliSeconds
time per iteration 803.852839 microseconds
time per addTail/removeHead 0.401926 microseconds
-18
View File
@@ -1,18 +0,0 @@
5c5
< alarm alarm
---
> structure alarm
8c8
< timeStamp timeStamp
---
> structure timeStamp
11c11
< display display
---
> structure display
19,20c19,20
< string factory factoryName
< double junk 3
---
> key(factory) string factory factoryName
> key(junk) double junk 3
+5 -5
View File
@@ -2,13 +2,13 @@
testPVAuxInfo
structure value
double value 0
structure alarm
alarm alarm
int severity 0
string message
structure timeStamp
timeStamp timeStamp
long secondsPastEpoch 0
int nanoSeconds 0
structure display
display display
string description
string format
string units
@@ -16,8 +16,8 @@ structure value
double low 0
double high 0
auxInfo
key(factory) string factory factoryName
key(junk) double junk 3
string factory factoryName
double junk 3
value offset 0 next 15 number 15
value offset 1 next 2 number 1
alarm offset 2 next 5 number 3
-192
View File
@@ -1,192 +0,0 @@
13c13
< alarm alarm
---
> structure alarm
16c16
< timeStamp timeStamp
---
> structure timeStamp
26c26
< alarm alarm
---
> structure alarm
29c29
< timeStamp timeStamp
---
> structure timeStamp
32c32
< display display
---
> structure display
39c39
< control control
---
> structure control
57c57
< alarm alarm
---
> structure alarm
60c60
< timeStamp timeStamp
---
> structure timeStamp
63c63
< display display
---
> structure display
70c70
< control control
---
> structure control
88c88
< alarm alarm
---
> structure alarm
91c91
< timeStamp timeStamp
---
> structure timeStamp
94c94
< display display
---
> structure display
101c101
< control control
---
> structure control
119c119
< alarm alarm
---
> structure alarm
122c122
< timeStamp timeStamp
---
> structure timeStamp
125c125
< display display
---
> structure display
132c132
< control control
---
> structure control
150c150
< alarm alarm
---
> structure alarm
153c153
< timeStamp timeStamp
---
> structure timeStamp
156c156
< display display
---
> structure display
163c163
< control control
---
> structure control
181c181
< alarm alarm
---
> structure alarm
184c184
< timeStamp timeStamp
---
> structure timeStamp
187c187
< display display
---
> structure display
194c194
< control control
---
> structure control
212c212
< alarm alarm
---
> structure alarm
215c215
< timeStamp timeStamp
---
> structure timeStamp
221,222c221,222
< boolean[] value [true,false,true]
< alarm alarm
---
> booleanArray value [true,false,true]
> structure alarm
225c225
< timeStamp timeStamp
---
> structure timeStamp
229,230c229,230
< byte[] value [0,1,2]
< alarm alarm
---
> byteArray value [0,1,2]
> structure alarm
233c233
< timeStamp timeStamp
---
> structure timeStamp
237,238c237,238
< short[] value [0,1,2]
< alarm alarm
---
> shortArray value [0,1,2]
> structure alarm
241c241
< timeStamp timeStamp
---
> structure timeStamp
245,246c245,246
< int[] value [0,1,2]
< alarm alarm
---
> intArray value [0,1,2]
> structure alarm
249c249
< timeStamp timeStamp
---
> structure timeStamp
253,254c253,254
< long[] value [0,1,2]
< alarm alarm
---
> longArray value [0,1,2]
> structure alarm
257c257
< timeStamp timeStamp
---
> structure timeStamp
261,262c261,262
< float[] value [0,1,2]
< alarm alarm
---
> floatArray value [0,1,2]
> structure alarm
265c265
< timeStamp timeStamp
---
> structure timeStamp
269,270c269,270
< double[] value [0,1,2]
< alarm alarm
---
> doubleArray value [0,1,2]
> structure alarm
273c273
< timeStamp timeStamp
---
> structure timeStamp
277,278c277,278
< string[] value [0,1,2]
< alarm alarm
---
> stringArray value [0,1,2]
> structure alarm
281c281
< timeStamp timeStamp
---
> structure timeStamp
+52 -52
View File
@@ -10,10 +10,10 @@ double double 10
string string 10
structure boolean
boolean value true
structure alarm
alarm alarm
int severity 2
string message messageForAlarm
structure timeStamp
timeStamp timeStamp
long secondsPastEpoch 123456789
int nanoSeconds 1000000
structure valueAlarm
@@ -23,20 +23,20 @@ structure boolean
int changeStateSeverity 0
structure byte
byte value 127
structure alarm
alarm alarm
int severity 2
string message messageForAlarm
structure timeStamp
timeStamp timeStamp
long secondsPastEpoch 123456789
int nanoSeconds 1000000
structure display
display display
string description this is a description
string format f10.2
string units SomeUnits
structure limit
double low 0
double high 10
structure control
control control
structure limit
double low 1
double high 9
@@ -54,20 +54,20 @@ structure byte
byte hystersis 0
structure short
short value 32767
structure alarm
alarm alarm
int severity 2
string message messageForAlarm
structure timeStamp
timeStamp timeStamp
long secondsPastEpoch 123456789
int nanoSeconds 1000000
structure display
display display
string description this is a description
string format f10.2
string units SomeUnits
structure limit
double low 0
double high 10
structure control
control control
structure limit
double low 1
double high 9
@@ -85,20 +85,20 @@ structure short
short hystersis 0
structure int
int value -2147483648
structure alarm
alarm alarm
int severity 2
string message messageForAlarm
structure timeStamp
timeStamp timeStamp
long secondsPastEpoch 123456789
int nanoSeconds 1000000
structure display
display display
string description this is a description
string format f10.2
string units SomeUnits
structure limit
double low 0
double high 10
structure control
control control
structure limit
double low 1
double high 9
@@ -116,20 +116,20 @@ structure int
int hystersis 0
structure long
long value -9223372032559808513
structure alarm
alarm alarm
int severity 2
string message messageForAlarm
structure timeStamp
timeStamp timeStamp
long secondsPastEpoch 123456789
int nanoSeconds 1000000
structure display
display display
string description this is a description
string format f10.2
string units SomeUnits
structure limit
double low 0
double high 10
structure control
control control
structure limit
double low 1
double high 9
@@ -147,20 +147,20 @@ structure long
long hystersis 0
structure float
float value 1.123e+08
structure alarm
alarm alarm
int severity 2
string message messageForAlarm
structure timeStamp
timeStamp timeStamp
long secondsPastEpoch 123456789
int nanoSeconds 1000000
structure display
display display
string description this is a description
string format f10.2
string units SomeUnits
structure limit
double low 0
double high 10
structure control
control control
structure limit
double low 1
double high 9
@@ -178,20 +178,20 @@ structure float
float hystersis 0
structure double
double value 1.123e+35
structure alarm
alarm alarm
int severity 2
string message messageForAlarm
structure timeStamp
timeStamp timeStamp
long secondsPastEpoch 123456789
int nanoSeconds 1000000
structure display
display display
string description this is a description
string format f10.2
string units SomeUnits
structure limit
double low 0
double high 10
structure control
control control
structure limit
double low 1
double high 9
@@ -209,76 +209,76 @@ structure double
double hystersis 0
structure string
string value this is a string
structure alarm
alarm alarm
int severity 2
string message messageForAlarm
structure timeStamp
timeStamp timeStamp
long secondsPastEpoch 123456789
int nanoSeconds 1000000
testScalarArray
structure boolean
booleanArray value [true,false,true]
structure alarm
boolean[] value [true,false,true]
alarm alarm
int severity 0
string message
structure timeStamp
timeStamp timeStamp
long secondsPastEpoch 0
int nanoSeconds 0
structure byte
byteArray value [0,1,2]
structure alarm
byte[] value [0,1,2]
alarm alarm
int severity 0
string message
structure timeStamp
timeStamp timeStamp
long secondsPastEpoch 0
int nanoSeconds 0
structure short
shortArray value [0,1,2]
structure alarm
short[] value [0,1,2]
alarm alarm
int severity 0
string message
structure timeStamp
timeStamp timeStamp
long secondsPastEpoch 0
int nanoSeconds 0
structure int
intArray value [0,1,2]
structure alarm
int[] value [0,1,2]
alarm alarm
int severity 0
string message
structure timeStamp
timeStamp timeStamp
long secondsPastEpoch 0
int nanoSeconds 0
structure long
longArray value [0,1,2]
structure alarm
long[] value [0,1,2]
alarm alarm
int severity 0
string message
structure timeStamp
timeStamp timeStamp
long secondsPastEpoch 0
int nanoSeconds 0
structure float
floatArray value [0,1,2]
structure alarm
float[] value [0,1,2]
alarm alarm
int severity 0
string message
structure timeStamp
timeStamp timeStamp
long secondsPastEpoch 0
int nanoSeconds 0
structure double
doubleArray value [0,1,2]
structure alarm
double[] value [0,1,2]
alarm alarm
int severity 0
string message
structure timeStamp
timeStamp timeStamp
long secondsPastEpoch 0
int nanoSeconds 0
structure string
stringArray value [0,1,2]
structure alarm
string[] value [0,1,2]
alarm alarm
int severity 0
string message
structure timeStamp
timeStamp timeStamp
long secondsPastEpoch 0
int nanoSeconds 0
linkedListNode: totalConstruct 5 totalDestruct 0
-22
View File
@@ -1,22 +0,0 @@
2c2,3
< structure[] value
---
> structureArray value
> [
18c19
< string message
---
> string message ,
34c35
< string message
---
> string message ,
51c52,53
< alarm alarm
---
> ]
> structure alarm
54c56
< timeStamp timeStamp
---
> structure timeStamp
+35 -37
View File
@@ -1,38 +1,5 @@
structure powerSupply
structureArray value
[
structure powerSupply
structure voltage
double value 0
structure alarm
int severity 0
string message
structure power
double value 0
structure alarm
int severity 0
string message
structure current
double value 0
structure alarm
int severity 0
string message ,
structure powerSupply
structure voltage
double value 0
structure alarm
int severity 0
string message
structure power
double value 0
structure alarm
int severity 0
string message
structure current
double value 0
structure alarm
int severity 0
string message ,
structure[] value
structure powerSupply
structure voltage
double value 0
@@ -49,11 +16,42 @@ structure powerSupply
structure alarm
int severity 0
string message
]
structure alarm
structure powerSupply
structure voltage
double value 0
structure alarm
int severity 0
string message
structure power
double value 0
structure alarm
int severity 0
string message
structure current
double value 0
structure alarm
int severity 0
string message
structure powerSupply
structure voltage
double value 0
structure alarm
int severity 0
string message
structure power
double value 0
structure alarm
int severity 0
string message
structure current
double value 0
structure alarm
int severity 0
string message
alarm alarm
int severity 0
string message
structure timeStamp
timeStamp timeStamp
long secondsPastEpoch 0
int nanoSeconds 0
linkedListNode: totalConstruct 5 totalDestruct 0
+1 -1
View File
@@ -1 +1 @@
time per call 8.982863 microseconds
time per call 9.434397 microseconds
+4 -4
View File
@@ -1,5 +1,5 @@
current 1292844557 996799614 milliSec 1292844557996
2010.12.20 06:29:17 996799614 nanoSeconds isDst false
current 1292845147 903990741 milliSec 1292845147903
2010.12.20 06:39:07 903990741 nanoSeconds isDst false
fromTime_t
current 1292844557 0 milliSec 1292844557000
2010.12.20 06:29:17 0 nanoSeconds isDst false
current 1292845147 0 milliSec 1292845147000
2010.12.20 06:39:07 0 nanoSeconds isDst false
+6 -6
View File
@@ -1,6 +1,6 @@
one requested 0.400000 diff 0.400278 seconds
two requested 0.200000 diff 0.200263 seconds
one requested 0.200000 diff 0.200349 seconds
two requested 0.400000 diff 0.400335 seconds
one requested 0.000000 diff 0.000086 seconds
two requested 0.000000 diff 0.000104 seconds
one requested 0.400000 diff 0.400215 seconds
two requested 0.200000 diff 0.200168 seconds
one requested 0.200000 diff 0.200188 seconds
two requested 0.400000 diff 0.400392 seconds
one requested 0.000000 diff 0.000068 seconds
two requested 0.000000 diff 0.000091 seconds