From ffb0ccd04bc3505f20827a0bfcf7a7060dfd4d89 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Wed, 24 Feb 2021 12:15:50 +0900 Subject: [PATCH] Add a BpfMap#clear method. A caller can mostly already do this via forEach(), but having a specific method is faster (since the code does not need to read the value) and easier to use. The semantics of this method (e.g., ignore ENOENT while deleting a key, but throw on any other error) match those of the native BpfMap::clear method. Test: new unit tests Change-Id: I5cd32efd0f87c823cd2d0a2fa3a95a83093fb6f9 --- .../networkstack/tethering/BpfMap.java | 14 ++++++++++ .../networkstack/tethering/BpfMapTest.java | 26 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/Tethering/src/com/android/networkstack/tethering/BpfMap.java b/Tethering/src/com/android/networkstack/tethering/BpfMap.java index 9a9376f0a7..e9b4ccf2f4 100644 --- a/Tethering/src/com/android/networkstack/tethering/BpfMap.java +++ b/Tethering/src/com/android/networkstack/tethering/BpfMap.java @@ -226,6 +226,20 @@ public class BpfMap implements AutoCloseable closeMap(mMapFd); } + /** + * Clears the map. The map may already be empty. + * + * @throws ErrnoException if the map is already closed, if an error occurred during iteration, + * or if a non-ENOENT error occurred when deleting a key. + */ + public void clear() throws ErrnoException { + K key = getFirstKey(); + while (key != null) { + deleteEntry(key); // ignores ENOENT. + key = getFirstKey(); + } + } + private static native int closeMap(int fd) throws ErrnoException; private native int bpfFdGet(String path, int mode) throws ErrnoException, NullPointerException; diff --git a/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java b/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java index cceaa8c82e..62302c37c8 100644 --- a/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java +++ b/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java @@ -311,6 +311,32 @@ public final class BpfMapTest { assertNull(mTestMap.getFirstKey()); } + @Test + public void testClear() throws Exception { + // Clear an empty map. + assertTrue(mTestMap.isEmpty()); + mTestMap.clear(); + + // Clear a map with some data in it. + final ArrayMap resultMap = + new ArrayMap<>(mTestData); + for (int i = 0; i < resultMap.size(); i++) { + mTestMap.insertEntry(resultMap.keyAt(i), resultMap.valueAt(i)); + } + assertFalse(mTestMap.isEmpty()); + mTestMap.clear(); + assertTrue(mTestMap.isEmpty()); + + // Clearing an already-closed map throws. + mTestMap.close(); + try { + mTestMap.clear(); + fail("clearing already-closed map should throw"); + } catch (ErrnoException expected) { + assertEquals(OsConstants.EBADF, expected.errno); + } + } + @Test public void testInsertOverflow() throws Exception { final ArrayMap testData =