public Optional getStateFromTimestamp()

in baremaps-openstreetmap/src/main/java/org/apache/baremaps/openstreetmap/state/StateReader.java [117:188]


  public Optional<State> getStateFromTimestamp(LocalDateTime timestamp) {
    var upper = getLatestState();
    if (upper.isEmpty()) {
      return Optional.empty();
    }
    if (timestamp.isAfter(upper.get().timestamp()) || upper.get().sequenceNumber() <= 0) {
      return upper;
    }
    var lower = Optional.<State>empty();
    var lowerId = 0L;
    while (lower.isEmpty()) {
      lower = getLatestState(lowerId);
      if (lower.isPresent() && lower.get().timestamp().isAfter(timestamp)) {
        if (lower.get().sequenceNumber() == 0
            || lower.get().sequenceNumber() + 1 >= upper.get().sequenceNumber()) {
          return lower;
        }
        upper = lower;
        lower = Optional.empty();
        lowerId = 0L;
      }
      if (lower.isEmpty()) {
        var newId = (lowerId + upper.get().sequenceNumber()) / 2;
        if (newId <= lowerId) {
          return upper;
        }
        lowerId = newId;
      }
    }
    long baseSplitId;
    while (true) {
      if (balancedSearch) {
        baseSplitId = ((lower.get().sequenceNumber() + upper.get().sequenceNumber()) / 2);
      } else {
        var tsInt = upper.get().timestamp().toEpochSecond(ZoneOffset.UTC)
            - lower.get().timestamp().toEpochSecond(ZoneOffset.UTC);
        var seqInt = upper.get().sequenceNumber() - lower.get().sequenceNumber();
        var goal = timestamp.getSecond() - lower.get().timestamp().getSecond();
        baseSplitId =
            lower.get().sequenceNumber() + (long) Math.ceil((double) (goal * seqInt) / tsInt);
        if (baseSplitId >= upper.get().sequenceNumber()) {
          baseSplitId = upper.get().sequenceNumber() - 1;
        }
      }
      var split = getLatestState(baseSplitId);
      if (split.isEmpty()) {
        var splitId = baseSplitId - 1;
        while (split.isEmpty() && splitId > lower.get().sequenceNumber()) {
          split = getLatestState(splitId);
          splitId--;
        }
      }
      if (split.isEmpty()) {
        var splitId = baseSplitId + 1;
        while (split.isEmpty() && splitId < upper.get().sequenceNumber()) {
          split = getLatestState(splitId);
          splitId++;
        }
      }
      if (split.isEmpty()) {
        return lower;
      }
      if (split.get().timestamp().isBefore(timestamp)) {
        lower = split;
      } else {
        upper = split;
      }
      if (lower.get().sequenceNumber() + 1 >= upper.get().sequenceNumber()) {
        return lower;
      }
    }
  }