Browse Source

Introduce additional Time units (Year, Day, Hour, Minute)

ndnSIM-v1
Vedran Miletić 12 years ago
parent
commit
df005f262e
  1. 149
      src/core/model/nstime.h
  2. 58
      src/core/model/time.cc
  3. 16
      src/core/test/time-test-suite.cc

149
src/core/model/nstime.h

@ -86,13 +86,17 @@ public:
*/
enum Unit
{
S = 0, //!< second
MS = 1, //!< millisecond
US = 2, //!< microsecond
NS = 3, //!< nanosecond
PS = 4, //!< picosecond
FS = 5, //!< femtosecond
LAST = 6
Y = 0, //!< year, 365 days
D = 1, //!< day, 24 hours
H = 2, //!< hour, 60 minutes
MIN = 3, //!< minute, 60 seconds
S = 4, //!< second
MS = 5, //!< millisecond
US = 6, //!< microsecond
NS = 7, //!< nanosecond
PS = 8, //!< picosecond
FS = 9, //!< femtosecond
LAST = 10
};
inline Time &operator = (const Time &o)
@ -182,6 +186,10 @@ public:
* - `ns` (nanoseconds)
* - `ps` (picoseconds)
* - `fs` (femtoseconds)
* - `min` (minutes)
* - `h` (hours)
* - `d` (days)
* - `y` (years)
*
* There can be no white space between the numerical portion
* and the units. Any otherwise malformed string causes a fatal error to
@ -308,6 +316,40 @@ public:
{
return ToInteger (Time::FS);
}
/**
* \returns an approximation in minutes of the time stored in this
* instance.
*/
inline double GetMinutes (void) const
{
return ToDouble (Time::MIN);
}
/**
* \returns an approximation in hours of the time stored in this
* instance.
*/
inline double GetHours (void) const
{
return ToDouble (Time::H);
}
/**
* \returns an approximation in days of the time stored in this
* instance.
*/
inline double GetDays (void) const
{
return ToDouble (Time::D);
}
/**
* \returns an approximation in years of the time stored in this
* instance.
*/
inline double GetYears (void) const
{
return ToDouble (Time::Y);
}
/**
* \returns the raw time value, in the current units
*/
@ -762,7 +804,66 @@ inline Time FemtoSeconds (uint64_t fs)
{
return Time::FromInteger (fs, Time::FS);
}
/**
* \brief create ns3::Time instances in units of minutes (equal to 60 seconds).
*
* For example:
* \code
* Time t = Minutes (2.0);
* Simulator::Schedule (Minutes (5.0), ...);
* \endcode
* \param minutes mintues value
* \relates ns3::Time
*/
inline Time Minutes (double minutes)
{
return Time::FromDouble (minutes, Time::MIN);
}
/**
* \brief create ns3::Time instances in units of hours (equal to 60 minutes).
*
* For example:
* \code
* Time t = Hours (2.0);
* Simulator::Schedule (Hours (5.0), ...);
* \endcode
* \param hours hours value
* \relates ns3::Time
*/
inline Time Hours (double hours)
{
return Time::FromDouble (hours, Time::H);
}
/**
* \brief create ns3::Time instances in units of days (equal to 24 hours).
*
* For example:
* \code
* Time t = Days (2.0);
* Simulator::Schedule (Days (5.0), ...);
* \endcode
* \param days days value
* \relates ns3::Time
*/
inline Time Days (double days)
{
return Time::FromDouble (days, Time::D);
}
/**
* \brief create ns3::Time instances in units of years (equal to 365 days).
*
* For example:
* \code
* Time t = Years (2.0);
* Simulator::Schedule (Years (5.0), ...);
* \endcode
* \param years years value
* \relates ns3::Time
*/
inline Time Years (double years)
{
return Time::FromDouble (years, Time::Y);
}
/**
* \see Seconds(double)
@ -812,6 +913,38 @@ inline Time FemtoSeconds (int64x64_t fs)
{
return Time::From (fs, Time::FS);
}
/**
* \see Minutes(uint64_t)
* \relates ns3::Time
*/
inline Time Minutes (int64x64_t minutes)
{
return Time::From (minutes, Time::MIN);
}
/**
* \see Minutes(uint64_t)
* \relates ns3::Time
*/
inline Time Hours (int64x64_t hours)
{
return Time::From (hours, Time::H);
}
/**
* \see Minutes(uint64_t)
* \relates ns3::Time
*/
inline Time Days (int64x64_t days)
{
return Time::From (days, Time::D);
}
/**
* \see Minutes(uint64_t)
* \relates ns3::Time
*/
inline Time Years (int64x64_t years)
{
return Time::From (years, Time::Y);
}
// internal function not publicly documented
inline Time TimeStep (uint64_t ts)

58
src/core/model/time.cc

@ -123,6 +123,22 @@ Time::Time (const std::string& s)
{
*this = Time::FromDouble (r, Time::FS);
}
else if (trailer == std::string ("min"))
{
*this = Time::FromDouble (r, Time::MIN);
}
else if (trailer == std::string ("h"))
{
*this = Time::FromDouble (r, Time::H);
}
else if (trailer == std::string ("d"))
{
*this = Time::FromDouble (r, Time::D);
}
else if (trailer == std::string ("y"))
{
*this = Time::FromDouble (r, Time::Y);
}
else
{
NS_ABORT_MSG ("Can't Parse Time " << s);
@ -176,21 +192,41 @@ Time::SetResolution (enum Unit unit, struct Resolution *resolution,
ConvertTimes (unit);
}
int8_t power [LAST] = { 15, 12, 9, 6, 3, 0};
// Y, D, H, MIN, S, MS, US, NS, PS, FS
const int8_t power [LAST] = { 17, 17, 17, 16, 15, 12, 9, 6, 3, 0 };
const int32_t coefficient [LAST] = { 315360, 864, 36, 6, 1, 1, 1, 1, 1, 1 };
for (int i = 0; i < Time::LAST; i++)
{
int shift = power[i] - power[(int)unit];
int64_t factor = (int64_t) std::pow (10, std::fabs (shift));
int quotient = 1;
if (coefficient[i] > coefficient[(int) unit])
{
quotient = coefficient[i] / coefficient[(int) unit];
NS_ASSERT (quotient * coefficient[(int) unit] == coefficient[i]);
}
else if (coefficient[i] < coefficient[(int) unit])
{
quotient = coefficient[(int) unit] / coefficient[i];
NS_ASSERT (quotient * coefficient[i] == coefficient[(int) unit]);
}
NS_LOG_DEBUG ("SetResolution for unit " << (int) unit << " loop iteration " << i
<< " has shift " << shift << " has quotient " << quotient);
int64_t factor = static_cast<int64_t> (std::pow (10, std::fabs (shift)) * quotient);
double realFactor = std::pow (10, (double) shift)
* static_cast<double> (coefficient[i]) / coefficient[(int) unit];
NS_LOG_DEBUG ("SetResolution factor " << factor << " real factor " << realFactor);
struct Information *info = &resolution->info[i];
info->factor = factor;
if (shift == 0)
// here we could equivalently check for realFactor == 1.0 but it's better
// to avoid checking equality of doubles
if (shift == 0 && quotient == 1)
{
info->timeFrom = int64x64_t (1);
info->timeTo = int64x64_t (1);
info->toMul = true;
info->fromMul = true;
}
else if (shift > 0)
else if (realFactor > 1)
{
info->timeFrom = int64x64_t (factor);
info->timeTo = int64x64_t::Invert (factor);
@ -199,7 +235,7 @@ Time::SetResolution (enum Unit unit, struct Resolution *resolution,
}
else
{
NS_ASSERT (shift < 0);
NS_ASSERT (realFactor < 1);
info->timeFrom = int64x64_t::Invert (factor);
info->timeTo = int64x64_t (factor);
info->toMul = true;
@ -368,6 +404,18 @@ operator<< (std::ostream& os, const Time & time)
case Time::FS:
unit = "fs";
break;
case Time::MIN:
unit = "min";
break;
case Time::H:
unit = "h";
break;
case Time::D:
unit = "d";
break;
case Time::Y:
unit = "y";
break;
case Time::LAST:
NS_ABORT_MSG ("can't be reached");
unit = "unreachable";

16
src/core/test/time-test-suite.cc

@ -47,6 +47,22 @@ TimeSimpleTestCase::DoSetup (void)
void
TimeSimpleTestCase::DoRun (void)
{
NS_TEST_ASSERT_MSG_EQ_TOL (Years (1.0).GetYears (), 1.0, Years (1).GetYears (),
"is 1 really 1 ?");
NS_TEST_ASSERT_MSG_EQ_TOL (Years (10.0).GetYears (), 10.0, Years (1).GetYears (),
"is 10 really 10 ?");
NS_TEST_ASSERT_MSG_EQ_TOL (Days (1.0).GetDays (), 1.0, Days (1).GetDays (),
"is 1 really 1 ?");
NS_TEST_ASSERT_MSG_EQ_TOL (Days (10.0).GetDays (), 10.0, Days (1).GetDays (),
"is 10 really 10 ?");
NS_TEST_ASSERT_MSG_EQ_TOL (Hours (1.0).GetHours (), 1.0, Hours (1).GetHours (),
"is 1 really 1 ?");
NS_TEST_ASSERT_MSG_EQ_TOL (Hours (10.0).GetHours (), 10.0, Hours (1).GetHours (),
"is 10 really 10 ?");
NS_TEST_ASSERT_MSG_EQ_TOL (Minutes (1.0).GetMinutes (), 1.0, Minutes (1).GetMinutes (),
"is 1 really 1 ?");
NS_TEST_ASSERT_MSG_EQ_TOL (Minutes (10.0).GetMinutes (), 10.0, Minutes (1).GetMinutes (),
"is 10 really 10 ?");
NS_TEST_ASSERT_MSG_EQ_TOL (Seconds (1.0).GetSeconds (), 1.0, TimeStep (1).GetSeconds (),
"is 1 really 1 ?");
NS_TEST_ASSERT_MSG_EQ_TOL (Seconds (10.0).GetSeconds (), 10.0, TimeStep (1).GetSeconds (),

Loading…
Cancel
Save