+
+/**
+ * Divide relative time by a given factor.
+ *
+ * @param rel some duration
+ * @param factor integer to divide by
+ * @return FOREVER if rel=FOREVER or factor==0; otherwise rel/factor
+ */
+struct GNUNET_TIME_Relative
+GNUNET_TIME_relative_divide (struct GNUNET_TIME_Relative rel,
+ unsigned int factor)
+{
+ struct GNUNET_TIME_Relative ret;
+
+ if ((0 == factor) ||
+ (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us))
+ return GNUNET_TIME_UNIT_FOREVER_REL;
+ ret.rel_value_us = rel.rel_value_us / (unsigned long long) factor;
+ return ret;
+}
+
+
+/**
+ * Calculate the estimate time of arrival/completion
+ * for an operation.
+ *
+ * @param start when did the operation start?
+ * @param finished how much has been done?
+ * @param total how much must be done overall (same unit as for "finished")
+ * @return remaining duration for the operation,
+ * assuming it continues at the same speed
+ */
+struct GNUNET_TIME_Relative
+GNUNET_TIME_calculate_eta (struct GNUNET_TIME_Absolute start, uint64_t finished,
+ uint64_t total)
+{
+ struct GNUNET_TIME_Relative dur;
+ double exp;
+ struct GNUNET_TIME_Relative ret;
+
+ GNUNET_break (finished <= total);
+ if (finished >= total)
+ return GNUNET_TIME_UNIT_ZERO;
+ if (0 == finished)
+ return GNUNET_TIME_UNIT_FOREVER_REL;
+ dur = GNUNET_TIME_absolute_get_duration (start);
+ exp = ((double) dur.rel_value_us) * ((double) total) / ((double) finished);
+ ret.rel_value_us = ((uint64_t) exp) - dur.rel_value_us;
+ return ret;
+}
+
+