/** * converts the list of acls to a long. * Increments the reference counter for this ACL. * @param acls * @return a long that map to the acls */ public synchronized Long convertAcls(List<ACL> acls) { if (acls == null) return OPEN_UNSAFE_ACL_ID; // get the value from the map Long ret = aclKeyMap.get(acls); if (ret == null) { ret = incrementIndex(); longKeyMap.put(ret, acls); aclKeyMap.put(acls, ret); } addUsage(ret); return ret; }
public Stat setACL(String path, List<ACL> acl, int version) throws KeeperException.NoNodeException { Stat stat = new Stat(); DataNode n = nodes.get(path); if (n == null) { throw new KeeperException.NoNodeException(); } synchronized (n) { aclCache.removeUsage(n.acl); n.stat.setAversion(version); n.acl = aclCache.convertAcls(acl); n.copyStat(stat); return stat; } }
public List<ACL> getACL(DataNode node) { synchronized (node) { return aclCache.convertLong(node.acl); } }
@Test public void testAddUsage() { List<ACL> testACL = createACL("myid"); ReferenceCountedACLCache cache = new ReferenceCountedACLCache(); Long aclId = cache.convertAcls(testACL); assertEquals(1, cache.size()); cache.addUsage(aclId); assertEquals(1, cache.size()); cache.removeUsage(aclId); assertEquals(1, cache.size()); cache.removeUsage(aclId); assertEquals(0, cache.size()); }
@Test public void testPurgeUnused() throws IOException { ReferenceCountedACLCache cache = new ReferenceCountedACLCache(); List<ACL> acl1 = createACL("one"); List<ACL> acl2 = createACL("two"); List<ACL> acl3 = createACL("three"); List<ACL> acl4 = createACL("four"); List<ACL> acl5 = createACL("five"); Long aclId1 = convertACLsNTimes(cache, acl1, 1); Long aclId2 = convertACLsNTimes(cache, acl2, 2); Long aclId3 = convertACLsNTimes(cache, acl3, 3); Long aclId4 = convertACLsNTimes(cache, acl4, 4); Long aclId5 = convertACLsNTimes(cache, acl5, 5); ByteArrayOutputStream baos = new ByteArrayOutputStream(); BinaryOutputArchive archive = BinaryOutputArchive.getArchive(baos); cache.serialize(archive); BinaryInputArchive inArchive = BinaryInputArchive.getArchive(new ByteArrayInputStream(baos.toByteArray())); ReferenceCountedACLCache deserializedCache = new ReferenceCountedACLCache(); deserializedCache.deserialize(inArchive); callAddUsageNTimes(deserializedCache, aclId1, 1); callAddUsageNTimes(deserializedCache, aclId2, 2); deserializedCache.purgeUnused(); assertEquals(2, deserializedCache.size()); assertEquals(aclId1, deserializedCache.convertAcls(acl1)); assertEquals(aclId2, deserializedCache.convertAcls(acl2)); assertFalse(acl3.equals(deserializedCache.convertAcls(acl3))); assertFalse(acl4.equals(deserializedCache.convertAcls(acl4))); assertFalse(acl5.equals(deserializedCache.convertAcls(acl5))); }
public void deserialize(InputArchive ia, String tag) throws IOException { aclCache.deserialize(ia); nodes.clear(); pTrie.clear(); nodes.put(path, node); synchronized (node) { aclCache.addUsage(node.acl); aclCache.purgeUnused();
@Test public void testNPEInDeserialize() throws IOException { ReferenceCountedACLCache serializeCache = new ReferenceCountedACLCache(){ @Override public synchronized void serialize(OutputArchive oa) throws IOException { oa.writeInt(1, "map"); oa.writeLong(1, "long"); oa.startVector(null, "acls"); oa.endVector(null, "acls"); } }; ByteArrayOutputStream baos = new ByteArrayOutputStream(); BinaryOutputArchive archive = BinaryOutputArchive.getArchive(baos); serializeCache.serialize(archive); BinaryInputArchive inArchive = BinaryInputArchive.getArchive(new ByteArrayInputStream(baos.toByteArray())); ReferenceCountedACLCache deserializedCache = new ReferenceCountedACLCache(); try { deserializedCache.deserialize(inArchive); } catch (NullPointerException e){ fail("should not throw NPE while do deserialized"); } catch (RuntimeException e) { // do nothing. } }
@Test public void testAddNonExistentUsage() { ReferenceCountedACLCache cache = new ReferenceCountedACLCache(); cache.addUsage(1L); assertEquals(0, cache.size()); /* On startup, it's possible that we'll try calling addUsage of an ID not in the cache. This is safe to ignore as it'll be added later when we traverse the tranlog. See discussion here: http://mail-archives.apache.org/mod_mbox/zookeeper-user/201507.mbox/%3CCAB5oV2_ujhvBA1sEkCG2WRakPjCy%2BNR10620WK2G1GGgmEO44g%40mail.gmail.com%3E This test makes sure that we don't add the ID to the cache in this case as that would result in dupes later and consequently incorrect counts and entries that will never be cleaned out. */ }
@Test public void testBidirectionality() { List<ACL> testACL = createACL("myid"); ReferenceCountedACLCache cache = new ReferenceCountedACLCache(); Long aclId = cache.convertAcls(testACL); assertEquals(testACL, cache.convertLong(aclId)); }
@Test public void testCacheSize() { List<ACL> testACL = createACL("myid"); ReferenceCountedACLCache cache = new ReferenceCountedACLCache(); Long aclId = cache.convertAcls(testACL); assertEquals(1, cache.size()); List<ACL> testACL2 = createACL("myid"); assertEquals(aclId, cache.convertAcls(testACL2)); assertEquals(1, cache.size()); List<ACL> testACL3 = createACL("differentId"); Long aclId3 = cache.convertAcls(testACL3); assertFalse(aclId3.equals(aclId)); assertEquals(2, cache.size()); }
public Long getACL(DataNodeV1 oldDataNode) { synchronized (oldDataNode) { return aclCache.convertAcls(oldDataNode.acl); } }
@Test public void testSameACLGivesSameID() { List<ACL> testACL = createACL("myid"); ReferenceCountedACLCache cache = new ReferenceCountedACLCache(); Long aclId = cache.convertAcls(testACL); List<ACL> testACL2 = createACL("myid"); assertEquals(aclId, cache.convertAcls(testACL2)); }
public void serialize(OutputArchive oa, String tag) throws IOException { aclCache.serialize(oa); serializeNode(oa, new StringBuilder("")); // / marks end of stream // we need to check if clear had been called in between the snapshot. if (root != null) { oa.writeString("/", "path"); } }
public int aclCacheSize() { return aclCache.size(); }
aclCache.removeUsage(node.acl); nodeDataSize.addAndGet(-getNodeSize(path, node.data));
private void callAddUsageNTimes(ReferenceCountedACLCache deserializedCache, Long aclId, int num) { for (int i = 0; i < num; i++) { deserializedCache.addUsage(aclId); } }
public synchronized void deserialize(InputArchive ia) throws IOException { clear(); int i = ia.readInt("map"); while (i > 0) { Long val = ia.readLong("long"); if (aclIndex < val) { aclIndex = val; } List<ACL> aclList = new ArrayList<ACL>(); Index j = ia.startVector("acls"); if (j == null) { throw new RuntimeException("Incorrent format of InputArchive when deserialize DataTree - missing acls"); } while (!j.done()) { ACL acl = new ACL(); acl.deserialize(ia, "acl"); aclList.add(acl); j.incr(); } longKeyMap.put(val, aclList); aclKeyMap.put(aclList, val); referenceCounter.put(val, new AtomicLongWithEquals(0)); i--; } }
@Test public void testAddThenRemove() { List<ACL> testACL = createACL("myid"); ReferenceCountedACLCache cache = new ReferenceCountedACLCache(); Long aclId = cache.convertAcls(testACL); assertEquals(1, cache.size()); cache.removeUsage(aclId); assertEquals(0, cache.size()); }
public void deserialize(InputArchive ia, String tag) throws IOException { aclCache.deserialize(ia); nodes.clear(); pTrie.clear(); nodes.put(path, node); synchronized (node) { aclCache.addUsage(node.acl); aclCache.purgeUnused();
@Test public void testSerializeDeserialize() throws IOException { ReferenceCountedACLCache cache = new ReferenceCountedACLCache(); List<ACL> acl1 = createACL("one"); List<ACL> acl2 = createACL("two"); List<ACL> acl3 = createACL("three"); List<ACL> acl4 = createACL("four"); List<ACL> acl5 = createACL("five"); Long aclId1 = convertACLsNTimes(cache, acl1, 1); Long aclId2 = convertACLsNTimes(cache, acl2, 2); Long aclId3 = convertACLsNTimes(cache, acl3, 3); Long aclId4 = convertACLsNTimes(cache, acl4, 4); Long aclId5 = convertACLsNTimes(cache, acl5, 5); ByteArrayOutputStream baos = new ByteArrayOutputStream(); BinaryOutputArchive archive = BinaryOutputArchive.getArchive(baos); cache.serialize(archive); BinaryInputArchive inArchive = BinaryInputArchive.getArchive(new ByteArrayInputStream(baos.toByteArray())); ReferenceCountedACLCache deserializedCache = new ReferenceCountedACLCache(); deserializedCache.deserialize(inArchive); callAddUsageNTimes(deserializedCache, aclId1, 1); callAddUsageNTimes(deserializedCache, aclId2, 2); callAddUsageNTimes(deserializedCache, aclId3, 3); callAddUsageNTimes(deserializedCache, aclId4, 4); callAddUsageNTimes(deserializedCache, aclId5, 5); assertCachesEqual(cache, deserializedCache); }