Loading tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/FlagTable.java +24 −15 Original line number Diff line number Diff line Loading @@ -16,41 +16,50 @@ package android.aconfig.storage; import static java.nio.charset.StandardCharsets.UTF_8; import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Map; import java.util.Objects; public class FlagTable { private Header mHeader; private Map<String, Node> mNodeMap; private ByteBufferReader mReader; public static FlagTable fromBytes(ByteBuffer bytes) { FlagTable flagTable = new FlagTable(); ByteBufferReader reader = new ByteBufferReader(bytes); Header header = Header.fromBytes(reader); flagTable.mHeader = header; flagTable.mNodeMap = new HashMap(TableUtils.getTableSize(header.mNumFlags)); reader.position(header.mNodeOffset); for (int i = 0; i < header.mNumFlags; i++) { Node node = Node.fromBytes(reader); flagTable.mNodeMap.put(makeKey(node.mPackageId, node.mFlagName), node); } flagTable.mReader = new ByteBufferReader(bytes); flagTable.mHeader = Header.fromBytes(flagTable.mReader); return flagTable; } public Node get(int packageId, String flagName) { return mNodeMap.get(makeKey(packageId, flagName)); int numBuckets = (mHeader.mNodeOffset - mHeader.mBucketOffset) / 4; int bucketIndex = TableUtils.getBucketIndex(makeKey(packageId, flagName), numBuckets); mReader.position(mHeader.mBucketOffset + bucketIndex * 4); int nodeIndex = mReader.readInt(); while (nodeIndex != -1) { mReader.position(nodeIndex); Node node = Node.fromBytes(mReader); if (Objects.equals(flagName, node.mFlagName) && packageId == node.mPackageId) { return node; } nodeIndex = node.mNextOffset; } throw new AconfigStorageException("get cannot find flag: " + flagName); } public Header getHeader() { return mHeader; } private static String makeKey(int packageId, String flagName) { private static byte[] makeKey(int packageId, String flagName) { StringBuilder ret = new StringBuilder(); return ret.append(packageId).append('/').append(flagName).toString(); return ret.append(packageId).append('/').append(flagName).toString().getBytes(UTF_8); } public static class Header { Loading tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/PackageTable.java +14 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.aconfig.storage; import static java.nio.charset.StandardCharsets.UTF_8; import java.nio.ByteBuffer; import java.util.Objects; Loading @@ -33,13 +35,22 @@ public class PackageTable { } public Node get(String packageName) { mReader.position(mHeader.mNodeOffset); for (int i = 0; i < mHeader.mNumPackages; i++) { int numBuckets = (mHeader.mNodeOffset - mHeader.mBucketOffset) / 4; int bucketIndex = TableUtils.getBucketIndex(packageName.getBytes(UTF_8), numBuckets); mReader.position(mHeader.mBucketOffset + bucketIndex * 4); int nodeIndex = mReader.readInt(); while (nodeIndex != -1) { mReader.position(nodeIndex); Node node = Node.fromBytes(mReader); if (Objects.equals(node.mPackageName, packageName)) { if (Objects.equals(packageName, node.mPackageName)) { return node; } nodeIndex = node.mNextOffset; } throw new AconfigStorageException("get cannot find package: " + packageName); } Loading tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/SipHasher13.java +12 −16 Original line number Diff line number Diff line Loading @@ -44,43 +44,39 @@ public class SipHasher13 { private void cRounds() { v0 += v1; v1 = rotateLeft(v1, 13); v1 = Long.rotateLeft(v1, 13); v1 ^= v0; v0 = rotateLeft(v0, 32); v0 = Long.rotateLeft(v0, 32); v2 += v3; v3 = rotateLeft(v3, 16); v3 = Long.rotateLeft(v3, 16); v3 ^= v2; v0 += v3; v3 = rotateLeft(v3, 21); v3 = Long.rotateLeft(v3, 21); v3 ^= v0; v2 += v1; v1 = rotateLeft(v1, 17); v1 = Long.rotateLeft(v1, 17); v1 ^= v2; v2 = rotateLeft(v2, 32); v2 = Long.rotateLeft(v2, 32); } private void dRounds() { for (int i = 0; i < 3; i++) { v0 += v1; v1 = rotateLeft(v1, 13); v1 = Long.rotateLeft(v1, 13); v1 ^= v0; v0 = rotateLeft(v0, 32); v0 = Long.rotateLeft(v0, 32); v2 += v3; v3 = rotateLeft(v3, 16); v3 = Long.rotateLeft(v3, 16); v3 ^= v2; v0 += v3; v3 = rotateLeft(v3, 21); v3 = Long.rotateLeft(v3, 21); v3 ^= v0; v2 += v1; v1 = rotateLeft(v1, 17); v1 = Long.rotateLeft(v1, 17); v1 ^= v2; v2 = rotateLeft(v2, 32); v2 = Long.rotateLeft(v2, 32); } } private static long rotateLeft(long value, int shift) { return (value << shift) | value >>> (64 - shift); } } public static long hash(byte[] data) { Loading tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/TableUtils.java +5 −0 Original line number Diff line number Diff line Loading @@ -58,4 +58,9 @@ public class TableUtils { } throw new AconfigStorageException("Number of items in a hash table exceeds limit"); } public static int getBucketIndex(byte[] val, int numBuckets) { long hashVal = SipHasher13.hash(val); return (int) Long.remainderUnsigned(hashVal, numBuckets); } } tools/aconfig/aconfig_storage_file/tests/Android.bp +3 −1 Original line number Diff line number Diff line Loading @@ -30,9 +30,10 @@ android_test { static_libs: [ "androidx.test.runner", "junit", "aconfig_storage_file_java", ], test_config: "AndroidStorageJaveTest.xml", certificate: "platform", sdk_version: "test_current", data: [ "package.map", "flag.map", Loading @@ -42,4 +43,5 @@ android_test { test_suites: [ "general-tests", ], jarjar_rules: "jarjar.txt", } Loading
tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/FlagTable.java +24 −15 Original line number Diff line number Diff line Loading @@ -16,41 +16,50 @@ package android.aconfig.storage; import static java.nio.charset.StandardCharsets.UTF_8; import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Map; import java.util.Objects; public class FlagTable { private Header mHeader; private Map<String, Node> mNodeMap; private ByteBufferReader mReader; public static FlagTable fromBytes(ByteBuffer bytes) { FlagTable flagTable = new FlagTable(); ByteBufferReader reader = new ByteBufferReader(bytes); Header header = Header.fromBytes(reader); flagTable.mHeader = header; flagTable.mNodeMap = new HashMap(TableUtils.getTableSize(header.mNumFlags)); reader.position(header.mNodeOffset); for (int i = 0; i < header.mNumFlags; i++) { Node node = Node.fromBytes(reader); flagTable.mNodeMap.put(makeKey(node.mPackageId, node.mFlagName), node); } flagTable.mReader = new ByteBufferReader(bytes); flagTable.mHeader = Header.fromBytes(flagTable.mReader); return flagTable; } public Node get(int packageId, String flagName) { return mNodeMap.get(makeKey(packageId, flagName)); int numBuckets = (mHeader.mNodeOffset - mHeader.mBucketOffset) / 4; int bucketIndex = TableUtils.getBucketIndex(makeKey(packageId, flagName), numBuckets); mReader.position(mHeader.mBucketOffset + bucketIndex * 4); int nodeIndex = mReader.readInt(); while (nodeIndex != -1) { mReader.position(nodeIndex); Node node = Node.fromBytes(mReader); if (Objects.equals(flagName, node.mFlagName) && packageId == node.mPackageId) { return node; } nodeIndex = node.mNextOffset; } throw new AconfigStorageException("get cannot find flag: " + flagName); } public Header getHeader() { return mHeader; } private static String makeKey(int packageId, String flagName) { private static byte[] makeKey(int packageId, String flagName) { StringBuilder ret = new StringBuilder(); return ret.append(packageId).append('/').append(flagName).toString(); return ret.append(packageId).append('/').append(flagName).toString().getBytes(UTF_8); } public static class Header { Loading
tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/PackageTable.java +14 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package android.aconfig.storage; import static java.nio.charset.StandardCharsets.UTF_8; import java.nio.ByteBuffer; import java.util.Objects; Loading @@ -33,13 +35,22 @@ public class PackageTable { } public Node get(String packageName) { mReader.position(mHeader.mNodeOffset); for (int i = 0; i < mHeader.mNumPackages; i++) { int numBuckets = (mHeader.mNodeOffset - mHeader.mBucketOffset) / 4; int bucketIndex = TableUtils.getBucketIndex(packageName.getBytes(UTF_8), numBuckets); mReader.position(mHeader.mBucketOffset + bucketIndex * 4); int nodeIndex = mReader.readInt(); while (nodeIndex != -1) { mReader.position(nodeIndex); Node node = Node.fromBytes(mReader); if (Objects.equals(node.mPackageName, packageName)) { if (Objects.equals(packageName, node.mPackageName)) { return node; } nodeIndex = node.mNextOffset; } throw new AconfigStorageException("get cannot find package: " + packageName); } Loading
tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/SipHasher13.java +12 −16 Original line number Diff line number Diff line Loading @@ -44,43 +44,39 @@ public class SipHasher13 { private void cRounds() { v0 += v1; v1 = rotateLeft(v1, 13); v1 = Long.rotateLeft(v1, 13); v1 ^= v0; v0 = rotateLeft(v0, 32); v0 = Long.rotateLeft(v0, 32); v2 += v3; v3 = rotateLeft(v3, 16); v3 = Long.rotateLeft(v3, 16); v3 ^= v2; v0 += v3; v3 = rotateLeft(v3, 21); v3 = Long.rotateLeft(v3, 21); v3 ^= v0; v2 += v1; v1 = rotateLeft(v1, 17); v1 = Long.rotateLeft(v1, 17); v1 ^= v2; v2 = rotateLeft(v2, 32); v2 = Long.rotateLeft(v2, 32); } private void dRounds() { for (int i = 0; i < 3; i++) { v0 += v1; v1 = rotateLeft(v1, 13); v1 = Long.rotateLeft(v1, 13); v1 ^= v0; v0 = rotateLeft(v0, 32); v0 = Long.rotateLeft(v0, 32); v2 += v3; v3 = rotateLeft(v3, 16); v3 = Long.rotateLeft(v3, 16); v3 ^= v2; v0 += v3; v3 = rotateLeft(v3, 21); v3 = Long.rotateLeft(v3, 21); v3 ^= v0; v2 += v1; v1 = rotateLeft(v1, 17); v1 = Long.rotateLeft(v1, 17); v1 ^= v2; v2 = rotateLeft(v2, 32); v2 = Long.rotateLeft(v2, 32); } } private static long rotateLeft(long value, int shift) { return (value << shift) | value >>> (64 - shift); } } public static long hash(byte[] data) { Loading
tools/aconfig/aconfig_storage_file/srcs/android/aconfig/storage/TableUtils.java +5 −0 Original line number Diff line number Diff line Loading @@ -58,4 +58,9 @@ public class TableUtils { } throw new AconfigStorageException("Number of items in a hash table exceeds limit"); } public static int getBucketIndex(byte[] val, int numBuckets) { long hashVal = SipHasher13.hash(val); return (int) Long.remainderUnsigned(hashVal, numBuckets); } }
tools/aconfig/aconfig_storage_file/tests/Android.bp +3 −1 Original line number Diff line number Diff line Loading @@ -30,9 +30,10 @@ android_test { static_libs: [ "androidx.test.runner", "junit", "aconfig_storage_file_java", ], test_config: "AndroidStorageJaveTest.xml", certificate: "platform", sdk_version: "test_current", data: [ "package.map", "flag.map", Loading @@ -42,4 +43,5 @@ android_test { test_suites: [ "general-tests", ], jarjar_rules: "jarjar.txt", }