1 /* Copyright 2012-present Facebook, Inc. 2 * Licensed under the Apache License, Version 2.0 */ 3 #pragma once 4 #include <unordered_map> 5 #include "watchman_synchronized.h" 6 7 struct watchman_clock { 8 uint32_t ticks; 9 time_t timestamp; 10 }; 11 typedef struct watchman_clock w_clock_t; 12 13 struct w_query_ctx; 14 struct w_query_since; 15 16 struct ClockPosition { 17 uint32_t rootNumber{0}; 18 uint32_t ticks{0}; 19 20 ClockPosition() = default; ClockPositionClockPosition21 ClockPosition(uint32_t rootNumber, uint32_t ticks) 22 : rootNumber(rootNumber), ticks(ticks) {} 23 24 w_string toClockString() const; 25 }; 26 27 enum w_clockspec_tag { 28 w_cs_timestamp, 29 w_cs_clock, 30 w_cs_named_cursor 31 }; 32 33 struct ClockSpec { 34 enum w_clockspec_tag tag; 35 time_t timestamp; 36 struct { 37 uint64_t start_time; 38 int pid; 39 ClockPosition position; 40 } clock; 41 struct { 42 w_string cursor; 43 } named_cursor; 44 45 // Optional SCM merge base parameters 46 w_string scmMergeBase; 47 w_string scmMergeBaseWith; 48 49 ClockSpec(); 50 explicit ClockSpec(const ClockPosition& position); 51 explicit ClockSpec(const json_ref& value); 52 53 /** Given a json value, parse out a clockspec. 54 * Will return nullptr if the input was json null, indicating 55 * an absence of a specified clock value. 56 * Throws std::domain_error for badly formed clockspec value. 57 */ 58 static std::unique_ptr<ClockSpec> parseOptionalClockSpec( 59 const json_ref& value); 60 61 /** Evaluate the clockspec against the inputs, returning 62 * the effective since parameter. 63 * If cursorMap is passed in, it MUST be unlocked, as this method 64 * will acquire a lock to evaluate a named cursor. */ 65 struct w_query_since evaluate( 66 const ClockPosition& position, 67 const uint32_t lastAgeOutTick, 68 watchman::Synchronized<std::unordered_map<w_string, uint32_t>>* 69 cursorMap = nullptr) const; 70 71 /** Initializes some global state needed for clockspec evaluation */ 72 static void init(); 73 positionClockSpec74 inline const ClockPosition& position() const { 75 w_check(tag == w_cs_clock, "position() called for non-clock clockspec"); 76 return clock.position; 77 } 78 79 bool hasScmParams() const; 80 81 /** Returns a json value representing the current state of this ClockSpec 82 * that can be parsed by the ClockSpec(const json_ref&) 83 * constructor of this class */ 84 json_ref toJson() const; 85 }; 86