def link_list(expand_size)
      list = [@base]
      # fd
      work = proc do |ptr, nxt, append|
        sz = 0
        dup = {}
        while ptr != @base && sz < expand_size
          append.call(ptr)
          break if ptr.nil? || dup[ptr] # invalid or duplicated pointer

          dup[ptr] = true
          ptr = __send__(nxt, ptr)
          sz += 1
        end
      end
      work.call(@fd, :fd_of, ->(ptr) { list << ptr })
      work.call(@bk, :bk_of, ->(ptr) { list.unshift(ptr) })
      list
    end
def link_list(expand_size)
      list = [@base]
      # fd
      work = proc do |ptr, nxt, append|
        sz = 0
        dup = {}
        while ptr != @base && sz < expand_size
          append.call(ptr)
          break if ptr.nil? || dup[ptr] # invalid or duplicated pointer

          dup[ptr] = true
          ptr = __send__(nxt, ptr)
          sz += 1
        end
      end
      work.call(@fd, :fd_of, ->(ptr) { list << ptr })
      work.call(@bk, :bk_of, ->(ptr) { list.unshift(ptr) })
      list
    end
Return the double link list with bin in the center.

 The list will like +[..., bk of bk, bk of bin, bin, fd of bin, fd of fd, ...]+.
 @param [Integer] expand_size
   At most expand size. For +size = 2+, the expand list would be <tt>bk, bk, bin, fd, fd</tt>.
 @return [Array<Integer>] The linked list.