// 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 <vector>
#include <boost/scoped_ptr.hpp>
#include <boost/thread/locks.hpp>

#include "common/atomic.h"
#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 "runtime/tmp-file-mgr.h"
#include "util/aligned-new.h"
#include "util/internal-queue.h"
#include "util/mem-range.h"
#include "util/spinlock.h"

namespace impala {

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

/// 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, TmpFileMgr::FileGroup* 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;

 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'.
  void RestoreReservation(SubReservation* src, int64_t bytes);

  /// 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().
  bool TransferReservationTo(ReservationTracker* dst, int64_t bytes);

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

  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. Each BufferHandle should only
/// be used by a single thread at a time: concurrently calling BufferHandle methods or
/// BufferPool methods with the BufferHandle as an argument is not supported.
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. Each PageHandle should
/// only be used by a single thread at a time: concurrently calling PageHandle methods
/// or BufferPool methods with the PageHandle as an argument is not supported.
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.
  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
