///|
/// 返回 freelist 中的 trunk 与 leaf 页号,并校验计数与循环。
pub fn Database::freelist(self : Database) -> Array[Int] raise SqliteError {
  let result : Array[Int] = []
  let visited : Map[Int, Bool] = Map([])
  let mut next = page_number(self.header.freelist_trunk)
  while next != 0 {
    if next == 1 {
      raise Invalid("schema 页不能出现在 freelist")
    }
    if visited.contains(next) {
      raise Invalid("freelist 页重复或形成环")
    }
    if result.length() >= self.limits.max_pages {
      raise LimitExceeded("freelist 页数超过限制")
    }
    visited[next] = true
    result.push(next)
    let bytes = self.read_page(next)
    let count = page_number(read_u32(bytes, 4))
    if count > (self.header.usable_size - 8) / 4 {
      raise Invalid("freelist trunk 指针数组越界")
    }
    for i = 0; i < count; i = i + 1 {
      let leaf = page_number(read_u32(bytes, 8 + i * 4))
      if leaf <= 1 || leaf > self.page_count || visited.contains(leaf) {
        raise Invalid("freelist leaf 越界或重复")
      }
      if result.length() >= self.limits.max_pages {
        raise LimitExceeded("freelist 页数超过限制")
      }
      visited[leaf] = true
      result.push(leaf)
    }
    next = page_number(read_u32(bytes, 0))
  }
  if result.length().reinterpret_as_uint() != self.header.freelist_pages {
    raise Invalid("freelist 长度与数据库头不一致")
  }
  result
}