package com.linkedin.databus.core.util; /* * * Copyright 2013 LinkedIn Corp. All rights reserved * * Licensed 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. * */ import java.util.ArrayList; import java.util.Queue; import java.util.concurrent.ArrayBlockingQueue; import org.apache.log4j.Level; import org.testng.Assert; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import com.linkedin.databus.core.util.RangeBasedReaderWriterLock.LockToken; public class TestRangeBasedReaderWriterLockPerf { BufferPositionParser _parser = new BufferPositionParser(Integer.MAX_VALUE, Integer.MAX_VALUE); @BeforeMethod public void setUp() throws Exception { } @AfterMethod public void tearDown() throws Exception { } @Test /** * Test how fast we can check out read locks from the lock provider * We will keep a maximum of N read locks checked out at any point in time * Once the number of read locks has exceeded N we will release a few K back to the provider * We will also check out a non-overlapping write lock after checking out the read lock */ public void testReaderInsertWithCooperatingWritesPerformance() throws Exception { ArrayList<Double> avgInsertsPerSecond = new ArrayList<Double>(); for (int numTests = 0; numTests < 20; ++ numTests) { Queue<LockToken> checkedOutLockTokens = new ArrayBlockingQueue<LockToken>(100); RangeBasedReaderWriterLock lockProvider = new RangeBasedReaderWriterLock(); RangeBasedReaderWriterLock.LOG.setLevel(Level.FATAL); long startTime = System.nanoTime(); int numOperations = 1000000; for (int i=numOperations -1; i > 0; --i) { LockToken token = lockProvider.acquireReaderLock(i, numOperations,_parser, "lock" + i); long minStart = lockProvider.getReaderRanges().peek()._id.start; lockProvider.acquireWriterLock(0, minStart,_parser); lockProvider.releaseWriterLock(_parser); if (minStart != i) { Assert.fail("i should always be equal to minStart"); } //assertEquals(i, minStart); while (!checkedOutLockTokens.offer(token)) { for (int j = 0; j < 5; ++j) { LockToken releaseToken = checkedOutLockTokens.poll(); lockProvider.releaseReaderLock(releaseToken); } } } long endTime = System.nanoTime(); if (numTests>0) { double insertsPerSecond = numOperations * 1000000000L / (endTime - startTime); avgInsertsPerSecond.add(insertsPerSecond); System.out.println("Inserts per second = " + insertsPerSecond); } } double total = 0; for (Double d: avgInsertsPerSecond) { total += d; } System.out.println("Overall Average Inserts Per Second = " + (total / avgInsertsPerSecond.size())); } }