Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 日志结构文件系统中的记录查找算法_Algorithm_Logging_Data Structures_Filesystems - Fatal编程技术网

Algorithm 日志结构文件系统中的记录查找算法

Algorithm 日志结构文件系统中的记录查找算法,algorithm,logging,data-structures,filesystems,Algorithm,Logging,Data Structures,Filesystems,我有很多记录。每个记录都有一个ID和时间戳。新记录以单调递增的ID追加到日志中,即使其间可能会删除记录 问题是-如果给您一个时间戳T1,那么提供一个有效的算法来确定具有timestamp=Ceil(T1)的日志记录 注意事项。日志可能非常大,有数百万条记录。由于记录删除,可能会丢失记录 示例:如果日志记录=(ID,时间戳),则日志可以如下所示: (1,10)、(2,11)、(5,15)、(8,18)、(9,19)、(10,20) 查找最小时间戳大于或等于17的记录的ID 答案是8 查找最小时间戳

我有很多记录。每个记录都有一个ID和时间戳。新记录以单调递增的ID追加到日志中,即使其间可能会删除记录

问题是-如果给您一个时间戳T1,那么提供一个有效的算法来确定具有timestamp=Ceil(T1)的日志记录

注意事项。日志可能非常大,有数百万条记录。由于记录删除,可能会丢失记录

示例:如果日志记录=(ID,时间戳),则日志可以如下所示:

(1,10)、(2,11)、(5,15)、(8,18)、(9,19)、(10,20)

查找最小时间戳大于或等于17的记录的ID

答案是8

查找最小时间戳大于或等于11的记录的ID

答案是2

查找最小时间戳大于或等于22的记录的ID

答案是零

查找最小时间戳大于或等于5的记录的ID

答案是1

我提出了简单的数据结构来解决这个问题

/*索引:01 2 3 4 5 6 7 8 9 10 11 12*/
int-id[]={1,2,6,7,10,11,12};
int-map[]={0,1,1,0,0,1,1,0,0,0,1,1,1};
int time[]={0,10,20,0,0,0,60,70,0,0,100,110,120};

int start=1,end=12;//这是我们所知道的。
如果在两次搜索之间将此函数保存在内存中,我们可以利用以前的搜索来缩小将来的搜索范围。如果获取时间戳是昂贵的,那么这可能是一个非常显著的改进。但是如果它们已经在你的帖子中的数组中,那么这基本上是一个没有意义的问题。 假设时间戳是唯一的,我将从以下内容开始寻找解决方案:

int FindFirstNonZero(int startIdx)
{
    int myIdx=startIdx;
    while (map[myIdx] == 0)
    {
        myIdx++;
    }
    return(myIdx);
}

int FindLastNonZero(int startIdx)
{
    int myIdx=startIdx;
    while (map[myIdx] == 0)
    {
        myIdx--;
    }
    return(myIdx);
}

int find_ceil_id(int timestamp) 
{
    int low=FindFirstNonZero(0);
    int high=FindLastNonZero(map.count -1);
    int checkIndex = FindLastNonZero((low + high)/2);
    int checkTime;

    while (low < FindLastNonZero(high - 1))
    {
        checkTime = time[checkIndex];
        if (checkTime >= timestamp) {
            high = checkIndex;
        } else {
            low = checkIndex;
        }
        checkIndex = FindLastNonZero((low+high) / 2);
        if (checkIndex == low) {
            checkIndex = FindFirstNonZero(low+1);
        }
    }
    return (high);
}
int-FindFirstNonZero(int-startIdx)
{
int myIdx=startIdx;
while(map[myIdx]==0)
{
myIdx++;
}
返回(myIdx);
}
int FindLastNonZero(int startIdx)
{
int myIdx=startIdx;
while(map[myIdx]==0)
{
myIdx--;
}
返回(myIdx);
}
int find_ceil_id(int时间戳)
{
int low=FindFirstNonZero(0);
int high=FindLastNonZero(map.count-1);
int checkIndex=FindLastNonZero((低+高)/2);
整数校验时间;
而(低=时间戳){
高=检查指数;
}否则{
低=检查索引;
}
检查索引=FindLastNonZero((低+高)/2);
如果(检查索引==低){
检查索引=FindFirstNonZero(低+1);
}
}
回报率(高);
}
从您的一些评论来看,时间戳似乎可以重复。是这样吗?如果是这样的话,就需要对上述内容稍作修改。。。没关系,它做了更改,甚至使代码更简单。 这是一个基本的二进制搜索,它将在log2(N)尝试中找到正确的元素,N是ID数组的大小。因此,对于ID数组中的100多万个条目,只需检查其中的20个就可以找到正确的条目。对于刚刚超过十亿个条目,它只需要检查30个
我不是在编译和测试代码,这取决于你。但它应该可以工作。

timestamp大于或等于20时的最小id应该是10,对吗?你说得对。对于20,它将给出10,但对于22,答案是零。从您在原始帖子中编辑的内容来看,现在的问题似乎是在内存数组中搜索,而不是在文件系统日志中搜索。完全不同的搜索问题。而这一点点虚构的数据根本就不会削减它。一个好的搜索算法取决于数据,一个好的程序员会希望看到真实的数据。你这样做是为了一份真正的工作,还是只是为了好玩而“测验”我们?我需要周围人的帮助,这是我面临的一个真正的问题。我认为我提供的数据是正确的。如果我解决了这个问题,那么实际问题也可以解决。这里有两个假设:时间[ID]是昂贵的,您不能索引到ID[]。好的,我很乐意与您合作。问题,此功能是否会在一个搜索中持续到另一个搜索?也就是说,这个函数是在整个程序的一次执行中被多次调用,还是被调用,给出结果,程序结束?Gilchrist。您的解决方案的问题在于,您假设id和时间戳之间存在相关性。不幸的是,没有。如果日志记录速度太快,可能数千条记录都有相同的时间戳。但在更长的时间内,它会平均吗?它不一定是一个完美的、经久不衰的关联,因为在此之后,您将应用不同的搜索来从那里获得实际的节点。但如果这仍然不可行,我只会使用二进制搜索,但通过在内存中保留一个节点表来改进它,在您开始访问文件系统之前,它会让您在附近找到您。如果可能的话。如果不仔细查看数据和所有其他会影响搜索算法的变量,就很难对这样的事情提出建议。