// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

#ifndef IMPALA_RUNTIME_BUFFER_POOL_H
#define IMPALA_RUNTIME_BUFFER_POOL_H

#include <stdint.h>
#include <string>
#include <boost/scoped_ptr.hpp>

#include "common/compiler-util.h"
#include "common/object-pool.h"
#include "common/status.h"
#include "gutil/macros.h"
#include "runtime/mem-tracker-types.h"
#include "util/aligned-new.h"
#include "util/mem-range.h"

namespace impala {

class MetricGroup;
class ReservationTracker;
class RuntimeProfile;
class SystemAllocator;
class TmpFileGroup;

/// A buffer pool that manages memory buffers for all queries in an Impala daemon.
/// The buffer pool enforces buffer reservations, limits, and implements policies
/// for moving spilled memory from in-memory buffers to disk. It also enables reuse of
/// buffers between queries, to avoid frequent allocations.
///
/// The buffer pool can be used for allocating any large buffers (above a configurable
/// minimum length), whether or not the buffers will be spilled. Smaller allocations
/// are not serviced directly by the buffer pool: clients of the buffer pool must
/// subdivide buffers if they wish to use smaller allocations.
///
/// All buffer pool operations are in the context of a registered buffer pool client.
/// A buffer pool client should be created for every allocator of buffers at the level
/// of granularity required for reporting and enforcement of reservations, e.g. an
/// operator. The client tracks buffer reservations via its ReservationTracker and also
/// includes info that is helpful for debugging (e.g. the operator that is associated
/// with the buffer). Unless otherwise noted, it is not safe to invoke concurrent buffer
/// pool operations for the same client.
///
/// Pages, Buffers and Pinning
/// ==========================
/// * A page is a logical block of memory that can reside in memory or on disk.
/// * A buffer is a physical block of memory that can hold a page in memory.
/// * A page handle is used by buffer pool clients to identify and access a page and
///   the corresponding buffer. Clients do not interact with pages directly.
/// * A buffer handle is used by buffer pool clients to identify and access a buffer.
/// * A page is pinned if it has pin count > 0. A pinned page stays mapped to the same
///   buffer.
/// * An unpinned page can be written out to disk by the buffer pool so that the buffer
///   can be used for another purpose.
///
/// Buffer/Page Sizes
/// =================
/// The buffer pool has a minimum buffer size, which must be a power-of-two. Page and
/// buffer sizes must be an exact power-of-two multiple of the minimum buffer size.
///
/// Reservations
/// ============
/// Before allocating buffers or pinning pages, a client must reserve memory through its
/// ReservationTracker. Reservation of n bytes give a client the right to allocate
/// buffers or pin pages summing up to n bytes. Reservations are both necessary and
/// sufficient for a client to allocate buffers or pin pages: the operations succeed
/// unless a "system error" such as a disk write error is encountered that prevents
/// unpinned pages from being written to disk.
///
/// More memory may be reserved than is used, e.g. if a client is not using its full
/// reservation. In such cases, the buffer pool can use the free buffers in any way,
/// e.g. for keeping unpinned pages in memory, so long as it is able to fulfill the
/// reservations when needed, e.g. by flushing unpinned pages to disk.
///
/// Page/Buffer Handles
/// ===================
/// The buffer pool exposes PageHandles and BufferHandles, which are owned by clients of
/// the buffer pool, and act as a proxy for the internal data structure representing the
/// page or buffer in the buffer pool. Handles are "open" if they are associated with a
/// page or buffer. An open PageHandle is obtained by creating a page. PageHandles are
/// closed by calling BufferPool::DestroyPage(). An open BufferHandle is obtained by
/// allocating a buffer or extracting a BufferHandle from a PageHandle. The buffer of a
/// pinned page can also be accessed through the PageHandle. The handle destructors check
/// for resource leaks, e.g. an open handle that would result in a buffer leak.
///
/// Pin Counting of Page Handles:
/// ----------------------------------
/// Page handles are scoped to a client. The invariants are as follows:
/// * A page can only be accessed through an open handle.
/// * A page is destroyed once the handle is destroyed via DestroyPage().
/// * A page's buffer can only be accessed through a pinned handle.
/// * Pin() can be called on an open handle, incrementing the handle's pin count.
/// * Unpin() can be called on a pinned handle, but not an unpinned handle.
/// * Pin() always increases usage of reservations, and Unpin() always decreases usage,
///   i.e. the handle consumes <pin count> * <page size> bytes of reservation.
///
/// Example Usage: Buffers
/// ==================================
/// The simplest use case is to allocate a memory buffer.
/// * The new buffer is created with AllocateBuffer().
/// * The client reads and writes to the buffer as it sees fit.
/// * If the client is done with the buffer's contents it can call FreeBuffer() to
///   destroy the handle and free the buffer, or use TransferBuffer() to transfer
///   the buffer to a different client.
///
/// Example Usage: Spillable Pages
/// ==============================
/// * In order to spill pages to disk, the Client must be registered with a FileGroup,
///   which is used to allocate scratch space on disk.
/// * A spilling operator creates a new page with CreatePage().
/// * The client reads and writes to the page's buffer as it sees fit.
/// * If the operator encounters memory pressure, it can decrease reservation usage by
///   calling Unpin() on the page. The page may then be written to disk and its buffer
///   repurposed internally by BufferPool.
/// * Once the operator needs the page's contents again and has sufficient unused
///   reservation, it can call Pin(), which brings the page's contents back into memory,
///   perhaps in a different buffer. Therefore the operator must fix up any pointers into
///   the previous buffer. Pin() executes asynchronously - the caller only blocks waiting
///   for read I/O if it calls GetBuffer() or ExtractBuffer() while the read is in
///   flight.
/// * If the operator is done with the page, it can call DestroyPage() to destroy the
///   handle and release resources, or call ExtractBuffer() to extract the buffer.
///
/// Synchronization
/// ===============
/// The data structures in the buffer pool itself are thread-safe. Client-owned data
/// structures - Client, PageHandle and BufferHandle - are not protected from concurrent
/// accesses. Clients must ensure that they do not invoke concurrent operations with the
/// same Client, PageHandle or BufferHandle.
class BufferPool : public CacheLineAligned {
 public:
  class BufferAllocator;
  class BufferHandle;
  class ClientHandle;
  class PageHandle;
  class SubReservation;

  /// Constructs a new buffer pool.
  /// 'min_buffer_len': the minimum buffer length for the pool. Must be a power of two.
  /// 'buffer_bytes_limit': the maximum physical memory in bytes that can be used by the
  ///     buffer pool. If 'buffer_bytes_limit' is not a multiple of 'min_buffer_len', the
  ///     remainder will not be usable.
  /// 'clean_page_bytes_limit': the maximum bytes of clean pages that will be retained by
  ///     the buffer pool.
  BufferPool(MetricGroup* metrics, int64_t min_buffer_len, int64_t buffer_bytes_limit,
      int64_t clean_page_bytes_limit);
  ~BufferPool();

  /// Register a client. Returns an error status and does not register the client if the
  /// arguments are invalid. 'name' is an arbitrary name used to identify the client in
  /// any errors messages or logging. If 'file_group' is non-NULL, it is used to allocate
  /// scratch space to write unpinned pages to disk. If it is NULL, unpinning of pages is
  /// not allowed for this client. Counters for this client are added to the (non-NULL)
  /// 'profile'. 'client' is the client to register. 'client' must not already be
  /// registered.
  ///
  /// The client's reservation is created as a child of 'parent_reservation' with limit
  /// 'reservation_limit' and associated with MemTracker 'mem_tracker'. The initial
  /// reservation is 0 bytes. 'mem_limit_mode' determines whether reservation
  /// increases are checked against the soft or hard limit of 'mem_tracker'.
  Status RegisterClient(const std::string& name, TmpFileGroup* file_group,
      ReservationTracker* parent_reservation, MemTracker* mem_tracker,
      int64_t reservation_limit, RuntimeProfile* profile, ClientHandle* client,
      MemLimit mem_limit_mode = MemLimit::SOFT) WARN_UNUSED_RESULT;

  /// Deregister 'client' if it is registered. All pages must be destroyed and buffers
  /// must be freed for the client before calling this. Releases any reservation that
  /// belongs to the client. Idempotent.
  void DeregisterClient(ClientHandle* client);

  /// Create a new page of 'len' bytes with pin count 1. 'len' must be a page length
  /// supported by BufferPool (see BufferPool class comment). The client must have
  /// sufficient unused reservation to pin the new page (otherwise it will DCHECK).
  /// CreatePage() only fails when a system error prevents the buffer pool from fulfilling
  /// the reservation.
  /// On success, the handle is mapped to the new page and 'buffer', if non-NULL, is set
  /// to the page's buffer.
  Status CreatePage(ClientHandle* client, int64_t len, PageHandle* handle,
      const BufferHandle** buffer = nullptr) WARN_UNUSED_RESULT;

  /// Increment the pin count of 'handle'. After Pin() the underlying page will
  /// be mapped to a buffer, which will be accessible through 'handle'. If the data
  /// was evicted from memory, it will be read back into memory asynchronously.
  /// Attempting to access the buffer with ExtractBuffer() or handle.GetBuffer() will
  /// block until the data is in memory. The caller is responsible for ensuring it has
  /// enough unused reservation before calling Pin() (otherwise it will DCHECK). Pin()
  /// only fails when a system error prevents the buffer pool from fulfilling the
  /// reservation or if an I/O error is encountered reading back data from disk.
  /// 'handle' must be open.
  Status Pin(ClientHandle* client, PageHandle* handle) WARN_UNUSED_RESULT;

  /// Decrement the pin count of 'handle'. Decrease client's reservation usage. If the
  /// handle's pin count becomes zero, it is no longer valid for the underlying page's
  /// buffer to be accessed via 'handle'. If the page's total pin count across all
  /// handles that reference it goes to zero, the page's data may be written to disk and
  /// the buffer reclaimed. 'handle' must be open and have a pin count > 0.
  ///
  /// It is an error to reduce the pin count to 0 if 'client' does not have an associated
  /// FileGroup.
  void Unpin(ClientHandle* client, PageHandle* handle);

  /// Destroy the page referenced by 'handle' (if 'handle' is open). Any buffers or disk
  /// storage backing the page are freed. Idempotent. If the page is pinned, the
  /// reservation usage is decreased accordingly.
  void DestroyPage(ClientHandle* client, PageHandle* handle);

  /// Extracts buffer from a pinned page. After this returns, the page referenced by
  /// 'page_handle' will be destroyed and 'buffer_handle' will reference the buffer from
  /// 'page_handle'. This may decrease reservation usage of 'client' if the page was
  /// pinned multiple times via 'page_handle'. May return an error if 'page_handle' was
  /// unpinned earlier with no subsequent GetBuffer() call and a read error is
  /// encountered while bringing the page back into memory.
  Status ExtractBuffer(ClientHandle* client, PageHandle* page_handle,
      BufferHandle* buffer_handle) WARN_UNUSED_RESULT;

  /// Allocates a new buffer of 'len' bytes. Uses reservation from 'client'. The caller
  /// is responsible for ensuring it has enough unused reservation before calling
  /// AllocateBuffer() (otherwise it will DCHECK). AllocateBuffer() only fails when
  /// a system error prevents the buffer pool from fulfilling the reservation.
  /// Safe to call concurrently with any other operations for 'client', except for
  /// operations on the same 'handle'.
  Status AllocateBuffer(
      ClientHandle* client, int64_t len, BufferHandle* handle) WARN_UNUSED_RESULT;

  /// Like AllocateBuffer(), except used when the client may not have the reservation
  /// to allocate the buffer. Tries to increase reservation on the behalf of the client
  /// if needed to allocate the buffer. If the reservation isn't available, 'handle'
  /// isn't opened and OK is returned. If an unexpected error occurs, an error is
  /// returned and any reservation increase remains in effect. Safe to call concurrently
  /// with any other operations for 'client', except for operations on the same 'handle'.
  ///
  /// This function is a transitional mechanism for components to allocate memory from
  /// the buffer pool without implementing the reservation accounting required to operate
  /// within a predetermined memory constraint. Wherever possible, clients should reserve
  /// memory ahead of time and allocate out of that instead of relying on this "best
  /// effort" interface.
  Status AllocateUnreservedBuffer(
      ClientHandle* client, int64_t len, BufferHandle* handle) WARN_UNUSED_RESULT;

  /// If 'handle' is open, close 'handle', free the buffer and decrease the reservation
  /// usage from 'client'. Idempotent. Safe to call concurrently with other operations
  /// for 'client', except for operations on the same 'handle'.
  void FreeBuffer(ClientHandle* client, BufferHandle* handle);

  /// Transfer ownership of buffer from 'src_client' to 'dst_client' and move the
  /// handle from 'src' to 'dst'. Increases reservation usage in 'dst_client' and
  /// decreases reservation usage in 'src_client'. 'src' must be open and 'dst' must be
  /// closed before calling. 'src'/'dst' and 'src_client'/'dst_client' must be different.
  /// After a successful call, 'src' is closed and 'dst' is open. Safe to call
  /// concurrently with any other operations for 'src_client', except for operations
  /// on the same handles.
  Status TransferBuffer(ClientHandle* src_client, BufferHandle* src,
      ClientHandle* dst_client, BufferHandle* dst) WARN_UNUSED_RESULT;

  /// Try to release at least 'bytes_to_free' bytes of memory to the system allocator.
  /// TODO: once IMPALA-4834 is done and all large allocations are served from the buffer
  /// pool, this may not be necessary.
  void ReleaseMemory(int64_t bytes_to_free);

  /// Called periodically by a maintenance thread to release unused memory back to the
  /// system allocator.
  void Maintenance();

  /// Print a debug string with the state of the buffer pool.
  std::string DebugString();

  int64_t min_buffer_len() const { return min_buffer_len_; }
  int64_t GetSystemBytesLimit() const;
  int64_t GetSystemBytesAllocated() const;

  /// Return the limit on bytes of clean pages in the pool.
  int64_t GetCleanPageBytesLimit() const;

  /// Return the total number of clean pages in the pool.
  int64_t GetNumCleanPages() const;

  /// Return the total bytes of clean pages in the pool.
  int64_t GetCleanPageBytes() const;

  /// Return the total number of free buffers in the pool.
  int64_t GetNumFreeBuffers() const;

  /// Return the total bytes of free buffers in the pool.
  int64_t GetFreeBufferBytes() const;

  /// Generous upper bounds on page and buffer size and the number of different
  /// power-of-two buffer sizes.
  static constexpr int LOG_MAX_BUFFER_BYTES = 48;
  static constexpr int64_t MAX_BUFFER_BYTES = 1L << LOG_MAX_BUFFER_BYTES;
  static constexpr int MAX_PAGE_ITER_DEBUG = 100;

 protected:
  friend class BufferPoolTest;
  /// Test helper: get a reference to the allocator.
  BufferAllocator* allocator() { return allocator_.get(); }

 private:
  DISALLOW_COPY_AND_ASSIGN(BufferPool);
  class Client;
  class FreeBufferArena;
  class PageList;
  struct Page;

  /// Allocator for allocating and freeing all buffer memory and managing lists of free
  /// buffers and clean pages.
  boost::scoped_ptr<BufferAllocator> allocator_;

  /// The minimum length of a buffer in bytes. All buffers and pages are a power-of-two
  /// multiple of this length. This is always a power of two.
  const int64_t min_buffer_len_;
};

/// External representation of a client of the BufferPool. Clients are used for
/// reservation accounting, and will be used in the future for tracking per-client
/// buffer pool counters. This class is the external handle for a client so
/// each Client instance is owned by the BufferPool's client, rather than the BufferPool.
/// Each Client should only be used by a single thread at a time: concurrently calling
/// Client methods or BufferPool methods with the Client as an argument is not supported.
class BufferPool::ClientHandle {
 public:
  ClientHandle() : impl_(NULL) {}
  /// Client must be deregistered.
  ~ClientHandle() { DCHECK(!is_registered()); }

  /// Request to increase reservation for this client by 'bytes' by calling
  /// ReservationTracker::IncreaseReservation(). Returns true if the reservation was
  /// successfully increased. Thread-safe.
  bool IncreaseReservation(int64_t bytes) WARN_UNUSED_RESULT;

  /// Tries to ensure that 'bytes' of unused reservation is available for this client
  /// to use by calling ReservationTracker::IncreaseReservationToFit(). Returns true
  /// if successful, after which 'bytes' can be used. Thread-safe.
  bool IncreaseReservationToFit(int64_t bytes) WARN_UNUSED_RESULT;

  /// Try to decrease this client's reservation down to a minimum of 'target_bytes' by
  /// releasing up to 'max_decrease' bytes of unused reservation to ancestor
  /// ReservationTrackers, all the way up to the root of the ReservationTracker tree.
  /// May block waiting for unpinned pages to be flushed. This client's reservation
  /// must be at least 'target_bytes' before calling this method. May fail if decreasing
  /// the reservation requires flushing unpinned pages to disk and a write to disk fails.
  /// Thread-safe.
  Status DecreaseReservationTo(
      int64_t max_decrease, int64_t target_bytes) WARN_UNUSED_RESULT;

  /// Move some of this client's reservation to the SubReservation. 'bytes' of unused
  /// reservation must be available in this tracker.
  void SaveReservation(SubReservation* dst, int64_t bytes);

  /// Move some of src's reservation to this client. 'bytes' of unused reservation must be
  /// available in 'src'.
  ///
  /// This is safe to call concurrently from multiple threads, as long as those threads
  /// coordinate to ensure there is sufficient unused reservation.
  void RestoreReservation(SubReservation* src, int64_t bytes);

  /// Same as above but move all of src's unused reservation to this client.
  void RestoreAllReservation(SubReservation* src);

  /// Accessors for this client's reservation corresponding to the identically-named
  /// methods in ReservationTracker.
  int64_t GetReservation() const;
  int64_t GetUsedReservation() const;
  int64_t GetUnusedReservation() const;

  /// Try to transfer 'bytes' of reservation from 'src' to this client using
  /// ReservationTracker::TransferReservationTo(). Not valid to call if 'this'
  /// has unpinned pages.
  bool TransferReservationFrom(ReservationTracker* src, int64_t bytes);

  /// Transfer 'bytes' of reservation from this client to 'dst' using
  /// ReservationTracker::TransferReservationTo(). The client must have at least 'bytes'
  /// of unused reservation. May fail if transferring the reservation requires flushing
  /// unpinned pages to disk and a write to disk fails, in which case it returns an error
  /// status. May also fail if a reservation limit on 'dst' would be exceeded as a result
  /// of the transfer, in which case *transferred is false but Status::OK is returned.
  ///
  /// This is safe to call concurrently from multiple threads, as long as those threads
  /// coordinate to ensure there is sufficient unused reservation.
  Status TransferReservationTo(ReservationTracker* dst, int64_t bytes, bool* transferred);
  Status TransferReservationTo(ClientHandle* dst, int64_t bytes, bool* transferred);

  /// Call SetDebugDenyIncreaseReservation() on this client's ReservationTracker.
  void SetDebugDenyIncreaseReservation(double probability);

  int64_t min_buffer_len() const;
  bool is_registered() const { return impl_ != NULL; }

  /// Return true if there are any unpinned pages for this client.
  bool has_unpinned_pages() const;

  std::string DebugString() const;

 private:
  friend class BufferPool;
  friend class BufferPoolTest;
  friend class SubReservation;
  DISALLOW_COPY_AND_ASSIGN(ClientHandle);

  /// Internal state for the client. NULL means the client isn't registered.
  /// Owned by BufferPool.
  Client* impl_;
};

/// Helper class that allows dividing up a client's reservation into separate buckets.
class BufferPool::SubReservation {
 public:
  // Construct without initializing this SubReservation.
  SubReservation();
  // Construct and initialize with 'client' as the parent.
  SubReservation(ClientHandle* client);
  ~SubReservation();

  // Initialize with 'client' as the parent.
  void Init(ClientHandle* client);

  /// Returns the amount of reservation stored in this sub-reservation.
  int64_t GetReservation() const;

  /// Releases the sub-reservation to the client's tracker. Must be called before
  /// destruction if this was initialized.
  void Close();

  bool is_closed() const { return tracker_ == nullptr; }

 private:
  friend class BufferPool::ClientHandle;
  DISALLOW_COPY_AND_ASSIGN(SubReservation);

  /// Child of the client's tracker used to track the sub-reservation. Usage is not
  /// tracked against this tracker - instead the reservation is always transferred back
  /// to the client's tracker before use.
  boost::scoped_ptr<ReservationTracker> tracker_;
};

/// A handle to a buffer allocated from the buffer pool. Only const methods on
/// BufferHandle are thread-safe. It is not safe to call non-constant BufferHandle
/// methods or BufferPool methods with the BufferHandle as an argument concurrently
/// with any other operations on the BufferHandle.
class BufferPool::BufferHandle {
 public:
  BufferHandle() { Reset(); }
  ~BufferHandle() { DCHECK(!is_open()); }

  /// Allow move construction of handles to support std::move(). Inline to make moving
  /// efficient.
  inline BufferHandle(BufferHandle&& src);

  /// Allow move assignment of handles to support STL classes like std::vector.
  /// Destination must be uninitialized. Inline to make moving efficient.
  inline BufferHandle& operator=(BufferHandle&& src);

  bool is_open() const { return data_ != NULL; }
  int64_t len() const {
    DCHECK(is_open());
    return len_;
  }
  /// Get a pointer to the start of the buffer.
  uint8_t* data() const {
    DCHECK(is_open());
    return data_;
  }

  MemRange mem_range() const { return MemRange(data(), len()); }

  std::string DebugString() const;

  /// Poison the memory associated with this handle. If ASAN is not enabled, this is a
  /// no-op.
  void Poison() { ASAN_POISON_MEMORY_REGION(data(), len()); }

  /// Unpoison the memory associated with this handle. If ASAN is not enabled, this is a
  /// no-op.
  void Unpoison() { ASAN_UNPOISON_MEMORY_REGION(data(), len()); }

 private:
  DISALLOW_COPY_AND_ASSIGN(BufferHandle);
  friend class BufferPool;
  friend class SystemAllocator;

  /// Internal helper to set the handle to an opened state.
  void Open(uint8_t* data, int64_t len, int home_core);

  /// Internal helper to reset the handle to an unopened state. Inlined to make moving
  /// efficient.
  inline void Reset();

  /// The client the buffer handle belongs to, used to validate that the correct client
  /// is provided in BufferPool method calls. Set to NULL if the buffer is in a free list.
  const ClientHandle* client_;

  /// Pointer to the start of the buffer. Non-NULL if open, NULL if closed.
  uint8_t* data_;

  /// Length of the buffer in bytes.
  int64_t len_;

  /// The CPU core that the buffer was allocated from - used to determine which arena
  /// it will be added to.
  int home_core_;
};

/// The handle for a page used by clients of the BufferPool. Only const methods on
/// PageHandle are thread-safe. It is not safe to call non-constant PageHandle
/// methods or BufferPool methods with the PageHandle as an argument concurrently
/// with any other operations on the PageHandle.
class BufferPool::PageHandle {
 public:
  PageHandle();
  ~PageHandle() { DCHECK(!is_open()); }

  // Allow move construction of page handles, to support std::move().
  PageHandle(PageHandle&& src);

  // Allow move assignment of page handles, to support STL classes like std::vector.
  // Destination must be closed.
  PageHandle& operator=(PageHandle&& src);

  bool is_open() const { return page_ != NULL; }
  bool is_pinned() const { return pin_count() > 0; }
  int pin_count() const;
  int64_t len() const;

  /// Get a reference to the page's buffer handle. Only valid to call if the page is
  /// pinned. If the page was previously unpinned and the read I/O for the data is still
  /// in flight, this can block waiting. Returns an error if an error was encountered
  /// reading the data back, which can only happen if Unpin() was called on the page
  /// since the last call to GetBuffer(). Only const accessors of the returned handle can
  /// be used: it is invalid to call FreeBuffer() or TransferBuffer() on it or to
  /// otherwise modify the handle.
  ///
  /// This is safe to call from multiple threads at the same time as long as the
  /// page is pinned.
  Status GetBuffer(const BufferHandle** buffer_handle) const WARN_UNUSED_RESULT;

  std::string DebugString() const;

 private:
  DISALLOW_COPY_AND_ASSIGN(PageHandle);
  friend class BufferPool;
  friend class BufferPoolTest;
  friend struct Page;

  /// Internal helper to open the handle for the given page.
  void Open(Page* page, ClientHandle* client);

  /// Internal helper to reset the handle to an unopened state.
  void Reset();

  /// The internal page structure. NULL if the handle is not open.
  Page* page_;

  /// The client the page handle belongs to.
  ClientHandle* client_;
};

inline BufferPool::BufferHandle::BufferHandle(BufferHandle&& src) {
  Reset();
  *this = std::move(src);
}

inline BufferPool::BufferHandle& BufferPool::BufferHandle::operator=(
    BufferHandle&& src) {
  DCHECK(!is_open());
  // Copy over all members then close src.
  client_ = src.client_;
  data_ = src.data_;
  len_ = src.len_;
  home_core_ = src.home_core_;
  src.Reset();
  return *this;
}

inline void BufferPool::BufferHandle::Reset() {
  client_ = NULL;
  data_ = NULL;
  len_ = -1;
  home_core_ = -1;
}
}

#endif
