diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeys.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeys.java
index 7575496..f9ae20a 100644
--- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeys.java
+++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeys.java
@@ -293,4 +293,7 @@
   public static final String NFS_EXPORTS_ALLOWED_HOSTS_SEPARATOR = ";";
   public static final String NFS_EXPORTS_ALLOWED_HOSTS_KEY = "nfs.exports.allowed.hosts";
   public static final String NFS_EXPORTS_ALLOWED_HOSTS_KEY_DEFAULT = "* rw";
+
+  public static final String HADOOP_MEMORY_MANAGER_KEY = "hadoop.memory.manager";
+  public static final String HADOOP_MEMORY_MANAGER_DEFAULT = "org.apache.hadoop.util.offheap.NativeMemoryManager";
 }
diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/offheap/ByteArrayMemoryManager.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/offheap/ByteArrayMemoryManager.java
new file mode 100644
index 0000000..57c7c76
--- /dev/null
+++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/offheap/ByteArrayMemoryManager.java
@@ -0,0 +1,272 @@
+/**
+ * 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.
+ */
+
+package org.apache.hadoop.util.offheap;
+
+import java.io.IOException;
+import java.lang.Long;
+import java.lang.RuntimeException;
+import java.util.Iterator;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+import org.apache.hadoop.classification.InterfaceAudience.Private;
+import org.apache.hadoop.classification.InterfaceStability.Unstable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * ByteArrayMemoryManager is a memory manager which keeps all memory on the Java
+ * heap.  It is useful for testing, since it peforms validation of all memory
+ * accesses and writes.  It also can be used if sun.misc.Unsafe is not
+ * available, although its performance will be less than that of the off-heap
+ * code.
+ */
+@Private
+@Unstable
+public class ByteArrayMemoryManager implements MemoryManager {
+  static final Logger LOG =
+      LoggerFactory.getLogger(ByteArrayMemoryManager.class);
+
+  private final static long MAX_ADDRESS = 0x3fffffffffffffffL;
+
+  private final TreeMap<Long, byte[]> buffers = new TreeMap<Long, byte[]>();
+
+  private long curAddress = 1000;
+
+  private final String name;
+
+  public ByteArrayMemoryManager(String name) {
+    this.name = name;
+    LOG.debug("Created {}.", this);
+  }
+
+  @Override
+  public synchronized void close() throws IOException {
+    Iterator<Entry<Long, byte[]>> iter = buffers.entrySet().iterator();
+    if (iter.hasNext()) {
+      StringBuilder bld = new StringBuilder();
+      Entry<Long, byte[]> entry = iter.next();
+      bld.append(entryToString(entry));
+      int numPrinted = 1;
+      while (iter.hasNext()) {
+        if (numPrinted >= 10) {
+          bld.append("...");
+          break;
+        }
+        bld.append(", ").append(entryToString(entry));
+        numPrinted++;
+      }
+      throw new RuntimeException("There are still unfreed buffers.  " +
+          bld.toString());
+    }
+    LOG.debug("Closed {}.", this);
+  }
+
+  private static String entryToString(Entry<Long, byte[]> entry) {
+    StringBuilder bld = new StringBuilder();
+    bld.append("Entry(base=0x").append(Long.toHexString(entry.getKey())).
+        append(", len=0x").append(Long.toHexString(entry.getValue().length)).
+        append(")");
+    return bld.toString();
+  }
+
+  @Override
+  public synchronized long allocate(long size) {
+    if (curAddress + size > MAX_ADDRESS) {
+      throw new RuntimeException("Cannot allocate any more memory.");
+    }
+    if (size > 0x7fffffff) {
+      throw new RuntimeException("Attempted to allocate " + size +
+          " bytes, but we cannot allocate a Java byte array with " +
+          "more than 2^^31 entries.");
+    }
+    long addr = curAddress;
+    curAddress += size;
+    byte val[] = new byte[(int)size];
+    buffers.put(Long.valueOf(addr), val);
+    LOG.trace("Allocated Entry(base=0x{}, len=0x{})",
+        Long.toHexString(addr), Long.toHexString(val.length));
+    return addr;
+  }
+
+  @Override
+  public synchronized long allocateZeroed(long size) {
+    // Java byte arrays are always zeroed on construction.
+    return allocate(size);
+  }
+
+  @Override
+  public synchronized void free(long addr) {
+    byte val[] =  buffers.remove(Long.valueOf(addr));
+    if (val == null) {
+      LOG.error("Attempted to free unallocated address 0x{}",
+          Long.toHexString(addr));
+    } else {
+      LOG.trace("Freed Entry(base=0x{}, len=0x{})",
+          Long.toHexString(addr), Long.toHexString(val.length));
+    }
+  }
+
+  private synchronized Entry<Long, byte[]> getEntry(long addr, String op) {
+    Entry<Long, byte[]> entry = buffers.floorEntry(Long.valueOf(addr));
+    if (entry == null) {
+      throw new RuntimeException(op + " unallocated address 0x" +
+          Long.toHexString(addr));
+    }
+    return entry;
+  }
+
+  @Override
+  public synchronized byte getByte(long addr) {
+    Entry<Long, byte[]> entry = getEntry(addr, "Accessed");
+    long off = addr - entry.getKey();
+    byte arr[] = entry.getValue();
+    if (off + 1 > arr.length) {
+      throw new RuntimeException("Attempted to read unallocated memory " +
+          "at 0x" + Long.toHexString(addr) + ".  Closest lower allocated area " +
+          "is " + entryToString(entry));
+    }
+    int i = (int)off;
+    return arr[i];
+  }
+
+  @Override
+  public void putByte(long addr, byte val) {
+    Entry<Long, byte[]> entry = getEntry(addr, "Wrote to");
+    long off = addr - entry.getKey();
+    byte arr[] = entry.getValue();
+    if (off + 1 > arr.length) {
+      throw new RuntimeException("Attempted to write to unallocated memory " +
+          "at 0x" + Long.toHexString(addr) + ".  Closest lower allocated area " +
+          "is " + entryToString(entry));
+    }
+    int i = (int)off;
+    arr[i] = val;
+  }
+
+  @Override
+  public synchronized short getShort(long addr) {
+    Entry<Long, byte[]> entry = getEntry(addr, "Accessed");
+    long off = addr - entry.getKey();
+    byte arr[] = entry.getValue();
+    if (off + 2 > arr.length) {
+      throw new RuntimeException("Attempted to read unallocated memory " +
+          "at 0x" + Long.toHexString(addr) + ".  Closest lower allocated " +
+          "area is " + entryToString(entry));
+    }
+    int i = (int)off;
+    return (short)((arr[i + 0] & 0xff) << 8 |
+        (arr[i + 1] & 0xff));
+  }
+
+  @Override
+  public void putShort(long addr, short val) {
+    Entry<Long, byte[]> entry = getEntry(addr, "Wrote to");
+    long off = addr - entry.getKey();
+    byte arr[] = entry.getValue();
+    if (off + 2 > arr.length) {
+      throw new RuntimeException("Attempted to write to unallocated memory " +
+          "at 0x" + Long.toHexString(addr) + ".  Closest lower allocated " +
+          "area is " + entryToString(entry));
+    }
+    int i = (int)off;
+    arr[i + 0] = (byte)((val >> 8) & 0xff);
+    arr[i + 1] = (byte)(val & 0xff);
+  }
+
+  @Override
+  public int getInt(long addr) {
+    Entry<Long, byte[]> entry = getEntry(addr, "Accessed");
+    long off = addr - entry.getKey();
+    byte arr[] = entry.getValue();
+    if (off + 4 > arr.length) {
+      throw new RuntimeException("Attempted to read unallocated memory " +
+          "at 0x" + Long.toHexString(addr) + ".  Closest lower allocated " +
+          "area is " + entryToString(entry));
+    }
+    int i = (int)off;
+    return arr[i + 0] << 24 | 
+           (arr[i + 1] & 0xff) << 16 |
+           (arr[i + 2] & 0xff) << 8 |
+           (arr[i + 3] & 0xff);
+  }
+
+  @Override
+  public void putInt(long addr, int val) {
+    Entry<Long, byte[]> entry = getEntry(addr, "Wrote to");
+    long off = addr - entry.getKey();
+    byte arr[] = entry.getValue();
+    if (off + 4 > arr.length) {
+      throw new RuntimeException("Attempted to write to unallocated memory " +
+          "at 0x" + Long.toHexString(addr) + ".  Closest lower allocated " +
+          "area is " + entryToString(entry));
+    }
+    int i = (int)off;
+    arr[i + 0] = (byte)((val >> 24) & 0xff);
+    arr[i + 1] = (byte)((val >> 16) & 0xff);
+    arr[i + 2] = (byte)((val >> 8) & 0xff);
+    arr[i + 3] = (byte)(val & 0xff);
+  }
+
+  @Override
+  public long getLong(long addr) {
+    Entry<Long, byte[]> entry = getEntry(addr, "Accessed");
+    long off = addr - entry.getKey();
+    byte arr[] = entry.getValue();
+    if (off + 8 > arr.length) {
+      throw new RuntimeException("Attempted to read unallocated memory " +
+          "at 0x" + Long.toHexString(addr) + ".  Closest lower allocated " +
+          "area is " + entryToString(entry));
+    }
+    int i = (int)off;
+    return (arr[i + 0] & 0xffL) << 56 |
+           (arr[i + 1] & 0xffL) << 48 |
+           (arr[i + 2] & 0xffL) << 40 |
+           (arr[i + 3] & 0xffL) << 32 |
+           (arr[i + 4] & 0xffL) << 24 |
+           (arr[i + 5] & 0xffL) << 16 |
+           (arr[i + 6] & 0xffL) << 8 |
+           (arr[i + 7] & 0xffL);
+  }
+
+  @Override
+  public void putLong(long addr, long val) {
+    Entry<Long, byte[]> entry = getEntry(addr, "Wrote to");
+    long off = addr - entry.getKey();
+    byte arr[] = entry.getValue();
+    if (off + 8 > arr.length) {
+      throw new RuntimeException("Attempted to write to unallocated memory " +
+          "at 0x" + Long.toHexString(addr) + ".  Closest lower allocated " +
+          "area is " + entryToString(entry));
+    }
+    int i = (int)off;
+    arr[i + 0] = (byte)((val >> 56) & 0xff);
+    arr[i + 1] = (byte)((val >> 48) & 0xff);
+    arr[i + 2] = (byte)((val >> 40) & 0xff);
+    arr[i + 3] = (byte)((val >> 32) & 0xff);
+    arr[i + 4] = (byte)((val >> 24) & 0xff);
+    arr[i + 5] = (byte)((val >> 16) & 0xff);
+    arr[i + 6] = (byte)((val >> 8) & 0xff);
+    arr[i + 7] = (byte)(val & 0xff);
+  }
+
+  @Override
+  public String toString() {
+    return "ByteArrayMemoryManager(" + name + ")";
+  }
+}
diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/offheap/MemoryManager.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/offheap/MemoryManager.java
new file mode 100644
index 0000000..24c67fc
--- /dev/null
+++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/offheap/MemoryManager.java
@@ -0,0 +1,107 @@
+/**
+ * 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.
+ */
+
+package org.apache.hadoop.util.offheap;
+
+import java.io.Closeable;
+import java.lang.Class;
+
+import org.apache.hadoop.classification.InterfaceAudience.Private;
+import org.apache.hadoop.classification.InterfaceStability.Unstable;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.CommonConfigurationKeys;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Allocates memory which may be off-heap.
+ *
+ * MemoryManager objects are thread-safe.  They can be used by multiple threads
+ * at once without additional synchronization.
+ */
+@Private
+@Unstable
+public interface MemoryManager extends Closeable {
+  /**
+   * Allocate a memory region.  Will never return 0.
+   */
+  long allocate(long size);
+
+  /**
+   * Allocate a zeroed memory region.  Will never return 0.
+   */
+  long allocateZeroed(long size);
+
+  /**
+   * Free memory.
+   */
+  void free(long addr);
+
+  byte getByte(long addr);
+
+  void putByte(long addr, byte val);
+
+  short getShort(long addr);
+
+  void putShort(long addr, short val);
+
+  int getInt(long addr);
+
+  void putInt(long addr, int val);
+
+  long getLong(long addr);
+
+  void putLong(long addr, long val);
+
+  String toString();
+
+  public static class Factory {
+    private static final Logger LOG = LoggerFactory.getLogger(Factory.class);
+
+    /**
+     * Create a MemoryManager from a Configuration.
+     *
+     * @param conf      The Configuration
+     *
+     * @return          The MemoryManager.
+     */
+    public static MemoryManager create(String name, Configuration conf) {
+      String memoryManagerKey = conf.get(
+          CommonConfigurationKeys.HADOOP_MEMORY_MANAGER_KEY,
+          CommonConfigurationKeys.HADOOP_MEMORY_MANAGER_DEFAULT);
+      if (memoryManagerKey == null) {
+        memoryManagerKey = NativeMemoryManager.class.getCanonicalName();
+      }
+      Class<? extends MemoryManager> clazz =
+          (Class<? extends MemoryManager>)conf.
+              getClassByNameOrNull(memoryManagerKey);
+      if (clazz == null) {
+        LOG.error("Unable to locate {}: falling back on {}.",
+            memoryManagerKey, ByteArrayMemoryManager.class.getCanonicalName());
+      } else if (clazz != ByteArrayMemoryManager.class) {
+        try {
+          return clazz.getConstructor(String.class).newInstance(name);
+        } catch (Throwable t) {
+          LOG.error("Unable to create {}.  Falling back on {}", memoryManagerKey,
+              ByteArrayMemoryManager.class.getCanonicalName(), t);
+        }
+      }
+      return new ByteArrayMemoryManager(name);
+    }
+  }
+}
diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/offheap/NativeMemoryManager.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/offheap/NativeMemoryManager.java
new file mode 100644
index 0000000..17a77e6
--- /dev/null
+++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/offheap/NativeMemoryManager.java
@@ -0,0 +1,143 @@
+/**
+ * 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.
+ */
+
+package org.apache.hadoop.util.offheap;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.Throwable;
+import org.apache.hadoop.classification.InterfaceAudience.Private;
+import org.apache.hadoop.classification.InterfaceStability.Unstable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import sun.misc.Unsafe;
+
+/**
+ * NativeMemoryManager is a memory manager which uses sun.misc.Unsafe to
+ * allocate memory off-heap.  This memory will be allocated using the current
+ * platform's equivalent of malloc().
+ */
+@Private
+@Unstable
+public class NativeMemoryManager implements MemoryManager {
+  static final Logger LOG =
+      LoggerFactory.getLogger(NativeMemoryManager.class);
+
+  private final static Unsafe unsafe;
+
+  private final static String loadingFailureReason;
+
+  static {
+    Unsafe myUnsafe = null;
+    String myLoadingFailureReason = null;
+    try {
+      Field f = Unsafe.class.getDeclaredField("theUnsafe");
+      f.setAccessible(true);
+      myUnsafe = (Unsafe)f.get(null);
+    } catch (Throwable e) {
+      myLoadingFailureReason = e.getMessage();
+    } finally {
+      unsafe = myUnsafe;
+      loadingFailureReason = myLoadingFailureReason;
+    }
+  }
+
+  private final String name;
+
+  public static boolean isAvailable() {
+    return loadingFailureReason == null;
+  }
+
+  public NativeMemoryManager(String name) {
+    if (loadingFailureReason != null) {
+      LOG.error("Failed to load sun.misc.Unsafe: " + loadingFailureReason);
+      throw new RuntimeException("Failed to load sun.misc.Unsafe: " +
+          loadingFailureReason);
+    }
+    this.name = name;
+    LOG.debug("Created {}.", this);
+  }
+
+  @Override
+  public void close() throws IOException {
+    // Nothing to do
+    LOG.debug("Closed {}.", this);
+  }
+
+  @Override
+  public long allocate(long size) {
+    return unsafe.allocateMemory(size);
+  }
+
+  @Override
+  public long allocateZeroed(long size) {
+    long addr = unsafe.allocateMemory(size);
+    unsafe.setMemory(addr, size, (byte)0);
+    return addr;
+  }
+
+  @Override
+  public void free(long addr) {
+    unsafe.freeMemory(addr);
+  }
+
+  @Override
+  public byte getByte(long addr) {
+    return unsafe.getByte(null, addr);
+  }
+
+  @Override
+  public void putByte(long addr, byte val) {
+    unsafe.putByte(null, addr, val);
+  }
+
+  @Override
+  public short getShort(long addr) {
+    return unsafe.getShort(null, addr);
+  }
+
+  @Override
+  public void putShort(long addr, short val) {
+    unsafe.putShort(addr, val);
+  }
+
+    @Override
+  public int getInt(long addr) {
+    return unsafe.getInt(null, addr);
+  }
+
+  @Override
+  public void putInt(long addr, int val) {
+    unsafe.putInt(null, addr, val);
+  }
+
+  @Override
+  public long getLong(long addr) {
+    return unsafe.getLong(null, addr);
+  }
+
+  @Override
+  public void putLong(long addr, long val) {
+    unsafe.putLong(null, addr, val);
+  }
+
+  @Override
+  public String toString() {
+    return "NativeMemoryManager(" + name + ")";
+  }
+}
diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/offheap/ProbingHashTable.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/offheap/ProbingHashTable.java
new file mode 100644
index 0000000..d0ac2f8
--- /dev/null
+++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/offheap/ProbingHashTable.java
@@ -0,0 +1,636 @@
+/**
+ * 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.
+ */
+
+package org.apache.hadoop.util.offheap;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import com.google.common.base.Preconditions;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.classification.InterfaceAudience.Public;
+import org.apache.hadoop.classification.InterfaceStability.Unstable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A hash table which can be off-heaped and uses probing.<p/>
+ *
+ * Not thread-safe.  Requires external synchronization.<p/>
+ *
+ * Each entry must be stored in a slot which takes a fixed number of bytes.  We
+ * assume that slots which are zeroed are empty.<p/>
+ *
+ * This hash table does not implement the Java collection interface, because we
+ * want to avoid some of the limitations of that interface.  For example, we
+ * want to be able to have more than 2^^32 entries and to be able to use a hash
+ * function which is wider than 32 bits.<p/>
+ *
+ * This hash table uses linear probing rather than separate chaining to handle
+ * hash collisions.  When we hit a collision when inserting, we put the new
+ * element into the next open slot.<p/>
+ *
+ * When the hash table gets more than a certain percent full, we double the size
+ * of the table.  This requires moving all existing entries.<p/>
+ */
+@Public
+@Unstable
+public class ProbingHashTable<K extends ProbingHashTable.Key,
+      E extends ProbingHashTable.Entry<K>> implements Closeable {
+  static final Logger LOG =
+      LoggerFactory.getLogger(ProbingHashTable.class);
+
+  /**
+   * Adapts a given entry class to work with this hash table.<p/>
+   *
+   * Specifically, the Adaptor handles storing elements into slots,
+   * retrieving them, clearing slots, and getting the hash code for entries.<p/>
+   */
+  public interface Adaptor<E> {
+    /**
+     * Get the slot size to use for this hash table.
+     *
+     * @return            How many bytes each slot is in the hash table.
+     */
+    int getSlotSize();
+
+    /**
+     * Load an entry from memory.
+     *
+     * @param addr        The address to use to create the entry.
+     *
+     * @return            null if the slot was empty; the entry, otherwise.
+     */
+    E load(long addr);
+
+    /**
+     * Store an entry to memory.
+     *
+     * @param e           The element to store to memory.
+     * @param addr        The address to store the element to.
+     */
+    void store(E e, long addr);
+
+    /**
+     * Clear a slot.
+     *
+     * @param addr        The address to clear.
+     */
+    void clear(long addr);
+  }
+
+  public interface Key {
+    /**
+     * Get a 64-bit hash code for this key.
+     */
+    long longHash();
+
+    /**
+     * Determine if this key equals another key.
+     */
+    boolean equals(Object other);
+
+    /**
+     * Get a human-readable representation of this key.
+     */
+    String toString();
+  }
+
+  /**
+   * An entry in the ProbingHashTable.
+   */
+  public interface Entry<K extends Key> {
+    /**
+     * Get the key for this entry.
+     */
+    K getKey();
+  }
+
+  /**
+   * The minimum size to allow.
+   */
+  private static long MIN_SIZE = 4;
+
+  /**
+   * The name of this hash table.
+   */
+  private final String name;
+
+  /**
+   * The memory manager for this hash table.
+   */
+  private final MemoryManager mman;
+
+  /**
+   * The size of each slot in bytes.
+   */
+  private final int slotSize;
+
+  /**
+   * The adaptor to use.
+   */
+  private final Adaptor<E> adaptor;
+
+  /**
+   * The base address of the hash table.
+   */
+  private long base;
+
+  /**
+   * The current number of slots in the hash table.
+   */
+  private long numSlots;
+
+  /**
+   * The current number of entries in the hash table.
+   */
+  private long numEntries;
+
+  /**
+   * The maximum load factor for this hash table.
+   */
+  private float maxLoadFactor;
+
+  /**
+   * The number of entries we should double at.
+   */
+  private long expansionThreshold;
+
+  public static long roundUpToPowerOf2(long i) {
+    long r = 1;
+    while (r < i) {
+      r = r << 1;
+    }
+    return r;
+  }
+
+  /**
+   * Create a new ProbingHashTable.
+   *
+   * @param name              The name of the ProbingHashTable.
+   * @param mman              The memory manager to use.
+   * @param adaptor           The entry factory to use.
+   * @param initialSize       The initial size of the hash table (in number of
+   *                              slots, not elements.)  Will be rounded up to a
+   *                              power of 2.
+   * @param maxLoadFactor     The maximum load factor to allow before doubling
+   *                              the hash table size.
+   */
+  public ProbingHashTable(String name, MemoryManager mman, Adaptor<E> adaptor,
+                        long initialSize, float maxLoadFactor) {
+    this.name = name;
+    this.mman = mman;
+    this.slotSize = adaptor.getSlotSize();
+    this.adaptor = adaptor;
+    if (initialSize < MIN_SIZE) {
+      initialSize = MIN_SIZE;
+    }
+    this.numSlots = roundUpToPowerOf2((long)(initialSize / maxLoadFactor));
+    long allocLen = numSlots * slotSize;
+    this.base = mman.allocateZeroed(allocLen);
+    this.numEntries = 0;
+    this.maxLoadFactor = maxLoadFactor;
+    this.expansionThreshold = (long)(numSlots * maxLoadFactor);
+    LOG.debug("Created ProbingHashTable(name={}, mman={}, slotSize={}, " +
+          "adaptor={}, numSlots={}, base=0x{}, allocLen=0x{}," +
+          "maxLoadFactor={}, expansionThreshold={})",
+          name, mman.toString(), slotSize,
+          adaptor.getClass().getCanonicalName(), numSlots,
+          Long.toHexString(base), Long.toHexString(allocLen), maxLoadFactor,
+          expansionThreshold);
+    Preconditions.checkArgument(maxLoadFactor > 0.0f);
+    Preconditions.checkArgument(maxLoadFactor < 1.0f);
+  }
+
+  /**
+   * Frees the memory associated with this hash table and does error checking.
+   */
+  public void close() throws IOException {
+    ProbingHashTableIterator iter = iterator();
+    if (iter.hasNext()) {
+      StringBuilder bld = new StringBuilder();
+      K k = iter.next();
+      bld.append(k.toString());
+      int numPrinted = 1;
+      while (iter.hasNext()) {
+        if (numPrinted >= 10) {
+          bld.append("...");
+          break;
+        }
+        bld.append(", ").append(iter.next().toString());
+        numPrinted++;
+      }
+      throw new RuntimeException("Attempted to close the hash table " +
+          " before all entries were removed.  There are still " + numEntries +
+          " entries remaining, including " + bld.toString());
+    }
+    free();
+  }
+
+  /**
+   * Frees the memory associated with this hash table.
+   */
+  void free() throws IOException {
+    if (this.base != 0) {
+      LOG.debug("Freeing {}.", this);
+      mman.free(this.base);
+      this.base = 0;
+    }
+  }
+
+  protected void finalize() throws Throwable {
+    try {
+      if (this.base != 0) {
+        LOG.error("Hash table {} was never closed.", this);
+        free();
+      }
+    } finally {
+      super.finalize();
+    }
+  }
+
+  private long getSlot(K key, long nSlots) {
+    long hash = key.longHash();
+    if (hash < 0) {
+      hash = -hash;
+    }
+    return hash % nSlots;
+  }
+
+  private E getInternal(K key, boolean remove) {
+    long originalSlot = getSlot(key, numSlots);
+    long slot = originalSlot;
+    long addr;
+    E target = null;
+    K targetKey = null;
+    while (true) {
+      addr = this.base + (slot * slotSize);
+      target = adaptor.load(addr);
+      if (target == null) {
+        // By the compactness invariant, we're done.  See below for more
+        // discussion.
+        LOG.trace("{}: getInternal(key={}, remove={}) found nothing.",
+            this, key, remove);
+        return null;
+      }
+      targetKey = target.getKey();
+      if (targetKey.equals(key)) {
+        break;
+      }
+      slot++;
+      if (slot == numSlots) {
+        slot = 0;
+      }
+      if (slot == originalSlot) {
+        LOG.trace("{}: getInternal(key={}, remove={}) found nothing",
+            this, key, remove);
+        return null;
+      }
+    }
+    if (remove) {
+      adaptor.clear(addr);
+      numEntries--;
+      maintainCompactness(slot);
+    }
+    LOG.trace("{}: getInternal(key={}, remove={}) found {}",
+        this, key, remove, targetKey);
+    return target;
+  }
+
+  /**
+   * Maintain the compactness invariant.<p/>
+   *
+   * In order to avoid doing a full array search when looking for an element
+   * that may not be in the hash table, we maintain a compactness invariant.
+   * The compactness invariant states that if we start at slot N and continue
+   * searching until we hit an empty slot, we will have searched all the
+   * possible places where the element could be.  We maintain the compactness
+   * invariant by doing a little bit of extra work each time we delete an entry.
+   * Specifically, we search forwards from the deleted entry, moving any keys
+   * that need to be moved to maintain the invariant.  We can stop searching
+   * when we hit an empty slot.<p/>
+   *
+   * Although maintaining the compactness invariant is O(N) in the worst case,
+   * it should be O(1) in the average case.  This is because the hash table is
+   * half empty at all times.  Assuming good hash dispersion, on average every
+   * other slot should be empty.  Therefore, the average number of entries we
+   * move here should be less than 1.<p/>
+   */
+  private void maintainCompactness(long startSlot) {
+    long slot = startSlot;
+    while (true) {
+      slot++;
+      if (slot == numSlots) {
+        slot = 0;
+      }
+      if (slot == startSlot) {
+        return;
+      }
+      long addr = this.base + (slot * slotSize);
+      E e = adaptor.load(addr);
+      if (e == null) {
+        return;
+      }
+      E prevE = putInternal(e, false);
+      if (prevE != null) {
+        if (LOG.isTraceEnabled()) {
+          LOG.trace("{}: {} was already in the right place.",
+              this, e.getKey());
+        }
+      } else {
+        // The put didn't actually add anything, it just moved something.
+        // So decrement numEntries to its previous value.
+        numEntries--;
+        adaptor.clear(addr);
+        if (LOG.isTraceEnabled()) {
+          LOG.trace("{}: moved {} to the right place.",
+              this, e.getKey());
+        }
+      }
+    }
+  }
+
+  public E remove(K key) {
+    return getInternal(key, true);
+  }
+
+  public E get(K key) {
+    return getInternal(key, false);
+  }
+
+  private void expandTable(long newNumSlots) {
+    LOG.info("{}: Expanding table from {} slots to {}...",
+        this, numSlots, newNumSlots);
+    long newBase = mman.allocateZeroed(newNumSlots * slotSize);
+    long oldNumSlots = this.numSlots;
+    long oldExpansionThreshold = this.expansionThreshold;
+    long oldBase = this.base;
+    long oldNumEntries = this.numEntries;
+    try {
+      // Switch the hash table over to using the new memory region.
+      long entriesRemaining = oldNumEntries;
+      this.numSlots = newNumSlots;
+      this.expansionThreshold = (long)(newNumSlots * maxLoadFactor);
+      this.base = newBase;
+      this.numEntries = 0;
+
+      for (long slot = 0; slot < oldNumSlots; slot++) {
+        long addr = oldBase + (slot * slotSize);
+        E e = adaptor.load(addr);
+        if (e != null) {
+          E prevEntry = putInternal(e, false);
+          if (prevEntry != null) {
+            LOG.error("{}: Unexpected duplicate encountered when resizing " +
+                    "hash table: entry {} duplicates {}.", this,
+                e.getKey(), prevEntry.getKey()
+            );
+          }
+          entriesRemaining--;
+        }
+      }
+      if (entriesRemaining != 0) {
+        LOG.error("{}: Unexpectedly failed to locate {} entries that we " +
+                "thought we needed to move when resizing the hash table.",
+            this, entriesRemaining
+        );
+      }
+      LOG.info("{}: Finished expanding hash table from {} slots to {}.  " +
+              "Moved {} keys.  Freed old memory base 0x{}.  Using new memory " +
+              "base 0x{}.", this, oldNumSlots, numSlots, numEntries,
+              Long.toHexString(oldBase), Long.toHexString(newBase));
+    } catch (Throwable t) {
+      // In general we should never get here, since the functions used
+      // above should not throw exceptions.  But it's nice to be safe.
+      LOG.error("{}: expanding failed!  Restoring old memory region.", this, t);
+
+      // Switch back to using the old memory region.
+      this.numSlots = oldNumSlots;
+      this.expansionThreshold = oldExpansionThreshold;
+      this.base = oldBase;
+      this.numEntries = oldNumEntries;
+      mman.free(newBase);
+      throw new RuntimeException("Failed to expand " + this, t);
+    }
+    mman.free(oldBase);
+  }
+
+  /**
+   * Expand the hash table if it would need to expand to hold another key.
+   */
+  private void expandTableIfNeeded() {
+    if (numEntries > expansionThreshold) {
+      expandTable(numSlots * 2L);
+    }
+  }
+
+  /**
+   * Put the entry into the hash table if there is no entry in the hash table
+   * which is equivalent.
+   *
+   * @param putEntry        The entry to add if absent.
+   * @param overwrite       If true, we will overwrite the entry which is equal
+   *                          to putEntry (if there is one.)  If false, we will
+   *                          simply return that entry, but not overwrite it.
+   *
+   * @return                The previous entry in the hash table that was equal
+   *                          to the one we wanted to insert.  null if there
+   *                          was no such entry.
+   */
+  private E putInternal(E putEntry, boolean overwrite) {
+    long slot = getSlot(putEntry.getKey(), numSlots);
+    K putKey = putEntry.getKey();
+
+    while (true) {
+      long addr = this.base + (slot * slotSize);
+      E e = adaptor.load(addr);
+      if (e == null) {
+        adaptor.store(putEntry, addr);
+        numEntries++;
+        if (LOG.isTraceEnabled()) {
+          LOG.trace("{}: stored {} into slot {} (addr 0x{})",
+              this, putKey, slot, Long.toHexString(addr));
+        }
+        return null;
+      }
+      K k = e.getKey();
+      if (k.equals(putKey)) {
+        if (!overwrite) {
+          if (LOG.isTraceEnabled()) {
+            LOG.trace("{}: could not store {} because we found an " +
+                "equivalent key {} in slot {} (addr 0x{})",
+                this, putKey, k, slot, Long.toHexString(addr));
+          }
+          return e;
+        }
+        // Overwrite the existing entry.
+        adaptor.store(putEntry, addr);
+        if (LOG.isTraceEnabled()) {
+          LOG.trace("{}: stored {} by overwriting the equivalent key {} " +
+              "in slot {} (addr 0x{})", this, putKey, k, slot,
+              Long.toHexString(addr));
+        }
+        return e;
+      }
+      slot++;
+      if (slot == numSlots) {
+        slot = 0;
+      }
+    }
+  }
+
+  /**
+   * Put the entry into the hash table if there is no entry in the hash table
+   * which is equivalent.
+   *
+   * @param putEntry    The entry to add.
+   *
+   * @return            Null if the element was inserted.
+   *                      Otherwise, returns the previous element that compares
+   *                      to be the same as the one we unsuccessfully tried to
+   *                      add.
+   */
+  public E putIfAbsent(E putEntry) {
+    expandTableIfNeeded(); // call this first in case it fails (very unlikely)
+    return putInternal(putEntry, false);
+  }
+
+  /**
+   * Put an entry into the hash table, overwriting any existing element
+   * which is equivalent.
+   *
+   * @param putEntry    The entry to add.
+   *
+   * @return            null if there was no element in the table which was
+   *                      equivalent... the existing element which was
+   *                      equivalent, otherwise.  The existing element will
+   *                      be removed.
+   */
+  public E put(E putEntry) {
+    expandTableIfNeeded(); // call this first in case it fails (very unlikely)
+    return putInternal(putEntry, true);
+  }
+
+  /**
+   * Returns the current number of slots in the hash table.
+   */
+  public long numSlots() {
+    return numSlots;
+  }
+
+  /**
+   * Returns the size of the table.
+   */
+  public long size() {
+    return numEntries;
+  }
+
+  /**
+   * Returns true if the table is empty.
+   */
+  public boolean isEmpty() {
+    return numEntries == 0;
+  }
+
+  /**
+   * An iterator for the ProbingHashTable.<p/>
+   *
+   * Since ProbingHashTable has no internal synchronization, you are responsible
+   * for ensuring that there are no concurrent write operations on the hash
+   * table while an iterator function is being called.  The easiest way to do
+   * this is with external locking.<p/>
+   *
+   * You can still perform write operations after creating this iterator
+   * without invalidating the iterator object.  There are a few caveats:<p/>
+   * 1. Keys inserted after the iterator was created may or may not be
+   *    returned by the iterator.<p/>
+   * 2. If the hash table is enlarged due to adding more keys, this iterator
+   *    may return keys more than once, and return some keys not at all.<p/>
+   */
+  private class ProbingHashTableIterator implements Iterator<K> {
+    private long slotId = 0;
+    private K curKey;
+
+    private boolean refillCurKey() {
+      while (slotId < ProbingHashTable.this.numSlots) {
+        long addr = base + (slotId * slotSize);
+        E e = adaptor.load(addr);
+        slotId++;
+        if (e != null) {
+          curKey = e.getKey();
+          if (LOG.isTraceEnabled()) {
+            LOG.trace("{}: iterator found another key {} at slot {} " +
+                  "(address 0x{})", ProbingHashTable.this.toString(), curKey,
+                  (slotId - 1), Long.toHexString(addr));
+          }
+          return true;
+        }
+      }
+      LOG.trace("{}: no more keys to iterate over after reading all {} " +
+                "slots.", ProbingHashTable.this.toString(), slotId);
+      // Set slotId to Long.MAX_VALUE so that even if the hash table enlarges
+      // in the future, this iterator will continue to be at the end.
+      slotId = Long.MAX_VALUE;
+      return false;
+    }
+
+    @Override
+    public boolean hasNext() {
+      if (curKey != null) {
+        return true;
+      }
+      return refillCurKey();
+    }
+
+    @Override
+    public K next() {
+      if (curKey == null) {
+        if (!refillCurKey()) {
+          throw new IllegalStateException();
+        }
+      }
+      K key = curKey;
+      curKey = null;
+      return key;
+    }
+
+    @Override
+    public void remove() {
+      if (curKey == null) {
+        throw new IllegalStateException();
+      }
+      K key = curKey;
+      curKey = null;
+      if (ProbingHashTable.this.remove(key) == null) {
+        throw new NoSuchElementException("No such element as " +
+            key.toString());
+      }
+    }
+  }
+
+  public ProbingHashTableIterator iterator() {
+    return new ProbingHashTableIterator();
+  }
+
+  @Override
+  public String toString() {
+    return "ProbingHashTable(" + name + ")";
+  }
+}
diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/offheap/TestMemoryManager.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/offheap/TestMemoryManager.java
new file mode 100644
index 0000000..6ffd37f
--- /dev/null
+++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/offheap/TestMemoryManager.java
@@ -0,0 +1,202 @@
+/**
+ * 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.
+ */
+
+package org.apache.hadoop.util.offheap;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.CommonConfigurationKeys;
+import org.apache.hadoop.test.GenericTestUtils;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TestMemoryManager {
+  private static final Logger LOG =
+      LoggerFactory.getLogger(TestMemoryManager.class);
+
+  @Test(timeout=60000)
+  public void testAllocateAndFreeOnHeap() throws Exception {
+    ByteArrayMemoryManager mman = new ByteArrayMemoryManager("test");
+    testAllocateAndFree(mman);
+    mman.close();
+  }
+
+  @Test(timeout=60000)
+  public void testAllocateAndFreeOffHeap() throws Exception {
+    Assume.assumeTrue(NativeMemoryManager.isAvailable());
+    NativeMemoryManager mman = new NativeMemoryManager("test");
+    testAllocateAndFree(mman);
+    mman.close();
+  }
+
+  private void testAllocateAndFree(MemoryManager mman) throws Exception {
+    long addr = mman.allocate(100);
+    Assert.assertTrue("Expected addr to be non-zero.", addr != 0);
+    mman.free(addr);
+  }
+
+  @Test(timeout=60000)
+  public void testGetAndSetOnHeap() throws Exception {
+    ByteArrayMemoryManager mman = new ByteArrayMemoryManager("test");
+    testGetAndSet(mman);
+    mman.close();
+  }
+
+  @Test(timeout=60000)
+  public void testGetAndSetOffHeap() throws Exception {
+    Assume.assumeTrue(NativeMemoryManager.isAvailable());
+    NativeMemoryManager mman = new NativeMemoryManager("test");
+    testGetAndSet(mman);
+    mman.close();
+  }
+
+  private void testGetAndSet(MemoryManager mman) throws Exception {
+    LOG.info("testingGetAndSet with " + mman.getClass().getCanonicalName());
+    long byteAddr = mman.allocateZeroed(1);
+    Assert.assertTrue("Expected addr to be non-zero.", byteAddr != 0);
+    byte b = mman.getByte(byteAddr);
+    Assert.assertEquals((byte)0, b);
+    mman.putByte(byteAddr, (byte) 42);
+    b = mman.getByte(byteAddr);
+    Assert.assertEquals((byte)42, b);
+
+    long intAddr = mman.allocateZeroed(4);
+    Assert.assertTrue("Expected addr to be non-zero.", intAddr != 0);
+    int i = mman.getInt(intAddr);
+    Assert.assertEquals(0, i);
+    mman.putInt(intAddr, 0xfea01234);
+    i = mman.getInt(intAddr);
+    Assert.assertEquals(0xfea01234, i);
+
+    long shortAddr = mman.allocateZeroed(2);
+    Assert.assertTrue("Expected addr to be non-zero.", shortAddr != 0);
+    short s = mman.getShort(shortAddr);
+    Assert.assertEquals(0, s);
+    mman.putShort(shortAddr, (short) 0xeecc);
+    s = mman.getShort(shortAddr);
+    Assert.assertEquals((short)0xeecc, s);
+
+    long longAddr = mman.allocateZeroed(8);
+    Assert.assertTrue("Expected addr to be non-zero.", longAddr != 0);
+    long l = mman.getLong(longAddr);
+    Assert.assertEquals(0, l);
+    long testVal = 0x3ea0123400112233L;
+    LOG.info("longAddr = " + longAddr + ", testVal = "  + testVal);
+    mman.putLong(longAddr, testVal);
+    l = mman.getLong(longAddr);
+    LOG.info("got back " + l + " from " + longAddr);
+    Assert.assertEquals(testVal, l);
+
+    mman.free(byteAddr);
+    mman.free(intAddr);
+    mman.free(shortAddr);
+    mman.free(longAddr);
+  }
+
+  @Test(timeout=60000)
+  public void testCatchInvalidPuts() throws Exception {
+    ByteArrayMemoryManager mman = new ByteArrayMemoryManager("test");
+    long addr = mman.allocate(1);
+    mman.putByte(addr, (byte)1); // should succeed
+    try {
+      mman.putInt(addr, 0xdeadbeef);
+      Assert.fail("expected to catch invalid put");
+    } catch (RuntimeException e) {
+    }
+    try {
+      mman.putByte(addr + 1, (byte) 1);
+      Assert.fail("expected to catch invalid put");
+    } catch (RuntimeException e) {
+    }
+    try {
+      mman.putLong(addr, 11111111111L);
+      Assert.fail("expected to catch invalid put");
+    } catch (RuntimeException e) {
+    }
+    mman.free(addr);
+    try {
+      mman.putByte(addr, (byte)1);
+      Assert.fail("expected to catch invalid put");
+    } catch (RuntimeException e) {
+    }
+    try {
+      mman.putShort(addr, (short) 101);
+      Assert.fail("expected to catch invalid put");
+    } catch (RuntimeException e) {
+    }
+    try {
+      mman.putInt(addr + 1, 0xfaceface);
+      Assert.fail("expected to catch invalid put");
+    } catch (RuntimeException e) {
+    }
+    try {
+      mman.putLong(addr, 0xf00L);
+      Assert.fail("expected to catch invalid put");
+    } catch (RuntimeException e) {
+    }
+    mman.close();
+  }
+
+  private void testMemoryManagerCreate(
+      String className, String createdClassName) throws Exception {
+    Configuration conf = new Configuration();
+    conf.set(CommonConfigurationKeys.HADOOP_MEMORY_MANAGER_KEY, className);
+    MemoryManager mman = MemoryManager.Factory.create("test", conf);
+    Assert.assertNotNull(mman);
+    Assert.assertEquals(createdClassName, mman.getClass().getCanonicalName());
+    mman.close();
+  }
+
+  @Test(timeout=60000)
+  public void testByteBufferMemoryManagerCreate() throws Exception {
+    testMemoryManagerCreate(
+        "org.apache.hadoop.util.offheap.ByteArrayMemoryManager",
+        "org.apache.hadoop.util.offheap.ByteArrayMemoryManager");
+  }
+
+  @Test(timeout=60000)
+  public void testNativeMemoryManagerCreate() throws Exception {
+    Assume.assumeTrue(NativeMemoryManager.isAvailable());
+    testMemoryManagerCreate(
+        "org.apache.hadoop.util.offheap.NativeMemoryManager",
+        "org.apache.hadoop.util.offheap.NativeMemoryManager");
+  }
+
+  @Test(timeout=60000)
+  public void testDefaultMemoryManagerCreate() throws Exception {
+    testMemoryManagerCreate(
+        "org.apache.hadoop.util.offheap.NonExistentMemoryManager",
+        "org.apache.hadoop.util.offheap.ByteArrayMemoryManager");
+  }
+
+  @Test(timeout=60000)
+  public void testByteBufferMemoryDirtyClose() throws Exception {
+    ByteArrayMemoryManager mman = new ByteArrayMemoryManager("test");
+    long addr = mman.allocate(1);
+    try {
+      mman.close();
+      Assert.fail("expected close to fail since we did not free all " +
+          "allocations first.");
+    } catch (RuntimeException e) {
+      GenericTestUtils.assertExceptionContains("There are still unfreed " +
+          "buffers", e);
+    }
+  }
+}
diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/offheap/TestProbingHashTable.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/offheap/TestProbingHashTable.java
new file mode 100644
index 0000000..bb68f35
--- /dev/null
+++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/offheap/TestProbingHashTable.java
@@ -0,0 +1,392 @@
+/**
+ * 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.
+ */
+
+package org.apache.hadoop.util.offheap;
+
+import com.google.common.hash.HashFunction;
+import com.google.common.hash.Hashing;
+import org.apache.hadoop.io.IOUtils;
+import org.apache.hadoop.test.GenericTestUtils;
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+
+public class TestProbingHashTable {
+  private static final Logger LOG =
+      LoggerFactory.getLogger(TestProbingHashTable.class);
+
+  @Before
+  public void before() {
+    GenericTestUtils.setLogLevel(ProbingHashTable.LOG, Level.ALL);
+    GenericTestUtils.setLogLevel(NativeMemoryManager.LOG, Level.ALL);
+    GenericTestUtils.setLogLevel(ByteArrayMemoryManager.LOG, Level.ALL);
+  }
+
+  private static class TestBlockId implements ProbingHashTable.Key {
+    private static final HashFunction hashFunction = Hashing.goodFastHash(64);
+
+    private final long id;
+
+    TestBlockId(long id) {
+      this.id = id;
+    }
+
+    @Override
+    public long longHash() {
+      return hashFunction.newHasher().putLong(id).hash().asLong();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (o.getClass() != this.getClass()) {
+        return false;
+      }
+      return id == ((TestBlockId)o).id;
+    }
+
+    @Override
+    public String toString() {
+      return "TestBlockId(0x" + Long.toHexString(id) + ")";
+    }
+
+    // Just for use with java.util.HashMap
+    @Override
+    public int hashCode() {
+      return (int)(id & 0xfffffff) ^ (int)((id >> 32) & 0xffffffff);
+    }
+  }
+
+  private static class TestBlockInfo
+        implements  ProbingHashTable.Entry<TestBlockId>, Closeable {
+    /**
+     * The memory manager to use.
+     */
+    private MemoryManager mman;
+
+    /**
+     * The address of the block reference.
+     */
+    private long addr;
+
+    private static final long BLOCK_ID_OFF = 0;
+
+    private static final long TOTAL_LEN = 8;
+
+    static TestBlockInfo allocZeroed(MemoryManager mman) {
+      long addr = mman.allocateZeroed(TOTAL_LEN);
+      return new TestBlockInfo(mman, addr);
+    }
+
+    TestBlockInfo(MemoryManager mman, long addr) {
+      this.mman = mman;
+      this.addr = addr;
+    }
+
+    public long getBlockId() {
+      return mman.getLong(addr + BLOCK_ID_OFF);
+    }
+
+    public void setBlockId(long blockId) {
+      mman.putLong(addr + BLOCK_ID_OFF, blockId);
+    }
+
+    public void close() throws IOException {
+      mman.free(addr);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (o.getClass() != TestBlockInfo.class) {
+        return false;
+      }
+      TestBlockInfo other = (TestBlockInfo)o;
+      return (other.getBlockId() == getBlockId());
+    }
+
+    @Override
+    public TestBlockId getKey() {
+      return new TestBlockId(getBlockId());
+    }
+  }
+
+  private static class TestBlockInfoAdaptor
+        implements ProbingHashTable.Adaptor<TestBlockInfo> {
+    private final MemoryManager mman;
+
+    TestBlockInfoAdaptor(MemoryManager mman) {
+      this.mman = mman;
+    }
+
+    @Override
+    public int getSlotSize() {
+      return 8;
+    }
+
+    @Override
+    public TestBlockInfo load(long addr) {
+      long infoAddr = mman.getLong(addr);
+      if (infoAddr == 0) {
+        return null;
+      }
+      return new TestBlockInfo(mman, infoAddr);
+    }
+
+    @Override
+    public void store(TestBlockInfo info, long addr) {
+      mman.putLong(addr, info.addr);
+    }
+
+    @Override
+    public void clear(long addr) {
+      mman.putLong(addr, 0L);
+    }
+  }
+
+  private void testAllocateAndFree(MemoryManager mman) throws Exception {
+    TestBlockInfoAdaptor adaptor = new TestBlockInfoAdaptor(mman);
+    ProbingHashTable<TestBlockId, TestBlockInfo> htable =
+        new ProbingHashTable<TestBlockId, TestBlockInfo>(
+            "testAllocateAndFreeTable", mman, adaptor, 100, 0.5f);
+    // should have been rounded up to 256
+    Assert.assertEquals(256, htable.numSlots());
+    htable.close();
+  }
+
+  @Test(timeout=60000)
+  public void testAllocateAndFreeOnHeap() throws Exception {
+    ByteArrayMemoryManager mman = new ByteArrayMemoryManager("test");
+    testAllocateAndFree(mman);
+    mman.close();
+  }
+
+  @Test(timeout=60000)
+  public void testAllocateAndFreeOffHeap() throws Exception {
+    Assume.assumeTrue(NativeMemoryManager.isAvailable());
+    NativeMemoryManager mman = new NativeMemoryManager("test");
+    testAllocateAndFree(mman);
+    mman.close();
+  }
+
+  private static TestBlockInfo[] createBlockInfos(MemoryManager mman,
+                                    int initialBlockId, int numBlocks) {
+    TestBlockInfo infos[] = new TestBlockInfo[numBlocks];
+    boolean success = false;
+    try {
+      for (int i = 0; i < numBlocks; i++) {
+        infos[i] = TestBlockInfo.allocZeroed(mman);
+        infos[i].setBlockId(initialBlockId + i);
+        LOG.info("allocated infos[{}] with id {}", i, infos[i].getBlockId());
+      }
+      success = true;
+      return infos;
+    } finally {
+      if (!success) {
+        freeBlockInfos(infos);
+      }
+    }
+  }
+
+  private static void freeBlockInfos(TestBlockInfo[] infos) {
+    if (infos != null) {
+      for (int i = 0; i < infos.length; i++) {
+        if (infos[i] != null) {
+          IOUtils.cleanup(null, infos[i]);
+        }
+      }
+    }
+  }
+
+  private void testAddRemove(MemoryManager mman) throws Exception {
+    TestBlockInfoAdaptor adaptor = new TestBlockInfoAdaptor(mman);
+    ProbingHashTable<TestBlockId, TestBlockInfo> htable =
+        new ProbingHashTable<TestBlockId, TestBlockInfo>(
+            "testAddRemoveTable", mman, adaptor, 10, 0.5f);
+    TestBlockInfo infos[] = null;
+    Assert.assertEquals(32, htable.numSlots());
+    Assert.assertTrue(htable.isEmpty());
+    Assert.assertEquals(0, htable.size());
+    infos = createBlockInfos(mman, 1, 6);
+    for (int i = 0; i < infos.length; i++) {
+      LOG.info("Putting {} into {}", infos[i].getKey(), htable);
+      TestBlockInfo prev = htable.putIfAbsent(infos[i]);
+      Assert.assertEquals(null, prev);
+    }
+    Assert.assertFalse(htable.isEmpty());
+    Assert.assertEquals(infos.length, htable.size());
+
+    // Test that we can iterate over all elements in the hash table.
+    Iterator<TestBlockId> iter = htable.iterator();
+    Assert.assertNotNull(iter);
+    HashSet<TestBlockId> contents = new HashSet<TestBlockId>();
+    for (TestBlockInfo info : infos) {
+      contents.add(info.getKey());
+    }
+    for (int i = 0; i < infos.length; i++) {
+      Assert.assertTrue(iter.hasNext());
+      TestBlockId blockId = iter.next();
+      Assert.assertTrue("Iterator returned " + blockId + ", which was " +
+          "not inserted into the HashTable.", contents.remove(blockId));
+    }
+    Assert.assertFalse(iter.hasNext());
+    Assert.assertEquals("Did not find " + contents.size() + " entries " +
+        "from the hash table during iteration.", 0, contents.size());
+
+    for (int i = 0; i < infos.length; i++) {
+      LOG.info("Removing {} from {}", infos[i].getKey(), htable);
+      TestBlockInfo prev = htable.remove(infos[i].getKey());
+      Assert.assertNotNull("unable to remove " + infos[i].getKey() +
+          " from the ProbingHashTable.", prev);
+    }
+    Assert.assertTrue(htable.isEmpty());
+    freeBlockInfos(infos);
+    htable.close();
+  }
+
+  @Test(timeout=60000)
+  public void testAddRemoveOnHeap() throws Exception {
+    ByteArrayMemoryManager mman = new ByteArrayMemoryManager("test");
+    testAddRemove(mman);
+    mman.close();
+  }
+
+  @Test(timeout=60000)
+  public void testAddRemoveOffHeap() throws Exception {
+    Assume.assumeTrue(NativeMemoryManager.isAvailable());
+    NativeMemoryManager mman = new NativeMemoryManager("test");
+    testAddRemove(mman);
+    mman.close();
+  }
+
+  private void testEnlargeHashTable(MemoryManager mman) throws Exception {
+    TestBlockInfoAdaptor adaptor = new TestBlockInfoAdaptor(mman);
+    ProbingHashTable<TestBlockId, TestBlockInfo> htable =
+        new ProbingHashTable<TestBlockId, TestBlockInfo>(
+            "testEnlargeHashTable", mman, adaptor, 4, 0.5f);
+    TestBlockInfo infos[] = null;
+    Assert.assertEquals(8, htable.numSlots());
+    Assert.assertTrue(htable.isEmpty());
+    Assert.assertEquals(0, htable.size());
+    infos = createBlockInfos(mman, 1, 33);
+    for (int i = 0; i < 4; i++) {
+      LOG.info("Putting {} into {}", infos[i].getKey(), htable);
+      TestBlockInfo prev = htable.putIfAbsent(infos[i]);
+      Assert.assertEquals(null, prev);
+    }
+    Assert.assertEquals(8, htable.numSlots());
+    Assert.assertFalse(htable.isEmpty());
+    Assert.assertEquals(4, htable.size());
+    for (int i = 4; i < 8; i++) {
+      LOG.info("Putting {} into {}", infos[i].getKey(), htable);
+      TestBlockInfo prev = htable.putIfAbsent(infos[i]);
+      Assert.assertEquals(null, prev);
+    }
+    Assert.assertEquals(16, htable.numSlots());
+    Assert.assertFalse(htable.isEmpty());
+    Assert.assertEquals(8, htable.size());
+
+    for (int i = 8; i < 16; i++) {
+      LOG.info("Putting {} into {}", infos[i].getKey(), htable);
+      TestBlockInfo prev = htable.putIfAbsent(infos[i]);
+      Assert.assertEquals(null, prev);
+    }
+    Assert.assertEquals(32, htable.numSlots());
+    Assert.assertFalse(htable.isEmpty());
+    Assert.assertEquals(16, htable.size());
+
+    for (int i = 16; i < infos.length; i++) {
+      LOG.info("Putting {} into {}", infos[i].getKey(), htable);
+      TestBlockInfo prev = htable.putIfAbsent(infos[i]);
+      Assert.assertEquals(null, prev);
+    }
+    Assert.assertEquals(64, htable.numSlots());
+    Assert.assertFalse(htable.isEmpty());
+    Assert.assertEquals(33, htable.size());
+
+    // Delete every other element
+    for (int i = 0; i < infos.length; i+=2) {
+      LOG.info("Removing {} from {}", infos[i].getKey(), htable);
+      TestBlockInfo prev = htable.remove(infos[i].getKey());
+      Assert.assertNotNull("unable to remove " + infos[i].getKey() +
+          " from the ProbingHashTable.", prev);
+    }
+    Assert.assertEquals(64, htable.numSlots());
+    Assert.assertFalse(htable.isEmpty());
+    Assert.assertEquals(16, htable.size());
+
+    // Test that we can iterate over all remaining elements in the hash set.
+    Iterator<TestBlockId> iter = htable.iterator();
+    Assert.assertNotNull(iter);
+    HashSet<TestBlockId> contents = new HashSet<TestBlockId>();
+    for (int i = 1; i < infos.length; i+=2) {
+      contents.add(infos[i].getKey());
+    }
+    for (int i = 1; i < infos.length; i+=2) {
+      Assert.assertTrue(iter.hasNext());
+      TestBlockId blockId = iter.next();
+      Assert.assertTrue("Iterator returned " + blockId + ", which was " +
+          "not inserted into the HashTable.", contents.remove(blockId));
+    }
+    Assert.assertFalse(iter.hasNext());
+    Assert.assertEquals("Did not find " + contents.size() + " entries " +
+        "from the hash table during iteration.", 0, contents.size());
+
+    // Delete remaining elements
+    for (int i = 1; i < infos.length; i+=2) {
+      LOG.info("Removing {} from {}", infos[i].getKey(), htable);
+      TestBlockInfo prev = htable.remove(infos[i].getKey());
+      Assert.assertNotNull("unable to remove " + infos[i].getKey() +
+          " from the ProbingHashTable.", prev);
+    }
+    Assert.assertEquals(64, htable.numSlots());
+    Assert.assertTrue(htable.isEmpty());
+    Assert.assertEquals(0, htable.size());
+
+    iter = htable.iterator();
+    Assert.assertNotNull(iter);
+    Assert.assertFalse(iter.hasNext());
+
+    freeBlockInfos(infos);
+    htable.close();
+  }
+
+  @Test(timeout=60000)
+  public void testEnlargeHashTableOnHeap() throws Exception {
+    ByteArrayMemoryManager mman = new ByteArrayMemoryManager("test");
+    testEnlargeHashTable(mman);
+    mman.close();
+  }
+
+  @Test(timeout=60000)
+  public void testEnlargeHashTableOffHeap() throws Exception {
+    Assume.assumeTrue(NativeMemoryManager.isAvailable());
+    NativeMemoryManager mman = new NativeMemoryManager("test");
+    testEnlargeHashTable(mman);
+    mman.close();
+  }
+}
