generated from yandex-praktikum/java-kanban
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Сделать бесконечную историю со скоростью доступа О(1).
- Loading branch information
1 parent
6984829
commit 5f6d8e5
Showing
4 changed files
with
274 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,8 @@ public interface HistoryManager { | |
|
||
void clear(); | ||
|
||
void remove(int id); | ||
|
||
List<Task> getHistory(); | ||
|
||
} |
79 changes: 68 additions & 11 deletions
79
src/ru/alexgur/kanban/service/InMemoryHistoryManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,47 +1,104 @@ | ||
package ru.alexgur.kanban.service; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
|
||
import ru.alexgur.kanban.model.Task; | ||
|
||
public class InMemoryHistoryManager implements HistoryManager { | ||
|
||
public static final int HISTORY_MAX_SIZE = 10; | ||
|
||
private ArrayList<Task> history = new ArrayList<>(); | ||
private Node head; | ||
private Node tail; | ||
private HashMap<Integer, Node> history = new HashMap<>(); | ||
|
||
@Override | ||
public void clear() { | ||
clearImpl(); | ||
} | ||
|
||
@Override | ||
public void remove(int id) { | ||
removeImpl(id); | ||
} | ||
|
||
@Override | ||
public void add(Task task) { | ||
addImpl(task); | ||
} | ||
|
||
@Override | ||
public List<Task> getHistory() { | ||
return getHistoryImpl(); | ||
List<Task> listTasks = new ArrayList<>(); | ||
for (Node node : getTasks()) { | ||
listTasks.add(node.getTask()); | ||
} | ||
return listTasks; | ||
} | ||
|
||
private Node linkLast(Task task) { | ||
final Node oldtail = tail; | ||
final Node newNode = new Node(oldtail, task, null); | ||
tail = newNode; | ||
if (oldtail == null) { | ||
head = newNode; | ||
} else { | ||
oldtail.setNext(newNode); | ||
} | ||
return newNode; | ||
} | ||
|
||
private ArrayList<Node> getTasks() { | ||
ArrayList<Node> nodes = new ArrayList<>(); | ||
Node currentNode = head; | ||
while (currentNode != null) { | ||
nodes.add(currentNode); | ||
currentNode = currentNode.getNext(); | ||
} | ||
Collections.reverse(nodes); | ||
return nodes; | ||
} | ||
|
||
private void addImpl(Task task) { | ||
if (task != null) { | ||
history.add(task); | ||
if (history.size() > HISTORY_MAX_SIZE) { | ||
history.remove(0); | ||
if (history.containsKey(task.getId())) { | ||
Node node = history.remove(task.getId()); | ||
removeNode(node); | ||
} | ||
Node node = linkLast(task); | ||
history.put(task.getId(), node); | ||
} | ||
} | ||
|
||
private void removeNode(Node node) { | ||
Node prev = node.getPrev(); | ||
Node next = node.getNext(); | ||
|
||
if (prev != null && next != null) { | ||
// Удаляетяся элемент в середине списка | ||
next.setPrev(prev); | ||
prev.setNext(next); | ||
} else if (prev == null && next != null) { | ||
// Удаляетяся первый элемент | ||
head = next; | ||
next.setPrev(null); | ||
} else if (prev != null && next == null) { | ||
// Удаляетяся последний элемент | ||
tail = prev; | ||
prev.setNext(null); | ||
} | ||
|
||
history.remove(node.getTask().getId()); | ||
} | ||
|
||
private List<Task> getHistoryImpl() { | ||
List<Task> res = history; | ||
return List.copyOf(res); | ||
private void removeImpl(int id) { | ||
history.remove(id); | ||
} | ||
|
||
private void clearImpl() { | ||
head = null; | ||
tail = null; | ||
history.clear(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package ru.alexgur.kanban.service; | ||
|
||
import ru.alexgur.kanban.model.Task; | ||
|
||
public class Node { | ||
private Task task; | ||
private Node next; | ||
private Node prev; | ||
|
||
public Node(Node prev, Task task, Node next) { | ||
this.task = task; | ||
this.next = next; | ||
this.prev = prev; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return task.hashCode(); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
Node other = (Node) obj; | ||
return task.equals(other.task); | ||
} | ||
|
||
public Task getTask() { | ||
return task; | ||
} | ||
|
||
public void setTask(Task task) { | ||
this.task = task; | ||
} | ||
|
||
public Node getNext() { | ||
return next; | ||
} | ||
|
||
public void setNext(Node next) { | ||
this.next = next; | ||
} | ||
|
||
public Node getPrev() { | ||
return prev; | ||
} | ||
|
||
public void setPrev(Node prev) { | ||
this.prev = prev; | ||
} | ||
} |
Oops, something went wrong.