Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Спринт 6. Сделать бесконечную историю со скоростью доступа О(1) #1

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/ru/alexgur/kanban/service/HistoryManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ public interface HistoryManager {

void clear();

void remove(int id);

List<Task> getHistory();

}
79 changes: 68 additions & 11 deletions src/ru/alexgur/kanban/service/InMemoryHistoryManager.java
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();
}

}
50 changes: 50 additions & 0 deletions src/ru/alexgur/kanban/service/Node.java
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;
}
}
Loading
Loading