From 4e815f5a439b164219a2bf1e7f510d6b5c7eef65 Mon Sep 17 00:00:00 2001 From: David Date: Wed, 19 Apr 2017 14:03:46 +0300 Subject: [PATCH 01/14] SoftCache task --- SoftCache/.idea/misc.xml | 6 + SoftCache/.idea/modules.xml | 8 + SoftCache/.idea/workspace.xml | 598 ++++++++++++++++++ SoftCache/SoftCache.iml | 11 + .../out/production/SoftCache/Cache.class | Bin 0 -> 380 bytes .../production/SoftCache/SoftCacheMap.class | Bin 0 -> 1722 bytes SoftCache/src/Cache.java | 24 + SoftCache/src/SoftCacheMap.java | 45 ++ 8 files changed, 692 insertions(+) create mode 100644 SoftCache/.idea/misc.xml create mode 100644 SoftCache/.idea/modules.xml create mode 100644 SoftCache/.idea/workspace.xml create mode 100644 SoftCache/SoftCache.iml create mode 100644 SoftCache/out/production/SoftCache/Cache.class create mode 100644 SoftCache/out/production/SoftCache/SoftCacheMap.class create mode 100644 SoftCache/src/Cache.java create mode 100644 SoftCache/src/SoftCacheMap.java diff --git a/SoftCache/.idea/misc.xml b/SoftCache/.idea/misc.xml new file mode 100644 index 0000000..0548357 --- /dev/null +++ b/SoftCache/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/SoftCache/.idea/modules.xml b/SoftCache/.idea/modules.xml new file mode 100644 index 0000000..d370c02 --- /dev/null +++ b/SoftCache/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/SoftCache/.idea/workspace.xml b/SoftCache/.idea/workspace.xml new file mode 100644 index 0000000..70f81df --- /dev/null +++ b/SoftCache/.idea/workspace.xml @@ -0,0 +1,598 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + DEFINITION_ORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1492599433704 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SoftCache/SoftCache.iml b/SoftCache/SoftCache.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/SoftCache/SoftCache.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/SoftCache/out/production/SoftCache/Cache.class b/SoftCache/out/production/SoftCache/Cache.class new file mode 100644 index 0000000000000000000000000000000000000000..4b0ec5d7c361422a7ac15e256a5bad35f230d45d GIT binary patch literal 380 zcmZvY!H&UD6o&spwR9Mrc?jAK8!Hu?NhCr-Lb|`2qe!RZYCW8V2bhPNIIYA&?e2H( z`M-0|{rkV(01WVL!Ljf~Xhxh)w@b}uPEtb0ogdUi^<$Mp{l(_MVd{J35}~o$M~O-^ z&4jwUp84K7@CnsZCYJ6SOIhLtqRFF@%+IFg-{VDmwJ>I-Mds$^(P%a-hl4k@ak-6P zua21xd9shiZ2zcm$Gv<-8B+kkdEM9~5GwLdfMLipUbmL!K#863f35ux^`TDs~s_1FYjw7TCrstjp7?O zSYn7(jGC$0EsHbk`ZHGCP(w3o#Vyn3HExxpkj1OTO0#NziE*%OnEYMqaF1Kt+FpYq>2g!o8atY0h-WVtvg^h%!$4VZ zZEAX*lOh6DYuw(dez5p4H*JQQtW;X3+F2>)RYXM`@Go6QE{S7ERBTN@AOep(c+?{7 zY(H#2w9pnl(HbpBietC~-(`+i{IGdKZ^L?nYZk+_4E%m?pX+u>uGtIyqt1&;1$2&5 z0c-wn*>O$oPRAc9x7#p=c%|90bpF~9JxR&7&k0c~ZsHcb@J*D8A!JmnBgZh(lkb}o zk+Q*%?4`Km0(eu!Bwnh>BBx@u$0PSiyd4vHQz}L=Mx!9tcnR1wh75Nspx)EaFbrk; znw;s^4YG8(Ph4`YW4=Fx`}9GkLBmGBfN+QI!}Pfaa05}=laaLErpN|@v;&g4GqBt_ z0=s7jen;r5lRZM~0A+|Zgh9GexI<5>dj@xLkDi!t!^7JrjsV4`a^Dcjw-LTTqz&a4 zGM57vh@P@jN(`b$k|FqEOi+1(WY`7rNC=W-jT6m;bBaySmRjNQZX@i}nRaN-5!o%A zA=XCxQ%{Nb;{w5@sA@ql=AP&hq&)(Vchi`mZ2APRuI!pCwXd>qBAuklr?0AvM$l8X zNO#eps8H61`mdfm6cnVcL|r|}bur5x#yn{e+GDx=1rlux2 { + /** + * Возвращает соответствующее значение, если оно ещё в кэше, иначе null + */ + V getIfPresent(K key); + + /** + * Сохраняет value по соответствующему ключу key + */ + void put(K key, V value); + + /** + * Удаляет соответствующее ключу key значение + */ + V remove(K key); + + /** + * Очищает кэш + */ + void clear(); +} diff --git a/SoftCache/src/SoftCacheMap.java b/SoftCache/src/SoftCacheMap.java new file mode 100644 index 0000000..43e4fa2 --- /dev/null +++ b/SoftCache/src/SoftCacheMap.java @@ -0,0 +1,45 @@ +//import java.lang.ref.ReferenceQueue; +import java.lang.ref.SoftReference; +import java.util.HashMap; + +/** + * Created by david on 18.04.17. + */ + +public class SoftCacheMap implements Cache { + + private HashMap> hashMap; + //private ReferenceQueue> referenceQueue; + + public SoftCacheMap() { + this.hashMap = new HashMap>(); + // this.referenceQueue = new ReferenceQueue>(); + } + + @Override + public String getIfPresent(Integer key) { + if (hashMap.get(key).get() != null) { + return hashMap.get(key).get(); + } + return null; + } + + @Override + public void put(Integer key, String value) { + hashMap.put(key, new SoftReference(value)); + } + + @Override + public String remove(Integer key) { + if (hashMap.get(key).get() != null) { + + return hashMap.remove(key).get(); + } + return null; + } + + @Override + public void clear() { + hashMap.clear(); + } +} \ No newline at end of file From b5a6e3b71ffad80aeea17b96a2ce31ce742939c6 Mon Sep 17 00:00:00 2001 From: David Date: Sun, 23 Apr 2017 00:11:31 +0300 Subject: [PATCH 02/14] Binary files deleted --- SoftCache/out/production/SoftCache/Cache.class | Bin 380 -> 0 bytes .../out/production/SoftCache/SoftCacheMap.class | Bin 1722 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 SoftCache/out/production/SoftCache/Cache.class delete mode 100644 SoftCache/out/production/SoftCache/SoftCacheMap.class diff --git a/SoftCache/out/production/SoftCache/Cache.class b/SoftCache/out/production/SoftCache/Cache.class deleted file mode 100644 index 4b0ec5d7c361422a7ac15e256a5bad35f230d45d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 380 zcmZvY!H&UD6o&spwR9Mrc?jAK8!Hu?NhCr-Lb|`2qe!RZYCW8V2bhPNIIYA&?e2H( z`M-0|{rkV(01WVL!Ljf~Xhxh)w@b}uPEtb0ogdUi^<$Mp{l(_MVd{J35}~o$M~O-^ z&4jwUp84K7@CnsZCYJ6SOIhLtqRFF@%+IFg-{VDmwJ>I-Mds$^(P%a-hl4k@ak-6P zua21xd9shiZ2zcm$Gv<-8B+kkdEM9~5GwLdfMLipUbmL!K#863f35ux^`TDs~s_1FYjw7TCrstjp7?O zSYn7(jGC$0EsHbk`ZHGCP(w3o#Vyn3HExxpkj1OTO0#NziE*%OnEYMqaF1Kt+FpYq>2g!o8atY0h-WVtvg^h%!$4VZ zZEAX*lOh6DYuw(dez5p4H*JQQtW;X3+F2>)RYXM`@Go6QE{S7ERBTN@AOep(c+?{7 zY(H#2w9pnl(HbpBietC~-(`+i{IGdKZ^L?nYZk+_4E%m?pX+u>uGtIyqt1&;1$2&5 z0c-wn*>O$oPRAc9x7#p=c%|90bpF~9JxR&7&k0c~ZsHcb@J*D8A!JmnBgZh(lkb}o zk+Q*%?4`Km0(eu!Bwnh>BBx@u$0PSiyd4vHQz}L=Mx!9tcnR1wh75Nspx)EaFbrk; znw;s^4YG8(Ph4`YW4=Fx`}9GkLBmGBfN+QI!}Pfaa05}=laaLErpN|@v;&g4GqBt_ z0=s7jen;r5lRZM~0A+|Zgh9GexI<5>dj@xLkDi!t!^7JrjsV4`a^Dcjw-LTTqz&a4 zGM57vh@P@jN(`b$k|FqEOi+1(WY`7rNC=W-jT6m;bBaySmRjNQZX@i}nRaN-5!o%A zA=XCxQ%{Nb;{w5@sA@ql=AP&hq&)(Vchi`mZ2APRuI!pCwXd>qBAuklr?0AvM$l8X zNO#eps8H61`mdfm6cnVcL|r|}bur5x#yn{e+GDx=1rlux2 Date: Sun, 23 Apr 2017 18:04:06 +0300 Subject: [PATCH 03/14] ReferenceQueue checking added --- SoftCache/.idea/workspace.xml | 137 ++++++++++++++++++++++---------- SoftCache/src/SoftCacheMap.java | 57 +++++++++---- 2 files changed, 135 insertions(+), 59 deletions(-) diff --git a/SoftCache/.idea/workspace.xml b/SoftCache/.idea/workspace.xml index 70f81df..f447b3c 100644 --- a/SoftCache/.idea/workspace.xml +++ b/SoftCache/.idea/workspace.xml @@ -15,7 +15,7 @@ - + @@ -29,14 +29,10 @@ - - + + - - - - @@ -92,6 +88,8 @@ + + @@ -121,16 +119,30 @@ - - + - + + + + @@ -489,6 +502,12 @@ + project + + + + + @@ -504,6 +523,14 @@ + + + + + + + + - + + + + + + + + - + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - + + + + - - + @@ -564,7 +601,9 @@ - + + @@ -582,14 +621,28 @@ - - + + + + + + + + + + + + + + + + + + + + - - - - diff --git a/SoftCache/src/SoftCacheMap.java b/SoftCache/src/SoftCacheMap.java index 43e4fa2..65c8782 100644 --- a/SoftCache/src/SoftCacheMap.java +++ b/SoftCache/src/SoftCacheMap.java @@ -1,45 +1,68 @@ -//import java.lang.ref.ReferenceQueue; +import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.util.HashMap; - -/** - * Created by david on 18.04.17. - */ +import java.util.HashSet; public class SoftCacheMap implements Cache { - private HashMap> hashMap; - //private ReferenceQueue> referenceQueue; + private HashMap> hashMap1; + private HashMap, HashSet> hashMap2; + private ReferenceQueue> referenceQueue; + + private SoftCacheMap() { + hashMap1 = new HashMap(); + hashMap2 = new HashMap(); + referenceQueue = new ReferenceQueue(); + } - public SoftCacheMap() { - this.hashMap = new HashMap>(); - // this.referenceQueue = new ReferenceQueue>(); + private boolean delete() { + SoftReference reference = (SoftReference) referenceQueue.poll(); + if (reference != null) { + if (hashMap1.entrySet().contains(reference)) { + HashSet localSet = hashMap2.remove(reference); + for (Object local : localSet) { + hashMap1.remove(local); + } + } + return true; + } else { + return false; + } } @Override public String getIfPresent(Integer key) { - if (hashMap.get(key).get() != null) { - return hashMap.get(key).get(); + if (hashMap1.get(key).get() != null) { + return hashMap1.get(key).get(); } return null; } @Override public void put(Integer key, String value) { - hashMap.put(key, new SoftReference(value)); + hashMap1.put(key, new SoftReference(value, referenceQueue)); + if (hashMap2.get(hashMap1.get(key)) != null) { + hashMap2.get(hashMap1.get(key)).add(key); + } else { + hashMap2.put(hashMap1.get(key), new HashSet(key)); + } + while (delete()) { + //delete references + } } @Override public String remove(Integer key) { - if (hashMap.get(key).get() != null) { - - return hashMap.remove(key).get(); + if (hashMap1.get(key).get() != null) { + hashMap2.remove(hashMap1.get(key)); + return hashMap1.remove(key).get(); } return null; } @Override public void clear() { - hashMap.clear(); + hashMap1.clear(); + hashMap2.clear(); } } \ No newline at end of file From 694ea72670d22d65340a036276de68acc33dc11f Mon Sep 17 00:00:00 2001 From: David Date: Mon, 24 Apr 2017 14:28:02 +0300 Subject: [PATCH 04/14] Fixes --- SoftCache/.idea/workspace.xml | 43 +++++++++++++------ SoftCache/SoftCache.iml | 9 +--- SoftCache/src/SoftCacheMap.java | 75 ++++++++++++++++++--------------- 3 files changed, 74 insertions(+), 53 deletions(-) diff --git a/SoftCache/.idea/workspace.xml b/SoftCache/.idea/workspace.xml index f447b3c..a9cfb23 100644 --- a/SoftCache/.idea/workspace.xml +++ b/SoftCache/.idea/workspace.xml @@ -19,8 +19,8 @@ - - + + @@ -30,7 +30,7 @@ - + @@ -88,8 +88,6 @@ - - @@ -118,6 +116,8 @@ + + @@ -543,12 +543,13 @@ - @@ -566,7 +567,6 @@ - @@ -578,9 +578,8 @@ - + - @@ -591,7 +590,9 @@ + + @@ -602,7 +603,7 @@ - @@ -637,10 +638,28 @@ + + + + + + + + + + + + + + + + + + - + diff --git a/SoftCache/SoftCache.iml b/SoftCache/SoftCache.iml index c90834f..19dbd15 100644 --- a/SoftCache/SoftCache.iml +++ b/SoftCache/SoftCache.iml @@ -1,11 +1,6 @@ - - - - - - - + + \ No newline at end of file diff --git a/SoftCache/src/SoftCacheMap.java b/SoftCache/src/SoftCacheMap.java index 65c8782..0d99f9e 100644 --- a/SoftCache/src/SoftCacheMap.java +++ b/SoftCache/src/SoftCacheMap.java @@ -3,66 +3,73 @@ import java.util.HashMap; import java.util.HashSet; -public class SoftCacheMap implements Cache { +public class SoftCacheMap implements Cache { - private HashMap> hashMap1; - private HashMap, HashSet> hashMap2; - private ReferenceQueue> referenceQueue; + private HashMap> cache; + private HashMap, HashSet> subsidiaryMap; + private ReferenceQueue> referenceQueue; private SoftCacheMap() { - hashMap1 = new HashMap(); - hashMap2 = new HashMap(); - referenceQueue = new ReferenceQueue(); + cache = new HashMap<>(); + /** + * второй hashMap - вспомогательный, используется при удалении из кэша + * тех ссылок, которые попали в referenceQueue. Чтобы не искать все ключи, + * соответствующие одной ссылке, храню Set из таких ключей в качестве значения + * во втором hashMap-e. + */ + subsidiaryMap = new HashMap<>(); + referenceQueue = new ReferenceQueue<>(); } - private boolean delete() { - SoftReference reference = (SoftReference) referenceQueue.poll(); - if (reference != null) { - if (hashMap1.entrySet().contains(reference)) { - HashSet localSet = hashMap2.remove(reference); - for (Object local : localSet) { - hashMap1.remove(local); + private void clean() { + boolean done = false; + while (!done) { + SoftReference reference = (SoftReference) referenceQueue.poll(); + if (reference != null) { + if (cache.entrySet().contains(reference)) { + HashSet localSet = subsidiaryMap.remove(reference); + for (Integer local : localSet) { + cache.remove(local); + } } + } else { + done = true; } - return true; - } else { - return false; } } @Override - public String getIfPresent(Integer key) { - if (hashMap1.get(key).get() != null) { - return hashMap1.get(key).get(); + public Object getIfPresent(Integer key) { + if (cache.containsKey(key)) { + return cache.get(key).get(); } return null; } @Override - public void put(Integer key, String value) { - hashMap1.put(key, new SoftReference(value, referenceQueue)); - if (hashMap2.get(hashMap1.get(key)) != null) { - hashMap2.get(hashMap1.get(key)).add(key); + public void put(Integer key, Object value) { + SoftReference reference = new SoftReference(value, referenceQueue); + cache.put(key, reference); + if (subsidiaryMap.containsKey(reference)) { + subsidiaryMap.get(reference).add(key); } else { - hashMap2.put(hashMap1.get(key), new HashSet(key)); - } - while (delete()) { - //delete references + subsidiaryMap.put(reference, new HashSet<>(key)); } + clean(); } @Override - public String remove(Integer key) { - if (hashMap1.get(key).get() != null) { - hashMap2.remove(hashMap1.get(key)); - return hashMap1.remove(key).get(); + public Object remove(Integer key) { + if ((cache.containsKey(key)) && (cache.get(key).get() != null)) { + subsidiaryMap.remove(cache.get(key)); + return cache.remove(key).get(); } return null; } @Override public void clear() { - hashMap1.clear(); - hashMap2.clear(); + cache.clear(); + subsidiaryMap.clear(); } } \ No newline at end of file From 01f750bf480a79e43c17e5c2c8c7e44b08877149 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 24 Apr 2017 16:10:09 +0300 Subject: [PATCH 05/14] Delete unnecessary files --- .gitignore | 2 + SoftCache/.idea/misc.xml | 6 - SoftCache/.idea/modules.xml | 8 - SoftCache/.idea/workspace.xml | 670 ---------------------------------- SoftCache/SoftCache.iml | 6 - 5 files changed, 2 insertions(+), 690 deletions(-) create mode 100644 .gitignore delete mode 100644 SoftCache/.idea/misc.xml delete mode 100644 SoftCache/.idea/modules.xml delete mode 100644 SoftCache/.idea/workspace.xml delete mode 100644 SoftCache/SoftCache.iml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8cf4617 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.iml +*.xml diff --git a/SoftCache/.idea/misc.xml b/SoftCache/.idea/misc.xml deleted file mode 100644 index 0548357..0000000 --- a/SoftCache/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/SoftCache/.idea/modules.xml b/SoftCache/.idea/modules.xml deleted file mode 100644 index d370c02..0000000 --- a/SoftCache/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/SoftCache/.idea/workspace.xml b/SoftCache/.idea/workspace.xml deleted file mode 100644 index a9cfb23..0000000 --- a/SoftCache/.idea/workspace.xml +++ /dev/null @@ -1,670 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - DEFINITION_ORDER - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - project - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1492599433704 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/SoftCache/SoftCache.iml b/SoftCache/SoftCache.iml deleted file mode 100644 index 19dbd15..0000000 --- a/SoftCache/SoftCache.iml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From 47cd948bb15fd88817bc0a278ba1a34bd985ef6a Mon Sep 17 00:00:00 2001 From: David Date: Mon, 24 Apr 2017 16:48:11 +0300 Subject: [PATCH 06/14] Queue of recently used objects added --- SoftCache/src/SoftCacheMap.java | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/SoftCache/src/SoftCacheMap.java b/SoftCache/src/SoftCacheMap.java index 0d99f9e..209e620 100644 --- a/SoftCache/src/SoftCacheMap.java +++ b/SoftCache/src/SoftCacheMap.java @@ -1,15 +1,16 @@ import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; -import java.util.HashMap; -import java.util.HashSet; +import java.util.*; public class SoftCacheMap implements Cache { private HashMap> cache; private HashMap, HashSet> subsidiaryMap; private ReferenceQueue> referenceQueue; + private Deque recentlyUsed; + private int maxSize; - private SoftCacheMap() { + private SoftCacheMap(int size) { cache = new HashMap<>(); /** * второй hashMap - вспомогательный, используется при удалении из кэша @@ -19,8 +20,23 @@ private SoftCacheMap() { */ subsidiaryMap = new HashMap<>(); referenceQueue = new ReferenceQueue<>(); + recentlyUsed = new LinkedList<>(); + maxSize = size; } + private void putInQueue(Object object) { + if (object != null) { + recentlyUsed.remove(object); + if (recentlyUsed.size() < maxSize) { + recentlyUsed.addLast(object); + } else { + recentlyUsed.addLast(object); + recentlyUsed.removeFirst(); + } + } + } + + private void clean() { boolean done = false; while (!done) { @@ -41,6 +57,7 @@ private void clean() { @Override public Object getIfPresent(Integer key) { if (cache.containsKey(key)) { + putInQueue(cache.get(key).get()); return cache.get(key).get(); } return null; @@ -50,6 +67,7 @@ public Object getIfPresent(Integer key) { public void put(Integer key, Object value) { SoftReference reference = new SoftReference(value, referenceQueue); cache.put(key, reference); + putInQueue(value); if (subsidiaryMap.containsKey(reference)) { subsidiaryMap.get(reference).add(key); } else { From b63aea27d1f2ef329575d97ddd8926386fd5df55 Mon Sep 17 00:00:00 2001 From: David Date: Tue, 25 Apr 2017 00:35:56 +0300 Subject: [PATCH 07/14] Fixes --- SoftCache/src/SoftCacheMap.java | 59 ++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/SoftCache/src/SoftCacheMap.java b/SoftCache/src/SoftCacheMap.java index 209e620..da9fd9f 100644 --- a/SoftCache/src/SoftCacheMap.java +++ b/SoftCache/src/SoftCacheMap.java @@ -2,12 +2,12 @@ import java.lang.ref.SoftReference; import java.util.*; -public class SoftCacheMap implements Cache { +public class SoftCacheMap implements Cache { - private HashMap> cache; - private HashMap, HashSet> subsidiaryMap; - private ReferenceQueue> referenceQueue; - private Deque recentlyUsed; + private HashMap> cache; + private HashMap, HashSet> subsidiaryMap; + private ReferenceQueue referenceQueue; + private Deque recentlyUsed; private int maxSize; private SoftCacheMap(int size) { @@ -24,14 +24,16 @@ private SoftCacheMap(int size) { maxSize = size; } - private void putInQueue(Object object) { - if (object != null) { - recentlyUsed.remove(object); - if (recentlyUsed.size() < maxSize) { - recentlyUsed.addLast(object); - } else { - recentlyUsed.addLast(object); - recentlyUsed.removeFirst(); + private void putInQueue(V object) { + if (maxSize > 0) { + if (object != null) { + recentlyUsed.remove(object); + if (recentlyUsed.size() < maxSize) { + recentlyUsed.addLast(object); + } else { + recentlyUsed.addLast(object); + recentlyUsed.removeFirst(); + } } } } @@ -42,7 +44,7 @@ private void clean() { while (!done) { SoftReference reference = (SoftReference) referenceQueue.poll(); if (reference != null) { - if (cache.entrySet().contains(reference)) { + if (subsidiaryMap.containsKey(reference)) { HashSet localSet = subsidiaryMap.remove(reference); for (Integer local : localSet) { cache.remove(local); @@ -55,7 +57,7 @@ private void clean() { } @Override - public Object getIfPresent(Integer key) { + public V getIfPresent(Integer key) { if (cache.containsKey(key)) { putInQueue(cache.get(key).get()); return cache.get(key).get(); @@ -64,20 +66,21 @@ public Object getIfPresent(Integer key) { } @Override - public void put(Integer key, Object value) { - SoftReference reference = new SoftReference(value, referenceQueue); + public void put(Integer key, V value) { + SoftReference reference = new SoftReference(value, referenceQueue); cache.put(key, reference); putInQueue(value); if (subsidiaryMap.containsKey(reference)) { subsidiaryMap.get(reference).add(key); } else { - subsidiaryMap.put(reference, new HashSet<>(key)); + subsidiaryMap.put(reference, new HashSet<>()); + subsidiaryMap.get(reference).add(key); } clean(); } @Override - public Object remove(Integer key) { + public V remove(Integer key) { if ((cache.containsKey(key)) && (cache.get(key).get() != null)) { subsidiaryMap.remove(cache.get(key)); return cache.remove(key).get(); @@ -90,4 +93,22 @@ public void clear() { cache.clear(); subsidiaryMap.clear(); } + + public static void main(String... args) { + SoftCacheMap cache = new SoftCacheMap(2); + for (int i = 0; i < 100; ++i) { + cache.put(i, i); + } + for (int i = 0; i < 100; ++i) { + if (cache.getIfPresent(i) == null) { + System.out.println("it doesn't work"); + } + } + System.gc(); + for (int i = 99; i >= 0; --i) { + if (cache.getIfPresent(i) == null) { + System.out.println("it works"); + } + } + } } \ No newline at end of file From 0f58e757e83475990eef2f6f32fe9432e0f2c603 Mon Sep 17 00:00:00 2001 From: David Date: Tue, 25 Apr 2017 17:47:02 +0300 Subject: [PATCH 08/14] Small fixes + test added --- SoftCache/src/SoftCacheMap.java | 82 +++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 19 deletions(-) diff --git a/SoftCache/src/SoftCacheMap.java b/SoftCache/src/SoftCacheMap.java index da9fd9f..4956121 100644 --- a/SoftCache/src/SoftCacheMap.java +++ b/SoftCache/src/SoftCacheMap.java @@ -1,16 +1,19 @@ import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.util.*; +import java.util.concurrent.TimeUnit; public class SoftCacheMap implements Cache { private HashMap> cache; private HashMap, HashSet> subsidiaryMap; - private ReferenceQueue referenceQueue; + private ReferenceQueue referenceQueue; private Deque recentlyUsed; private int maxSize; + private int cleaningFrequency; + private int numOfPuts; - private SoftCacheMap(int size) { + private SoftCacheMap(int size, int frequency) { cache = new HashMap<>(); /** * второй hashMap - вспомогательный, используется при удалении из кэша @@ -19,9 +22,11 @@ private SoftCacheMap(int size) { * во втором hashMap-e. */ subsidiaryMap = new HashMap<>(); - referenceQueue = new ReferenceQueue<>(); + referenceQueue = new ReferenceQueue(); recentlyUsed = new LinkedList<>(); maxSize = size; + cleaningFrequency = frequency; + numOfPuts = 0; } private void putInQueue(V object) { @@ -47,7 +52,9 @@ private void clean() { if (subsidiaryMap.containsKey(reference)) { HashSet localSet = subsidiaryMap.remove(reference); for (Integer local : localSet) { - cache.remove(local); + if (reference.get() == null) { + cache.remove(local); + } } } } else { @@ -67,6 +74,7 @@ public V getIfPresent(Integer key) { @Override public void put(Integer key, V value) { + ++numOfPuts; SoftReference reference = new SoftReference(value, referenceQueue); cache.put(key, reference); putInQueue(value); @@ -76,7 +84,9 @@ public void put(Integer key, V value) { subsidiaryMap.put(reference, new HashSet<>()); subsidiaryMap.get(reference).add(key); } - clean(); + if (numOfPuts % cleaningFrequency == 0) { + clean(); + } } @Override @@ -94,21 +104,55 @@ public void clear() { subsidiaryMap.clear(); } - public static void main(String... args) { - SoftCacheMap cache = new SoftCacheMap(2); - for (int i = 0; i < 100; ++i) { - cache.put(i, i); - } - for (int i = 0; i < 100; ++i) { - if (cache.getIfPresent(i) == null) { - System.out.println("it doesn't work"); - } + public static void main(String... args) throws InterruptedException { + + /** + * проверка корректной работы referenceQueue + */ + + SoftCacheMap cache1 = new SoftCacheMap(0, 1); + cache1.put(0, new Integer(0)); + + /** + * должен быть 0 + */ + System.out.println(cache1.getIfPresent(0)); + + try { + Object[] big = new Object[(int) Runtime.getRuntime().maxMemory()]; + } catch (OutOfMemoryError e) { + // ignore } - System.gc(); - for (int i = 99; i >= 0; --i) { - if (cache.getIfPresent(i) == null) { - System.out.println("it works"); - } + + /** + * должен быть null + */ + System.out.println(cache1.getIfPresent(0)); + cache1.clear(); + + + /** + * проверка корректной работы recentlyUsed + */ + + SoftCacheMap cache2 = new SoftCacheMap(1, 1); + cache2.put(0, new Integer(0)); + + /** + * должен быть 0 + */ + System.out.println(cache2.getIfPresent(0)); + + try { + Object[] big = new Object[(int) Runtime.getRuntime().maxMemory()]; + } catch (OutOfMemoryError e) { + // ignore } + + /** + * должен быть 0 + */ + System.out.println(cache2.getIfPresent(0)); + cache2.clear(); } } \ No newline at end of file From 031dec16be935722aef11b0832120972c7421c25 Mon Sep 17 00:00:00 2001 From: David Date: Tue, 25 Apr 2017 18:04:33 +0300 Subject: [PATCH 09/14] Small fixes --- SoftCache/src/SoftCacheMap.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/SoftCache/src/SoftCacheMap.java b/SoftCache/src/SoftCacheMap.java index 4956121..61ea83d 100644 --- a/SoftCache/src/SoftCacheMap.java +++ b/SoftCache/src/SoftCacheMap.java @@ -1,7 +1,9 @@ import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; -import java.util.*; -import java.util.concurrent.TimeUnit; +import java.util.Deque; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; public class SoftCacheMap implements Cache { @@ -22,7 +24,7 @@ private SoftCacheMap(int size, int frequency) { * во втором hashMap-e. */ subsidiaryMap = new HashMap<>(); - referenceQueue = new ReferenceQueue(); + referenceQueue = new ReferenceQueue<>(); recentlyUsed = new LinkedList<>(); maxSize = size; cleaningFrequency = frequency; @@ -75,7 +77,7 @@ public V getIfPresent(Integer key) { @Override public void put(Integer key, V value) { ++numOfPuts; - SoftReference reference = new SoftReference(value, referenceQueue); + SoftReference reference = new SoftReference<>(value, referenceQueue); cache.put(key, reference); putInQueue(value); if (subsidiaryMap.containsKey(reference)) { From 0da56dd954dc83d1f1d177a5d4037a9d5a851157 Mon Sep 17 00:00:00 2001 From: David Date: Tue, 25 Apr 2017 20:45:02 +0300 Subject: [PATCH 10/14] Fixes --- SoftCache/src/SoftCacheMap.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/SoftCache/src/SoftCacheMap.java b/SoftCache/src/SoftCacheMap.java index 61ea83d..0fee49a 100644 --- a/SoftCache/src/SoftCacheMap.java +++ b/SoftCache/src/SoftCacheMap.java @@ -5,10 +5,10 @@ import java.util.HashSet; import java.util.LinkedList; -public class SoftCacheMap implements Cache { +public class SoftCacheMap implements Cache { - private HashMap> cache; - private HashMap, HashSet> subsidiaryMap; + private HashMap> cache; + private HashMap, HashSet> subsidiaryMap; private ReferenceQueue referenceQueue; private Deque recentlyUsed; private int maxSize; @@ -52,8 +52,8 @@ private void clean() { SoftReference reference = (SoftReference) referenceQueue.poll(); if (reference != null) { if (subsidiaryMap.containsKey(reference)) { - HashSet localSet = subsidiaryMap.remove(reference); - for (Integer local : localSet) { + HashSet localSet = subsidiaryMap.remove(reference); + for (K local : localSet) { if (reference.get() == null) { cache.remove(local); } @@ -66,7 +66,7 @@ private void clean() { } @Override - public V getIfPresent(Integer key) { + public V getIfPresent(K key) { if (cache.containsKey(key)) { putInQueue(cache.get(key).get()); return cache.get(key).get(); @@ -75,7 +75,7 @@ public V getIfPresent(Integer key) { } @Override - public void put(Integer key, V value) { + public void put(K key, V value) { ++numOfPuts; SoftReference reference = new SoftReference<>(value, referenceQueue); cache.put(key, reference); @@ -92,7 +92,7 @@ public void put(Integer key, V value) { } @Override - public V remove(Integer key) { + public V remove(K key) { if ((cache.containsKey(key)) && (cache.get(key).get() != null)) { subsidiaryMap.remove(cache.get(key)); return cache.remove(key).get(); From 475e34d774091903feafec75d1d803857b3d6a2b Mon Sep 17 00:00:00 2001 From: David Date: Tue, 25 Apr 2017 23:44:33 +0300 Subject: [PATCH 11/14] Fixes --- SoftCache/src/SoftCacheMap.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SoftCache/src/SoftCacheMap.java b/SoftCache/src/SoftCacheMap.java index 0fee49a..80e65f5 100644 --- a/SoftCache/src/SoftCacheMap.java +++ b/SoftCache/src/SoftCacheMap.java @@ -9,7 +9,7 @@ public class SoftCacheMap implements Cache { private HashMap> cache; private HashMap, HashSet> subsidiaryMap; - private ReferenceQueue referenceQueue; + private ReferenceQueue referenceQueue; private Deque recentlyUsed; private int maxSize; private int cleaningFrequency; From 6ebecef69868835e883490893ee203eb12e45982 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 1 May 2017 12:13:10 +0300 Subject: [PATCH 12/14] Unit-test added --- SoftCache/.gitignore | 1 + SoftCache/pom.xml | 100 ++++++++++++++++++ .../src/{ => main/java/maven}/Cache.java | 5 +- .../{ => main/java/maven}/SoftCacheMap.java | 57 +--------- .../src/main/resources/log4j2.properties | 7 ++ .../src/test/java/maven/SoftCacheMapTest.java | 93 ++++++++++++++++ 6 files changed, 207 insertions(+), 56 deletions(-) create mode 100644 SoftCache/.gitignore create mode 100644 SoftCache/pom.xml rename SoftCache/src/{ => main/java/maven}/Cache.java (92%) rename SoftCache/src/{ => main/java/maven}/SoftCacheMap.java (71%) create mode 100644 SoftCache/src/main/resources/log4j2.properties create mode 100644 SoftCache/src/test/java/maven/SoftCacheMapTest.java diff --git a/SoftCache/.gitignore b/SoftCache/.gitignore new file mode 100644 index 0000000..ffd2a4a --- /dev/null +++ b/SoftCache/.gitignore @@ -0,0 +1 @@ +*.idea diff --git a/SoftCache/pom.xml b/SoftCache/pom.xml new file mode 100644 index 0000000..d2a7ca6 --- /dev/null +++ b/SoftCache/pom.xml @@ -0,0 +1,100 @@ + + + + 4.0.0 + + maven + softCache + jar + 1.0 + + A Camel Route + + + UTF-8 + UTF-8 + + + + + + + org.apache.camel + camel-parent + 2.18.3 + import + pom + + + + + + + + org.apache.camel + camel-core + + + + + org.apache.logging.log4j + log4j-api + runtime + + + org.apache.logging.log4j + log4j-core + runtime + + + org.apache.logging.log4j + log4j-slf4j-impl + runtime + + + + + org.apache.camel + camel-test + test + + + + + install + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-resources-plugin + 3.0.1 + + UTF-8 + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.5.0 + + maven.MainApp + false + + + + + + + diff --git a/SoftCache/src/Cache.java b/SoftCache/src/main/java/maven/Cache.java similarity index 92% rename from SoftCache/src/Cache.java rename to SoftCache/src/main/java/maven/Cache.java index ea03777..ab5fcb1 100644 --- a/SoftCache/src/Cache.java +++ b/SoftCache/src/main/java/maven/Cache.java @@ -1,6 +1,5 @@ -/** - * Created by david on 18.04.17. - */ +package maven; + public interface Cache { /** * Возвращает соответствующее значение, если оно ещё в кэше, иначе null diff --git a/SoftCache/src/SoftCacheMap.java b/SoftCache/src/main/java/maven/SoftCacheMap.java similarity index 71% rename from SoftCache/src/SoftCacheMap.java rename to SoftCache/src/main/java/maven/SoftCacheMap.java index 80e65f5..4b4616c 100644 --- a/SoftCache/src/SoftCacheMap.java +++ b/SoftCache/src/main/java/maven/SoftCacheMap.java @@ -1,3 +1,5 @@ +package maven; + import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.util.Deque; @@ -15,7 +17,7 @@ public class SoftCacheMap implements Cache { private int cleaningFrequency; private int numOfPuts; - private SoftCacheMap(int size, int frequency) { + protected SoftCacheMap(int size, int frequency) { cache = new HashMap<>(); /** * второй hashMap - вспомогательный, используется при удалении из кэша @@ -106,55 +108,4 @@ public void clear() { subsidiaryMap.clear(); } - public static void main(String... args) throws InterruptedException { - - /** - * проверка корректной работы referenceQueue - */ - - SoftCacheMap cache1 = new SoftCacheMap(0, 1); - cache1.put(0, new Integer(0)); - - /** - * должен быть 0 - */ - System.out.println(cache1.getIfPresent(0)); - - try { - Object[] big = new Object[(int) Runtime.getRuntime().maxMemory()]; - } catch (OutOfMemoryError e) { - // ignore - } - - /** - * должен быть null - */ - System.out.println(cache1.getIfPresent(0)); - cache1.clear(); - - - /** - * проверка корректной работы recentlyUsed - */ - - SoftCacheMap cache2 = new SoftCacheMap(1, 1); - cache2.put(0, new Integer(0)); - - /** - * должен быть 0 - */ - System.out.println(cache2.getIfPresent(0)); - - try { - Object[] big = new Object[(int) Runtime.getRuntime().maxMemory()]; - } catch (OutOfMemoryError e) { - // ignore - } - - /** - * должен быть 0 - */ - System.out.println(cache2.getIfPresent(0)); - cache2.clear(); - } -} \ No newline at end of file +} diff --git a/SoftCache/src/main/resources/log4j2.properties b/SoftCache/src/main/resources/log4j2.properties new file mode 100644 index 0000000..328db35 --- /dev/null +++ b/SoftCache/src/main/resources/log4j2.properties @@ -0,0 +1,7 @@ + +appender.out.type = Console +appender.out.name = out +appender.out.layout.type = PatternLayout +appender.out.layout.pattern = [%30.30t] %-30.30c{1} %-5p %m%n +rootLogger.level = INFO +rootLogger.appenderRef.out.ref = out diff --git a/SoftCache/src/test/java/maven/SoftCacheMapTest.java b/SoftCache/src/test/java/maven/SoftCacheMapTest.java new file mode 100644 index 0000000..4cfd06a --- /dev/null +++ b/SoftCache/src/test/java/maven/SoftCacheMapTest.java @@ -0,0 +1,93 @@ +package maven; + +import org.junit.Assert; +import org.junit.Test; +import java.util.ArrayList; +import java.util.Arrays; + +public class SoftCacheMapTest { + + private SoftCacheMap getCache(int size, int frequency) { + return new SoftCacheMap<>(size, frequency); + } + + private void testBefore(int size, int frequency, ArrayList values, + ArrayList expectedBefore) throws Exception { + + String errorMessage = "Bad result"; + SoftCacheMap cache = getCache(size, frequency); + for (int i = 0; i < values.size(); ++i) { + cache.put(i, values.get(i)); + } + for (int i = 0; i < values.size(); ++i) { + Assert.assertEquals(errorMessage, expectedBefore.get(i), cache.getIfPresent(i)); + } + } + + private void testAfter(int size, int frequency, ArrayList values, + ArrayList expectedAfter) { + String errorMessage = "Bad result"; + SoftCacheMap cache = getCache(size, frequency); + for (int i = 0; i < values.size(); ++i) { + cache.put(i, new Integer(values.get(i))); + } + try { + Object[] big = new Object[(int) Runtime.getRuntime().maxMemory()]; + } catch (OutOfMemoryError e) { + // ignore + } + + int counter = 0; + for (int i = 0; i < values.size(); ++i) { + if (cache.getIfPresent(i) != null) { + Assert.assertEquals(errorMessage, expectedAfter.get(counter), cache.getIfPresent(i)); + ++counter; + } + } + } + + @Test + public void testReferenceQueueBefore() throws Exception { + ArrayList values = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5)); + ArrayList expectedBefore = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5)); + testBefore(0, 1, values, expectedBefore); + } + + @Test + public void testReferenceQueueAfter() throws Exception { + ArrayList values = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5)); + testAfter(0, 1, values, null); + } + + @Test + public void testRecentlyUsedQueueAfter0() throws Exception { + ArrayList values = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5)); + ArrayList expectedAfter = new ArrayList<>(Arrays.asList(4, 5)); + testAfter(2, 1, values, expectedAfter); + } + + @Test + public void testRecentlyUsedQueueAfter1() throws Exception { + ArrayList values = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5)); + ArrayList expectedAfter = new ArrayList<>(Arrays.asList(2, 5)); + String errorMessage = "Bad result"; + SoftCacheMap cache = getCache(2, 1); + for (int i = 0; i < values.size(); ++i) { + cache.put(i, new Integer(values.get(i))); + } + cache.getIfPresent(2); + try { + Object[] big = new Object[(int) Runtime.getRuntime().maxMemory()]; + } catch (OutOfMemoryError e) { + // ignore + } + + int counter = 0; + for (int i = 0; i < values.size(); ++i) { + if (cache.getIfPresent(i) != null) { + Assert.assertEquals(errorMessage, expectedAfter.get(counter), cache.getIfPresent(i)); + ++counter; + } + } + } +} From 9fed77fb811cffa7e8d2e6d6ca6e6225bf7d18a1 Mon Sep 17 00:00:00 2001 From: David Date: Sun, 14 May 2017 20:02:47 +0300 Subject: [PATCH 13/14] Shell task --- Shell/src/CdCommand.java | 38 ++++++++++++++++ Shell/src/Command.java | 7 +++ Shell/src/CommandManager.java | 83 +++++++++++++++++++++++++++++++++++ Shell/src/CpCommand.java | 77 ++++++++++++++++++++++++++++++++ Shell/src/ExitCommand.java | 27 ++++++++++++ Shell/src/HistoryCommand.java | 36 +++++++++++++++ Shell/src/MkdirCommand.java | 39 ++++++++++++++++ Shell/src/MvCommand.java | 50 +++++++++++++++++++++ Shell/src/RedoCommand.java | 33 ++++++++++++++ Shell/src/SessionClosed.java | 5 +++ Shell/src/UndoCommand.java | 33 ++++++++++++++ Shell/src/WrongCommand.java | 5 +++ 12 files changed, 433 insertions(+) create mode 100644 Shell/src/CdCommand.java create mode 100644 Shell/src/Command.java create mode 100644 Shell/src/CommandManager.java create mode 100644 Shell/src/CpCommand.java create mode 100644 Shell/src/ExitCommand.java create mode 100644 Shell/src/HistoryCommand.java create mode 100644 Shell/src/MkdirCommand.java create mode 100644 Shell/src/MvCommand.java create mode 100644 Shell/src/RedoCommand.java create mode 100644 Shell/src/SessionClosed.java create mode 100644 Shell/src/UndoCommand.java create mode 100644 Shell/src/WrongCommand.java diff --git a/Shell/src/CdCommand.java b/Shell/src/CdCommand.java new file mode 100644 index 0000000..a0295ea --- /dev/null +++ b/Shell/src/CdCommand.java @@ -0,0 +1,38 @@ +import java.io.File; +import java.util.Arrays; + +public class CdCommand implements Command { + + private File curDirectory; + private String path; + + CdCommand(File directory, String path) { + curDirectory = directory; + this.path = path; + } + + @Override + public File execute() throws WrongCommand { + if (path.equals("..")) { + return new File(curDirectory.getParent()); + } else { + for (String name : Arrays.asList(curDirectory.list())) { + if (path.equals(name) && new File(curDirectory + File.separator + name).isDirectory()) { + return new File(curDirectory.toString() + File.separator + name); + } + } + throw new WrongCommand("No directory named " + path); + } + } + + @Override + public File cancel() { + return curDirectory; + } + + @Override + public String name() { + return "cd"; + } + +} diff --git a/Shell/src/Command.java b/Shell/src/Command.java new file mode 100644 index 0000000..ecc28a7 --- /dev/null +++ b/Shell/src/Command.java @@ -0,0 +1,7 @@ +import java.io.File; + +public interface Command { + File execute() throws WrongCommand, SessionClosed; + File cancel() throws WrongCommand; + String name(); +} diff --git a/Shell/src/CommandManager.java b/Shell/src/CommandManager.java new file mode 100644 index 0000000..a7cdcc4 --- /dev/null +++ b/Shell/src/CommandManager.java @@ -0,0 +1,83 @@ +import java.io.File; +import java.util.*; +import java.util.stream.Collectors; + +public class CommandManager { + + private LinkedList HISTORY; + private LinkedList TRASH; + private File curDirectory; + + private CommandManager(String home) throws WrongCommand { + HISTORY = new LinkedList<>(); + TRASH = new LinkedList<>(); + File homeDirectory = new File(home); + if ((!homeDirectory.exists()) || (homeDirectory.isFile())) { + throw new WrongCommand("Incorrect home directory"); + } + curDirectory = homeDirectory; + } + + private Command getCommand(String command) throws WrongCommand { + List parseCommand = Arrays.stream(command.split(" ")) + .filter((w) -> w.length() > 0) + .collect(Collectors.toList()); + switch (parseCommand.get(0)) { + case "cd": + return new CdCommand(curDirectory, parseCommand.get(1)); + case "cp": + return new CpCommand(curDirectory, parseCommand.get(1), parseCommand.get(2)); + case "mv": + return new MvCommand(curDirectory, parseCommand.get(1), parseCommand.get(2)); + case "mkdir": + return new MkdirCommand(curDirectory, parseCommand.get(1)); + case "redo": + return new RedoCommand(curDirectory, TRASH.removeLast(), HISTORY); + case "undo": + return new UndoCommand(curDirectory, HISTORY.removeLast(), TRASH); + case "history": + return new HistoryCommand(curDirectory, HISTORY); + case "exit": + return new ExitCommand(curDirectory); + default: + throw new WrongCommand("Wrong command"); + } + } + + private void doSession() throws SessionClosed, WrongCommand { + Scanner scanner = new Scanner(System.in); + System.out.println(curDirectory + "$"); + while (true) { + String curCommandName = scanner.nextLine(); + try { + Command curCommand = getCommand(curCommandName); + curDirectory = curCommand.execute(); + if (!curCommand.getClass().equals(RedoCommand.class) && + !curCommand.getClass().equals(UndoCommand.class) && + !curCommand.getClass().equals(HistoryCommand.class) && + !curCommand.getClass().equals(ExitCommand.class)) { + HISTORY.add(curCommand); + } + System.out.println(curDirectory); + } catch (WrongCommand e) { + System.out.println(e.getMessage()); + System.out.println(curDirectory); + } catch (SessionClosed e) { + System.out.println(e.getMessage()); + break; + } + } + } + + public static void main(String... args) { + + CommandManager manager; + try { + manager = new CommandManager(System.getProperty("user.dir")); + manager.doSession(); + } catch (WrongCommand | SessionClosed e) { + System.out.println(e.getMessage()); + } + } + +} diff --git a/Shell/src/CpCommand.java b/Shell/src/CpCommand.java new file mode 100644 index 0000000..983a336 --- /dev/null +++ b/Shell/src/CpCommand.java @@ -0,0 +1,77 @@ +import java.io.File; +import java.io.IOException; + +public class CpCommand implements Command { + + private File curDirectory; + private String destination; + private String source; + private boolean alreadyExist; + + CpCommand(File directory, String destination, String source) { + curDirectory = directory; + this.destination = destination; + this.source = source; + alreadyExist = false; + } + + @Override + public File execute() throws WrongCommand { + File folder = new File(destination); + //folder is absolute path + if (!folder.exists()) { + throw new WrongCommand("Directory does not exist"); + } + if (folder.isFile()) { + throw new WrongCommand("Destination is not a directory"); + } + + //source is absolute path + File file = new File(source); + try { + if (file.isDirectory() && file.list().length > 0) { + throw new WrongCommand("Folder is a non-empty directory."); + } + } catch (NullPointerException e) { + //do nothing + } + + File newFile = new File(destination + File.separator + file.getName()); + if (file.isFile()) { + try { + if (newFile.createNewFile()) { + System.out.println("File " + file.getName() + " copied"); + } else { + System.out.println("File already exist"); + alreadyExist = true; + } + } catch (IOException e) { + e.printStackTrace(); + } + } else if (file.isDirectory()) { + if (newFile.mkdir()) { + System.out.println("Directory " + file.getName() + " copied"); + } else { + System.out.println("Directory already exist"); + alreadyExist = true; + } + } + return curDirectory; + } + + @Override + public File cancel() throws WrongCommand { + File newFile = new File(destination + File.separator + new File(source).getName()); + if (!alreadyExist) { + newFile.delete(); + System.out.println("File " + newFile.getName() + " has been deleted."); + } + return curDirectory; + } + + @Override + public String name() { + return "cp"; + } + +} diff --git a/Shell/src/ExitCommand.java b/Shell/src/ExitCommand.java new file mode 100644 index 0000000..3528d43 --- /dev/null +++ b/Shell/src/ExitCommand.java @@ -0,0 +1,27 @@ +import java.io.File; + +public class ExitCommand implements Command { + + private File curDirectory; + + ExitCommand(File directory) { + curDirectory = directory; + } + + @Override + public File execute() throws SessionClosed { + throw new SessionClosed("Session Closed"); + } + + @Override + public File cancel() { + return curDirectory; + //do nothing + } + + @Override + public String name() { + return "exit"; + } + +} diff --git a/Shell/src/HistoryCommand.java b/Shell/src/HistoryCommand.java new file mode 100644 index 0000000..cf72865 --- /dev/null +++ b/Shell/src/HistoryCommand.java @@ -0,0 +1,36 @@ +import java.io.File; +import java.util.LinkedList; + +public class HistoryCommand implements Command { + + private File curDirectory; + private LinkedList history; + + HistoryCommand(File curDirectory, LinkedList history) { + this.curDirectory = curDirectory; + this.history = history; + } + + @Override + public File execute() { + System.out.println("HISTORY OF COMMANDS:"); + int counter = 0; + for (Command command : history) { + ++counter; + System.out.println(counter + " " + command.name()); + } + return curDirectory; + } + + @Override + public File cancel() { + return curDirectory; + //do nothing + } + + @Override + public String name() { + return "undo"; + } + +} diff --git a/Shell/src/MkdirCommand.java b/Shell/src/MkdirCommand.java new file mode 100644 index 0000000..0aa0d79 --- /dev/null +++ b/Shell/src/MkdirCommand.java @@ -0,0 +1,39 @@ +import java.io.File; + +public class MkdirCommand implements Command { + + private File curDirectory; + private String nameOfNewDirectory; + private boolean alreadyExist; + + MkdirCommand(File directory, String name) { + curDirectory = directory; + nameOfNewDirectory = name; + alreadyExist = false; + } + + @Override + public File execute() throws WrongCommand { + File file = new File(curDirectory.toString() + File.separator + nameOfNewDirectory); + alreadyExist = !file.mkdir(); + if (alreadyExist) { + System.out.println("Directory already exists. Nothing to be done."); + } + return curDirectory; + } + + @Override + public File cancel() { + if (!alreadyExist) { + File file = new File(curDirectory.toString() + File.separator + nameOfNewDirectory); + file.delete(); + } + return curDirectory; + } + + @Override + public String name() { + return "mkdir"; + } + +} diff --git a/Shell/src/MvCommand.java b/Shell/src/MvCommand.java new file mode 100644 index 0000000..5e1fc2a --- /dev/null +++ b/Shell/src/MvCommand.java @@ -0,0 +1,50 @@ +import java.io.File; +import java.io.IOException; + +public class MvCommand implements Command { + + private File curDirectory; + private String source; + private CpCommand copying; + + MvCommand(File directory, String destination, String source) { + curDirectory = directory; + this.source = source; + copying = new CpCommand(curDirectory, destination, source); + } + + @Override + public File execute() throws WrongCommand { + try { + copying.execute(); + new File(source).delete(); + System.out.println("Original source has been deleted."); + } catch (WrongCommand e) { + System.out.println(e.getMessage()); + } + return curDirectory; + } + + @Override + public File cancel() throws WrongCommand { + copying.cancel(); + File file = new File(source); + if (file.isDirectory()) { + file.mkdir(); + } else { + try { + file.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + System.out.println(file.getName() + " file has been recovered."); + return curDirectory; + } + + @Override + public String name() { + return "mv"; + } + +} diff --git a/Shell/src/RedoCommand.java b/Shell/src/RedoCommand.java new file mode 100644 index 0000000..d538ba6 --- /dev/null +++ b/Shell/src/RedoCommand.java @@ -0,0 +1,33 @@ +import java.io.File; +import java.util.LinkedList; + +public class RedoCommand implements Command { + + private File curDirectory; + private Command prevCommand; + private LinkedList history; + + RedoCommand(File directory, Command command, LinkedList commands) { + curDirectory = directory; + prevCommand = command; + history = commands; + } + + @Override + public File execute() throws WrongCommand, SessionClosed { + history.add(prevCommand); + return prevCommand.execute(); + } + + @Override + public File cancel() { + //do nothing + return curDirectory; + } + + @Override + public String name() { + return "redo"; + } + +} diff --git a/Shell/src/SessionClosed.java b/Shell/src/SessionClosed.java new file mode 100644 index 0000000..dda69c9 --- /dev/null +++ b/Shell/src/SessionClosed.java @@ -0,0 +1,5 @@ +class SessionClosed extends Exception { + SessionClosed(String message) { + super(message); + } +} diff --git a/Shell/src/UndoCommand.java b/Shell/src/UndoCommand.java new file mode 100644 index 0000000..9c17898 --- /dev/null +++ b/Shell/src/UndoCommand.java @@ -0,0 +1,33 @@ +import java.io.File; +import java.util.LinkedList; + +public class UndoCommand implements Command { + + private File curDirectory; + private Command prevCommand; + private LinkedList trash; + + UndoCommand(File directory, Command command, LinkedList commands) { + curDirectory = directory; + prevCommand = command; + trash = commands; + } + + @Override + public File execute() throws WrongCommand { + trash.add(prevCommand); + return prevCommand.cancel(); + } + + @Override + public File cancel() { + //do nothing + return curDirectory; + } + + @Override + public String name() { + return "undo"; + } + +} diff --git a/Shell/src/WrongCommand.java b/Shell/src/WrongCommand.java new file mode 100644 index 0000000..33131a4 --- /dev/null +++ b/Shell/src/WrongCommand.java @@ -0,0 +1,5 @@ +class WrongCommand extends Exception { + WrongCommand(String message) { + super(message); + } +} From 5988eb50affdf9a9f54020ef53281881c9004894 Mon Sep 17 00:00:00 2001 From: David Date: Wed, 17 May 2017 12:34:58 +0300 Subject: [PATCH 14/14] Remove unneseccary --- SoftCache/.gitignore | 1 - SoftCache/pom.xml | 100 ---------------- SoftCache/src/main/java/maven/Cache.java | 23 ---- .../src/main/java/maven/SoftCacheMap.java | 111 ------------------ .../src/main/resources/log4j2.properties | 7 -- .../src/test/java/maven/SoftCacheMapTest.java | 93 --------------- 6 files changed, 335 deletions(-) delete mode 100644 SoftCache/.gitignore delete mode 100644 SoftCache/pom.xml delete mode 100644 SoftCache/src/main/java/maven/Cache.java delete mode 100644 SoftCache/src/main/java/maven/SoftCacheMap.java delete mode 100644 SoftCache/src/main/resources/log4j2.properties delete mode 100644 SoftCache/src/test/java/maven/SoftCacheMapTest.java diff --git a/SoftCache/.gitignore b/SoftCache/.gitignore deleted file mode 100644 index ffd2a4a..0000000 --- a/SoftCache/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.idea diff --git a/SoftCache/pom.xml b/SoftCache/pom.xml deleted file mode 100644 index d2a7ca6..0000000 --- a/SoftCache/pom.xml +++ /dev/null @@ -1,100 +0,0 @@ - - - - 4.0.0 - - maven - softCache - jar - 1.0 - - A Camel Route - - - UTF-8 - UTF-8 - - - - - - - org.apache.camel - camel-parent - 2.18.3 - import - pom - - - - - - - - org.apache.camel - camel-core - - - - - org.apache.logging.log4j - log4j-api - runtime - - - org.apache.logging.log4j - log4j-core - runtime - - - org.apache.logging.log4j - log4j-slf4j-impl - runtime - - - - - org.apache.camel - camel-test - test - - - - - install - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.5.1 - - 1.8 - 1.8 - - - - org.apache.maven.plugins - maven-resources-plugin - 3.0.1 - - UTF-8 - - - - - - org.codehaus.mojo - exec-maven-plugin - 1.5.0 - - maven.MainApp - false - - - - - - - diff --git a/SoftCache/src/main/java/maven/Cache.java b/SoftCache/src/main/java/maven/Cache.java deleted file mode 100644 index ab5fcb1..0000000 --- a/SoftCache/src/main/java/maven/Cache.java +++ /dev/null @@ -1,23 +0,0 @@ -package maven; - -public interface Cache { - /** - * Возвращает соответствующее значение, если оно ещё в кэше, иначе null - */ - V getIfPresent(K key); - - /** - * Сохраняет value по соответствующему ключу key - */ - void put(K key, V value); - - /** - * Удаляет соответствующее ключу key значение - */ - V remove(K key); - - /** - * Очищает кэш - */ - void clear(); -} diff --git a/SoftCache/src/main/java/maven/SoftCacheMap.java b/SoftCache/src/main/java/maven/SoftCacheMap.java deleted file mode 100644 index 4b4616c..0000000 --- a/SoftCache/src/main/java/maven/SoftCacheMap.java +++ /dev/null @@ -1,111 +0,0 @@ -package maven; - -import java.lang.ref.ReferenceQueue; -import java.lang.ref.SoftReference; -import java.util.Deque; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; - -public class SoftCacheMap implements Cache { - - private HashMap> cache; - private HashMap, HashSet> subsidiaryMap; - private ReferenceQueue referenceQueue; - private Deque recentlyUsed; - private int maxSize; - private int cleaningFrequency; - private int numOfPuts; - - protected SoftCacheMap(int size, int frequency) { - cache = new HashMap<>(); - /** - * второй hashMap - вспомогательный, используется при удалении из кэша - * тех ссылок, которые попали в referenceQueue. Чтобы не искать все ключи, - * соответствующие одной ссылке, храню Set из таких ключей в качестве значения - * во втором hashMap-e. - */ - subsidiaryMap = new HashMap<>(); - referenceQueue = new ReferenceQueue<>(); - recentlyUsed = new LinkedList<>(); - maxSize = size; - cleaningFrequency = frequency; - numOfPuts = 0; - } - - private void putInQueue(V object) { - if (maxSize > 0) { - if (object != null) { - recentlyUsed.remove(object); - if (recentlyUsed.size() < maxSize) { - recentlyUsed.addLast(object); - } else { - recentlyUsed.addLast(object); - recentlyUsed.removeFirst(); - } - } - } - } - - - private void clean() { - boolean done = false; - while (!done) { - SoftReference reference = (SoftReference) referenceQueue.poll(); - if (reference != null) { - if (subsidiaryMap.containsKey(reference)) { - HashSet localSet = subsidiaryMap.remove(reference); - for (K local : localSet) { - if (reference.get() == null) { - cache.remove(local); - } - } - } - } else { - done = true; - } - } - } - - @Override - public V getIfPresent(K key) { - if (cache.containsKey(key)) { - putInQueue(cache.get(key).get()); - return cache.get(key).get(); - } - return null; - } - - @Override - public void put(K key, V value) { - ++numOfPuts; - SoftReference reference = new SoftReference<>(value, referenceQueue); - cache.put(key, reference); - putInQueue(value); - if (subsidiaryMap.containsKey(reference)) { - subsidiaryMap.get(reference).add(key); - } else { - subsidiaryMap.put(reference, new HashSet<>()); - subsidiaryMap.get(reference).add(key); - } - if (numOfPuts % cleaningFrequency == 0) { - clean(); - } - } - - @Override - public V remove(K key) { - if ((cache.containsKey(key)) && (cache.get(key).get() != null)) { - subsidiaryMap.remove(cache.get(key)); - return cache.remove(key).get(); - } - return null; - } - - @Override - public void clear() { - cache.clear(); - subsidiaryMap.clear(); - } - -} diff --git a/SoftCache/src/main/resources/log4j2.properties b/SoftCache/src/main/resources/log4j2.properties deleted file mode 100644 index 328db35..0000000 --- a/SoftCache/src/main/resources/log4j2.properties +++ /dev/null @@ -1,7 +0,0 @@ - -appender.out.type = Console -appender.out.name = out -appender.out.layout.type = PatternLayout -appender.out.layout.pattern = [%30.30t] %-30.30c{1} %-5p %m%n -rootLogger.level = INFO -rootLogger.appenderRef.out.ref = out diff --git a/SoftCache/src/test/java/maven/SoftCacheMapTest.java b/SoftCache/src/test/java/maven/SoftCacheMapTest.java deleted file mode 100644 index 4cfd06a..0000000 --- a/SoftCache/src/test/java/maven/SoftCacheMapTest.java +++ /dev/null @@ -1,93 +0,0 @@ -package maven; - -import org.junit.Assert; -import org.junit.Test; -import java.util.ArrayList; -import java.util.Arrays; - -public class SoftCacheMapTest { - - private SoftCacheMap getCache(int size, int frequency) { - return new SoftCacheMap<>(size, frequency); - } - - private void testBefore(int size, int frequency, ArrayList values, - ArrayList expectedBefore) throws Exception { - - String errorMessage = "Bad result"; - SoftCacheMap cache = getCache(size, frequency); - for (int i = 0; i < values.size(); ++i) { - cache.put(i, values.get(i)); - } - for (int i = 0; i < values.size(); ++i) { - Assert.assertEquals(errorMessage, expectedBefore.get(i), cache.getIfPresent(i)); - } - } - - private void testAfter(int size, int frequency, ArrayList values, - ArrayList expectedAfter) { - String errorMessage = "Bad result"; - SoftCacheMap cache = getCache(size, frequency); - for (int i = 0; i < values.size(); ++i) { - cache.put(i, new Integer(values.get(i))); - } - try { - Object[] big = new Object[(int) Runtime.getRuntime().maxMemory()]; - } catch (OutOfMemoryError e) { - // ignore - } - - int counter = 0; - for (int i = 0; i < values.size(); ++i) { - if (cache.getIfPresent(i) != null) { - Assert.assertEquals(errorMessage, expectedAfter.get(counter), cache.getIfPresent(i)); - ++counter; - } - } - } - - @Test - public void testReferenceQueueBefore() throws Exception { - ArrayList values = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5)); - ArrayList expectedBefore = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5)); - testBefore(0, 1, values, expectedBefore); - } - - @Test - public void testReferenceQueueAfter() throws Exception { - ArrayList values = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5)); - testAfter(0, 1, values, null); - } - - @Test - public void testRecentlyUsedQueueAfter0() throws Exception { - ArrayList values = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5)); - ArrayList expectedAfter = new ArrayList<>(Arrays.asList(4, 5)); - testAfter(2, 1, values, expectedAfter); - } - - @Test - public void testRecentlyUsedQueueAfter1() throws Exception { - ArrayList values = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5)); - ArrayList expectedAfter = new ArrayList<>(Arrays.asList(2, 5)); - String errorMessage = "Bad result"; - SoftCacheMap cache = getCache(2, 1); - for (int i = 0; i < values.size(); ++i) { - cache.put(i, new Integer(values.get(i))); - } - cache.getIfPresent(2); - try { - Object[] big = new Object[(int) Runtime.getRuntime().maxMemory()]; - } catch (OutOfMemoryError e) { - // ignore - } - - int counter = 0; - for (int i = 0; i < values.size(); ++i) { - if (cache.getIfPresent(i) != null) { - Assert.assertEquals(errorMessage, expectedAfter.get(counter), cache.getIfPresent(i)); - ++counter; - } - } - } -}