diff --git a/commander/src/main/java/hse/java/commander/CommanderApplication.java b/commander/src/main/java/hse/java/commander/CommanderApplication.java
index 471f6fd5..efe291c1 100644
--- a/commander/src/main/java/hse/java/commander/CommanderApplication.java
+++ b/commander/src/main/java/hse/java/commander/CommanderApplication.java
@@ -8,6 +8,8 @@
import java.io.IOException;
import java.nio.file.Paths;
+
+
public class CommanderApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
diff --git a/pom.xml b/pom.xml
index bb6d9b8a..2efcc4ac 100644
--- a/pom.xml
+++ b/pom.xml
@@ -45,6 +45,12 @@
${lombok.version}
provided
+
+ org.mockito
+ mockito-junit-jupiter
+ 5.23.0
+ test
+
diff --git a/src/main/java/hse/java/Task.java b/src/main/java/hse/java/Task.java
new file mode 100644
index 00000000..e69de29b
diff --git a/src/main/java/hse/java/lectures/lecture3/practice/randomSet/Debub.java b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/Debub.java
new file mode 100644
index 00000000..ed17fec7
--- /dev/null
+++ b/src/main/java/hse/java/lectures/lecture3/practice/randomSet/Debub.java
@@ -0,0 +1,20 @@
+package hse.java.lectures.lecture3.practice.randomSet;
+
+public class Debub {
+ public static void main(String[] args) {
+ RandomSet rs = new RandomSet();
+
+ rs.insert(10);
+ rs.insert(20);
+
+ for (int i = 0; i < 20; i++) {
+ System.out.println(rs.getRandom());
+ }
+
+ rs.remove(10);
+ for (int i = 0; i < 20; i++) {
+ System.out.println(rs.getRandom());
+ }
+ System.out.println(rs.remove(10));
+ }
+}
diff --git a/src/main/java/hse/java/lectures/lecture3/tasks/html/HtmlDocument.java b/src/main/java/hse/java/lectures/lecture3/tasks/html/HtmlDocument.java
index 1ddf27bf..e69de29b 100644
--- a/src/main/java/hse/java/lectures/lecture3/tasks/html/HtmlDocument.java
+++ b/src/main/java/hse/java/lectures/lecture3/tasks/html/HtmlDocument.java
@@ -1,32 +0,0 @@
-package hse.java.lectures.lecture3.tasks.html;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayDeque;
-import java.util.Deque;
-import java.util.Set;
-
-public class HtmlDocument {
-
- public HtmlDocument(String filePath) {
- this(Path.of(filePath));
- }
-
- public HtmlDocument(Path filePath) {
- String content = readFile(filePath);
- validate(content);
- }
-
- private String readFile(Path filePath) {
- try {
- return Files.readString(filePath, StandardCharsets.UTF_8);
- } catch (IOException e) {
- throw new RuntimeException("Failed to read file: " + filePath, e);
- }
- }
-
- private void validate(String content){}
-
-}
diff --git a/src/main/java/hse/java/lectures/lesson7/dau/DauService.java b/src/main/java/hse/java/lectures/lesson7/dau/DauService.java
index a02a0384..60e96694 100644
--- a/src/main/java/hse/java/lectures/lesson7/dau/DauService.java
+++ b/src/main/java/hse/java/lectures/lesson7/dau/DauService.java
@@ -1,7 +1,12 @@
package hse.java.lectures.lesson7.dau;
+import java.sql.Time;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.util.Date;
import java.util.List;
import java.util.Map;
+import java.util.Set;
public interface DauService {
diff --git a/src/main/java/hse/java/lectures/lesson7/dau/DauServiceImpl.java b/src/main/java/hse/java/lectures/lesson7/dau/DauServiceImpl.java
new file mode 100644
index 00000000..ab3a9cd3
--- /dev/null
+++ b/src/main/java/hse/java/lectures/lesson7/dau/DauServiceImpl.java
@@ -0,0 +1,66 @@
+package hse.java.lectures.lesson7.dau;
+
+import java.time.Duration;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.*;
+import java.util.concurrent.*;
+
+public class DauServiceImpl implements DauService {
+ private ConcurrentMap yesterdayStat = new ConcurrentHashMap<>();
+ private ConcurrentMap> nowStat = new ConcurrentHashMap<>();
+
+ private ScheduledExecutorService s = Executors.newScheduledThreadPool(1);
+
+ DauServiceImpl() {
+
+ ZonedDateTime now = ZonedDateTime.now(ZoneId.systemDefault());
+ ZonedDateTime nextRun = now.withHour(0).withMinute(0).withSecond(0).withNano(0);
+
+ long initialDelay = Duration.between(now, nextRun).getSeconds();
+ long period = TimeUnit.DAYS.toSeconds(1);
+
+ s.scheduleAtFixedRate(this::update,
+ initialDelay, period, TimeUnit.SECONDS
+ );
+ }
+
+ void update() {
+ yesterdayStat.clear();
+ for (var entry : nowStat.entrySet()) {
+ yesterdayStat.put(entry.getKey(), (long) entry.getValue().size());
+ }
+ nowStat.clear();
+ }
+
+
+ @Override
+ public void postEvent(Event event) {
+ nowStat.computeIfAbsent(event.authorId(), k -> ConcurrentHashMap.newKeySet()).add(event.userId());
+ }
+
+ @Override
+ public Map getDauStatistics(List authorIds) {
+ HashMap result = new HashMap<>();
+ for (var id : authorIds) {
+ var stat = yesterdayStat.get(id);
+ result.put(id, stat == null ? 0 : stat);
+ }
+ return result;
+ }
+
+ @Override
+ public Long getAuthorDauStatistics(int authorId) {
+ var res = yesterdayStat.get(authorId);
+ return (res == null ? 0 : res);
+ }
+
+ void goToNextDay() {
+ update();
+ }
+
+ void stopScheduler() {
+ s.shutdownNow();
+ }
+}
diff --git a/src/main/java/hse/java/practice/task1/Debug.java b/src/main/java/hse/java/practice/task1/Debug.java
new file mode 100644
index 00000000..e69de29b
diff --git a/src/test/java/hse/java/lectures/lecture3/tasks/html/HtmlDocumentTest.java b/src/test/java/hse/java/lectures/lecture3/tasks/html/HtmlDocumentTest.java
index dcdb6459..e69de29b 100644
--- a/src/test/java/hse/java/lectures/lecture3/tasks/html/HtmlDocumentTest.java
+++ b/src/test/java/hse/java/lectures/lecture3/tasks/html/HtmlDocumentTest.java
@@ -1,114 +0,0 @@
-package hse.java.lectures.lecture3.tasks.html;
-
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.MethodSource;
-import org.junit.jupiter.params.provider.Arguments;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.stream.Stream;
-
-import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-@Disabled
-class HtmlDocumentTest {
-
- @Test
- void validDocumentPasses() throws IOException {
- String html = "";
- Path path = writeTemp(html);
- assertDoesNotThrow(() -> new HtmlDocument(path));
- }
-
- @Test
- void validDocumentWithAttributesAndCasePasses() throws IOException {
- String html = "";
- Path path = writeTemp(html);
- assertDoesNotThrow(() -> new HtmlDocument(path));
- }
-
- @Test
- void unsupportedTagFails() throws IOException {
- String html = "";
- Path path = writeTemp(html);
- assertThrows(UnsupportedTagException.class, () -> new HtmlDocument(path));
- }
-
- @Test
- void unexpectedClosingTagFails() throws IOException {
- String html = "";
- Path path = writeTemp(html);
- assertThrows(UnexpectedClosingTagException.class, () -> new HtmlDocument(path));
- }
-
- @Test
- void mismatchedClosingTagFails() throws IOException {
- String html = "
";
- Path path = writeTemp(html);
- assertThrows(MismatchedClosingTagException.class, () -> new HtmlDocument(path));
- }
-
- @Test
- void unclosedTagFails() throws IOException {
- String html = "";
- Path path = writeTemp(html);
- assertThrows(UnclosedTagException.class, () -> new HtmlDocument(path));
- }
-
- @Test
- void invalidStructureBodyBeforeHeadFails() throws IOException {
- String html = "";
- Path path = writeTemp(html);
- assertThrows(InvalidStructureException.class, () -> new HtmlDocument(path));
- }
-
- @Test
- void invalidStructureMultipleHtmlFails() throws IOException {
- String html = "";
- Path path = writeTemp(html);
- assertThrows(InvalidStructureException.class, () -> new HtmlDocument(path));
- }
-
- @Test
- void invalidStructureHeadNotDirectChildFails() throws IOException {
- String html = "
";
- Path path = writeTemp(html);
- assertThrows(InvalidStructureException.class, () -> new HtmlDocument(path));
- }
-
- @ParameterizedTest(name = "{index}: {0}")
- @MethodSource("fileCases")
- void fileCases(String resourcePath, Class extends RuntimeException> expected) throws Exception {
- Path path = Path.of(getClass().getClassLoader().getResource(resourcePath).toURI());
- if (expected == null) {
- assertDoesNotThrow(() -> new HtmlDocument(path));
- } else {
- assertThrows(expected, () -> new HtmlDocument(path));
- }
- }
-
- static Stream
fileCases() {
- return Stream.of(
- Arguments.of("html/valid_basic.html", null),
- Arguments.of("html/valid_attrs_case.html", null),
- Arguments.of("html/invalid_unsupported_tag.html", UnsupportedTagException.class),
- Arguments.of("html/invalid_unexpected_closing.html", UnexpectedClosingTagException.class),
- Arguments.of("html/invalid_mismatched.html", MismatchedClosingTagException.class),
- Arguments.of("html/invalid_unclosed.html", UnclosedTagException.class),
- Arguments.of("html/invalid_structure_body_before_head.html", InvalidStructureException.class),
- Arguments.of("html/invalid_structure_multiple_html.html", InvalidStructureException.class),
- Arguments.of("html/invalid_structure_head_not_direct_child.html", InvalidStructureException.class)
- );
- }
-
- private Path writeTemp(String content) throws IOException {
- Path path = Files.createTempFile("html-doc", ".html");
- Files.writeString(path, content);
- path.toFile().deleteOnExit();
- return path;
- }
-}
diff --git a/src/test/java/hse/java/lectures/lesson7/dau/DauServiceImplTest.java b/src/test/java/hse/java/lectures/lesson7/dau/DauServiceImplTest.java
new file mode 100644
index 00000000..c2a4bdab
--- /dev/null
+++ b/src/test/java/hse/java/lectures/lesson7/dau/DauServiceImplTest.java
@@ -0,0 +1,54 @@
+package hse.java.lectures.lesson7.dau;
+
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+
+
+import java.time.LocalDate;
+import java.util.ArrayList;
+
+import static org.junit.jupiter.api.Assertions.*;
+@Tag("dau")
+class DauServiceImplTest {
+
+ @Test
+ void JustWorks() {
+ DauServiceImpl service = new DauServiceImpl();
+ service.stopScheduler();
+ service.postEvent(new Event(0,0));
+ service.postEvent(new Event(0,1));
+ service.postEvent(new Event(0,2));
+ service.postEvent(new Event(1,0));
+ service.goToNextDay();
+ assertEquals(2L, service.getAuthorDauStatistics(0));
+ assertEquals(1L, service.getAuthorDauStatistics(1));
+
+ }
+
+ @Test
+ void ManyThreads() throws InterruptedException {
+
+ ArrayList threads = new ArrayList<>();
+ DauServiceImpl service = new DauServiceImpl();
+ service.stopScheduler();
+ for (int i = 0; i < 10; i++) {
+ int ii = i;
+ var thread = new Thread(() -> {
+ for (int j = 0; j < 10000; j++) {
+ service.postEvent(new Event(ii,j));
+ }
+ });
+ thread.start();
+ threads.add(thread);
+ }
+
+ for (var thr : threads) {
+ thr.join();
+ }
+ service.goToNextDay();
+ for (int i = 0; i < 10000; i++) {
+ assertEquals(10L, service.getAuthorDauStatistics(i));
+ }
+
+ }
+}
\ No newline at end of file