为什么在levelDB的缓存中使用while循环(函数Resize)?

时间:2015-07-09 15:58:41

标签: c++ caching while-loop leveldb

当我看到levelDB缓存的实现时,address。我无法理解为什么它在for循环中使用while循环(在函数Resize中),我认为它可以用if语句替换。我希望有人可以帮助我。

 void Resize() {
    uint32_t new_length = 4;
    while (new_length < elems_) {
      new_length *= 2;
    }
    LRUHandle** new_list = new LRUHandle*[new_length];
    memset(new_list, 0, sizeof(new_list[0]) * new_length);
    uint32_t count = 0;
    for (uint32_t i = 0; i < length_; i++) {
      LRUHandle* h = list_[i];
      while (h != NULL) {
        LRUHandle* next = h->next_hash;
        uint32_t hash = h->hash;
        LRUHandle** ptr = &new_list[hash & (new_length - 1)];
        h->next_hash = *ptr;
        *ptr = h;
        h = next;
        count++;
      }
    }
    assert(elems_ == count);
    delete[] list_;
    list_ = new_list;
    length_ = new_length;
  }
};

4 个答案:

答案 0 :(得分:1)

list_显然是一系列链表。 while (h != NULL)h = next(其中nexth->next_hash)相结合,意味着while循环将对每个链接列表的所有元素进行操作,仅在最后一个元素为到达时(当h变为NULL时,要么是因为列表为空,要么是因为next_hash元素是NULL)。

如果您将其替换为if (h != NULL),则它只能用于链接列表的第一个元素。

答案 1 :(得分:1)

看起来list_是一个单链表的动态数组。

我认为list_看起来像下面的

list_[0]-> node_1 -> node_2 -> null
list_[1]-> node_3 -> null
list_[2]-> null
....
list_[n]-> node_m-1 -> node_m -> null

要将所有元素正确复制到new_list,您需要使用while循环。否则,任何不能直接从list_寻址的元素都不会被复制/散列到new_list中。在上图中,意味着node_2和node_m + 1不会被添加到new_list。

new_list将保持相同的形状,但应该有更少的碰撞。

使用if语句new_list看起来像:

new_list[0]-> node_1 -> null
new_list[1]-> null
new_list[2]-> node_2 -> null
...
new_list[p-1]-> node_k -> null
new_list[p] -> null

这就是new_list中的每个项目都会指向1个或0个元素的列表。 注意此图中的node_1不一定与上图中的节点1相同。

使用If语句而不是while循环也会导致内存泄漏,因为您无法再访问所有元素。

答案 2 :(得分:0)

变量toString有一个子列表,SELECT QueryDate=execquery.last_execution_time, SQLString=execsql.text, QueryCount=execution_count FROM sys.dm_exec_query_stats AS execquery CROSS APPLY sys.dm_exec_sql_text(execquery.sql_handle) AS execsql ORDER BY execquery.last_execution_time DESC 循环中的list_[i]循环遍历子列表。

答案 3 :(得分:0)

如果您有两个元素numbers = [0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1] for index, number in enumerate(numbers[9:], start=9): if number == 1: if sum(numbers[index - 9:index]) > 0: numbers[index] += 1 print(numbers) @HostListener('window:beforeunload', ['$event']) public beforeunloadHandler($event) { return $event.returnValue = "Are you sure?"; localStorage.clear(); } 都散列到相同的索引list_[i],则if语句不起作用。在这种情况下,您必须使用while语句合并两个存储桶。同时,此实现中每个存储桶的长度平均小于1,因此,此处的while语句实际上与if语句一样快。