Added LLD projects

This commit is contained in:
Your Name
2020-07-15 18:02:38 +05:30
commit 0d2fabc962
135 changed files with 3319 additions and 0 deletions

3
rate-limiter/.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

16
rate-limiter/.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="rate-limiter" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel>
<module name="rate-limiter" target="10" />
</bytecodeTargetLevel>
</component>
</project>

20
rate-limiter/.idea/jarRepositories.xml generated Normal file
View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>

View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: junit:junit:4.13">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.13/junit-4.13.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.13/junit-4.13-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.13/junit-4.13-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.hamcrest:hamcrest-core:1.3">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-sources.jar!/" />
</SOURCES>
</library>
</component>

13
rate-limiter/.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
rate-limiter/.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/rate-limiter.iml" filepath="$PROJECT_DIR$/rate-limiter.iml" />
</modules>
</component>
</project>

124
rate-limiter/.idea/uiDesigner.xml generated Normal file
View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

6
rate-limiter/.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

31
rate-limiter/pom.xml Normal file
View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>interviewready.io</groupId>
<artifactId>rate-limiter</artifactId>
<version>1.0</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>10</source>
<target>10</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_10">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.13" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
</component>
</module>

View File

@@ -0,0 +1,77 @@
import exceptions.RateLimitExceededException;
import models.Request;
import utils.Timer;
import java.util.Map;
import java.util.concurrent.*;
public class TimerWheel {
private final int timeOutPeriod;
private final int capacityPerSlot;
private final TimeUnit timeUnit;
private final ArrayBlockingQueue<Request>[] slots;
private final Map<String, Integer> reverseIndex;
private final Timer timer;
private final ExecutorService[] threads;
public TimerWheel(final TimeUnit timeUnit,
final int timeOutPeriod,
final int capacityPerSlot,
final Timer timer) {
this.timeUnit = timeUnit;
this.timeOutPeriod = timeOutPeriod;
this.capacityPerSlot = capacityPerSlot;
if (this.timeOutPeriod > 1000) {
throw new IllegalArgumentException();
}
this.slots = new ArrayBlockingQueue[this.timeOutPeriod];
this.threads = new ExecutorService[this.timeOutPeriod];
this.reverseIndex = new ConcurrentHashMap<>();
for (int i = 0; i < slots.length; i++) {
slots[i] = new ArrayBlockingQueue<>(capacityPerSlot);
threads[i] = Executors.newSingleThreadExecutor();
}
this.timer = timer;
final long timePerSlot = TimeUnit.MILLISECONDS.convert(1, timeUnit);
Executors.newSingleThreadScheduledExecutor()
.scheduleAtFixedRate(this::flushRequests,
timePerSlot - (this.timer.getCurrentTimeInMillis() % timePerSlot),
timePerSlot, TimeUnit.MILLISECONDS);
}
public Future<?> flushRequests() {
final int currentSlot = getCurrentSlot();
return threads[currentSlot].submit(() -> {
for (final Request request : slots[currentSlot]) {
if (timer.getCurrentTime(timeUnit) - request.getStartTime() >= timeOutPeriod) {
slots[currentSlot].remove(request);
reverseIndex.remove(request.getRequestId());
}
}
});
}
public Future<?> addRequest(final Request request) {
final int currentSlot = getCurrentSlot();
return threads[currentSlot].submit(() -> {
if (slots[currentSlot].size() >= capacityPerSlot) {
throw new RateLimitExceededException();
}
slots[currentSlot].add(request);
reverseIndex.put(request.getRequestId(), currentSlot);
});
}
public Future<?> evict(final String requestId) {
final int currentSlot = reverseIndex.get(requestId);
return threads[currentSlot].submit(() -> {
slots[currentSlot].remove(new Request(requestId, 0));
reverseIndex.remove(requestId);
});
}
private int getCurrentSlot() {
return (int) timer.getCurrentTime(timeUnit) % slots.length;
}
}

View File

@@ -0,0 +1,7 @@
package exceptions;
public class RateLimitExceededException extends IllegalStateException {
public RateLimitExceededException() {
super("Rate limit exceeded");
}
}

View File

@@ -0,0 +1,33 @@
package models;
import java.util.Objects;
public class Request {
private final String requestId;
private final long startTime;
public Request(String requestId, long startTime) {
this.requestId = requestId;
this.startTime = startTime;
}
public String getRequestId() {
return requestId;
}
public long getStartTime() {
return startTime;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
return requestId.equals(((Request) o).requestId);
}
@Override
public int hashCode() {
return requestId.hashCode();
}
}

View File

@@ -0,0 +1,13 @@
package utils;
import java.util.concurrent.TimeUnit;
public class Timer {
public long getCurrentTime(final TimeUnit timeUnit) {
return timeUnit.convert(getCurrentTimeInMillis(), TimeUnit.MILLISECONDS);
}
public long getCurrentTimeInMillis() {
return System.currentTimeMillis();
}
}

View File

@@ -0,0 +1,74 @@
import models.Request;
import org.junit.Assert;
import org.junit.Test;
import java.util.concurrent.TimeUnit;
public class RateLimitTest {
@Test
public void testDefaultBehaviour() throws Exception {
final TimeUnit timeUnit = TimeUnit.SECONDS;
final TestTimer timer = new TestTimer();
final TimerWheel timerWheel = new TimerWheel(timeUnit, 6, 3, timer);
timerWheel.addRequest(new Request("1", timer.getCurrentTime(timeUnit))).get();
timerWheel.addRequest(new Request("2", timer.getCurrentTime(timeUnit))).get();
timerWheel.addRequest(new Request("3", timer.getCurrentTime(timeUnit))).get();
Throwable exception = null;
try {
timerWheel.addRequest(new Request("4", timer.getCurrentTime(timeUnit))).get();
} catch (Exception e) {
exception = e.getCause();
}
Assert.assertNotNull(exception);
Assert.assertEquals("Rate limit exceeded", exception.getMessage());
tick(timeUnit, timer, timerWheel);
timerWheel.addRequest(new Request("4", timer.getCurrentTime(timeUnit))).get();
timerWheel.addRequest(new Request("5", timer.getCurrentTime(timeUnit))).get();
timerWheel.evict("1").get();
timerWheel.evict("4").get();
timerWheel.addRequest(new Request("6", timer.getCurrentTime(timeUnit))).get();
timerWheel.addRequest(new Request("7", timer.getCurrentTime(timeUnit))).get();
}
@Test
public void testClearing() throws Exception {
final TimeUnit timeUnit = TimeUnit.SECONDS;
final TestTimer timer = new TestTimer();
final int timeOutPeriod = 6;
final TimerWheel timerWheel = new TimerWheel(timeUnit, timeOutPeriod, 3, timer);
timerWheel.addRequest(new Request("0", timer.getCurrentTime(timeUnit))).get();
timerWheel.addRequest(new Request("1", timer.getCurrentTime(timeUnit))).get();
timerWheel.addRequest(new Request("2", timer.getCurrentTime(timeUnit))).get();
Throwable exception = null;
try {
timerWheel.addRequest(new Request("3", timer.getCurrentTime(timeUnit))).get();
} catch (Exception e) {
exception = e.getCause();
}
Assert.assertNotNull(exception);
Assert.assertEquals("Rate limit exceeded", exception.getMessage());
for (int i = 0; i < timeOutPeriod; i++) {
tick(timeUnit, timer, timerWheel);
}
timerWheel.addRequest(new Request("4", timer.getCurrentTime(timeUnit))).get();
timerWheel.addRequest(new Request("5", timer.getCurrentTime(timeUnit))).get();
timerWheel.addRequest(new Request("6", timer.getCurrentTime(timeUnit))).get();
exception = null;
try {
timerWheel.addRequest(new Request("7", timer.getCurrentTime(timeUnit))).get();
} catch (Exception e) {
exception = e.getCause();
}
Assert.assertNotNull(exception);
Assert.assertEquals("Rate limit exceeded", exception.getMessage());
}
private void tick(TimeUnit timeUnit, TestTimer timer, TimerWheel timerWheel) throws Exception {
timer.setTime(timer.getCurrentTimeInMillis() + TimeUnit.MILLISECONDS.convert(1, timeUnit));
timerWheel.flushRequests().get();
}
}

View File

@@ -0,0 +1,14 @@
import utils.Timer;
public class TestTimer extends Timer {
private long currentTime = System.currentTimeMillis();
@Override
public long getCurrentTimeInMillis() {
return currentTime;
}
public void setTime(final long currentTime) {
this.currentTime = currentTime;
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.