微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 16 位计数器检测多个窗口/轨道是否与单个窗口重叠

如何解决使用 16 位计数器检测多个窗口/轨道是否与单个窗口重叠

我得到多个轨道(称为窗口),具有开始和结束时间戳以及具有相同窗口的窗口。我需要检查是否有任何曲目时间戳与此窗口时间戳匹配。所有时间戳均为 16 位格式。这些时间戳是从同一个单调时钟生成的。

Process_1:

track_start -> get_data(clock_monotonic) & 0xFFFF

track_end -> get_data(clock_monotonic) & 0xFFFF

Process_2:

window_start -> get_data(clock_monotonic) & 0xFFFF

window_end -> get_data(clock_monotonic) & 0xFFFF

Process_3:

检测轨道是否与窗口匹配?

问题是 16 位翻转。下面是我解决这个问题的算法:

  1. 获取名为“当前”的 64 位当前时间戳

  2. 轨道和窗口的所有时间戳都被转换为 ('current'&0xFFFFFFFFFFFF0000) |时间戳,即较低的 16 位 LSB 被时间戳替换。

  3. 如果开始>结束(翻转问题),我们只使用开始时间戳并添加差异。所以new end timestamp = end + (0xFFFF - start) + end + 1。看代码中的remap函数

  4. 这是可行的,因为 Process_3 将获得最多 1 分钟延迟的轨道和窗口时间戳。

     #include <chrono>
     #include <cstdint>
     #include <iostream>
     #include <thread>
     #include <stdlib.h>     /* srand,rand */
     #include <vector>
     #include <time.h>       /* time */
     #include <unistd.h>
     #include <assert.h>
    
     using namespace std;
    
     auto getTimeStampCount() {
         struct timespec ts;
         clock_gettime( CLOCK_MONOTONIC,&ts );
         return (uint64_t)ts.tv_sec * 1000000000U + (uint64_t)ts.tv_nsec;
     }
    
     /* returns tuples in this format <16bit start,16bit end,real 64bit start,real 64bit end> */
     auto generateTimeStamp() {
         auto ms = getTimeStampCount();
         int x = ms & 0xFFFF;
         //generate a random number between 1 and 65535
         int randomNumber = rand() % 65535 + 1;
         int y = (x + randomNumber) & 0xFFFF;/
         return make_tuple(x,y,ms,ms + randomNumber);
     }
    
     bool isOverlapping(tuple<int64_t,int64_t> a,tuple<int64_t,int64_t> b) {
         return get<0>(a) <= get<1>(b) && get<0>(b) <= get<1>(a);
     }
    
     //for printing tuples
     template<std::size_t> struct int_{};
    
     template <class Tuple,size_t Pos>
     std::ostream& print_tuple(std::ostream& out,const Tuple& t,int_<Pos> ) {
         out << std::get< std::tuple_size<Tuple>::value-Pos >(t) << ',';
         return print_tuple(out,t,int_<Pos-1>());
     }
    
     template <class Tuple>
     std::ostream& print_tuple(std::ostream& out,int_<1> ) {
         return out << std::get<std::tuple_size<Tuple>::value-1>(t);
     }
    
     template <class... Args>
     ostream& operator<<(ostream& out,const std::tuple<Args...>& t) {
         out << '(';
         print_tuple(out,int_<sizeof...(Args)>());
         return out << ')';
     }
    
     auto remap(int64_t currentTime,int64_t,int64_t> t) {
         int64_t mask = 0xFFFFFFFFFFFF0000; //to remove 16 lsb bits
         int64_t x = (currentTime & mask) | get<0>(t);
         int64_t y = (currentTime & mask) | get<1>(t);
         /* 
              *  normal case: where x is less than y
              *                     ____x____________y______ 
              *                     <--------0xffff-------->
              *
              *  abnormal case: where x is greater than y
              *                     ____y____________x______ 
              *                     <--------0xffff-------->
          *  In the abnormal case just subtract 0xffff - x) + y + 1 to get the duration by which y increased
             */
         if(x > y) {
             int64_t increase = (0xFFFF - x) + y + 1;
             return make_tuple(x,y + increase);
         }
         return make_tuple(x,y);
     }
    
     int main ()
     {
         srand (time(NULL));
    
         //generate the timestamp for SSL
         vector<tuple<int64_t,int64_t> > tracks;
         for (int i = 0; i < rand()%5; i++) {
             tracks.push_back(generateTimeStamp());
         }
         for (int i = 0; i < tracks.size(); i++)
             cout << hex << "generated tracks " << tracks[i] << endl;
    
         //generate the timestamp for window
         auto window = generateTimeStamp();
         cout << hex << "generated window " << window << endl;
    
         auto currentTimeStamp = getTimeStampCount();
         cout << hex << "current timestamp " << currentTimeStamp << endl;
         //make sure currentTimeStamp is greater than current window timestamps and the difference between them is not more than 16 bits(approximately 1 minute)
         for (int i = 0; i < tracks.size(); i++) {
             if(currentTimeStamp <= get<3>(tracks[i]) || (get<2>(tracks[i]) - currentTimeStamp) >= 0xFFFF) {
                 cout << "error " << "currentTimeStamp " << currentTimeStamp << "track " << tracks[i] << endl;
                 exit(0);
             }
             if(currentTimeStamp <= get<3>(window) || (get<2>(window) - currentTimeStamp) >= 0xFFFF) {
                 cout << "error " << "currentTimeStamp " << currentTimeStamp << "window " << window << endl;
                 exit(0);
             }
         }
    
         //remapped tracks timestamps 
         std::vector<std::tuple<int64_t,int64_t>> remappedTracks;
         for (int i = 0; i < tracks.size(); i++) {
             remappedTracks.push_back(remap(currentTimeStamp,tracks[i]));
         }
    
         //remapped window timestamps 
         auto remappedWindow = remap(currentTimeStamp,window);
         cout << "remapped window " << hex << remappedWindow << endl;
    
         //check if window timestamps overlap with tracks timestamps
         for (int i = 0; i < tracks.size(); i++) {
             auto realTrackTimeStamps = make_tuple(get<2>(tracks[i]),get<3>(tracks[i]));
             auto realWindowTimeStamps = make_tuple(get<2>(window),get<3>(window));
             bool shouldBe = isOverlapping(realTrackTimeStamps,realWindowTimeStamps);
             bool got = isOverlapping(remappedTracks[i],remappedWindow);
             if (shouldBe != got) {
                 cout << "generated track " << tracks[i] << endl;
                 cout << "generated window " << window << endl;
                 cout << "ramapped track " << remappedTracks[i] << endl;
                 cout << "ramapped window " << remappedWindow << endl;
             }
             assert(shouldBe == got);
         }
     }
    

代码https://ideone.com/cpUrHL 给出一些想法。这是提供透视图的模拟代码

有任何改进的想法或您能想到的任何错误吗?

注意:无法修改 Process_1 和 2 以传递附加信息,并且此时无法更改 api。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。