forked from dracome/coding2017
-
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.
Merge pull request onlyliuxin#51 from Wrecksoul/master
完成jvm第一次作业与LRU
- Loading branch information
Showing
5 changed files
with
382 additions
and
0 deletions.
There are no files selected for viewing
104 changes: 104 additions & 0 deletions
104
group17/82427129/JavaUtil/src/main/java/com/coderising/jvm/loader/ClassFileLoader.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 |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package com.coderising.jvm.loader; | ||
|
||
import java.io.ByteArrayOutputStream; | ||
import java.io.File; | ||
import java.io.FileInputStream; | ||
import java.io.FileNotFoundException; | ||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class ClassFileLoader { | ||
private static final int BUFFERSIZE = 1024; | ||
private List<String> clzPaths = new ArrayList<String>(); | ||
|
||
public byte[] readBinaryCode(String className) { | ||
if (clzPaths.size()<=0){ | ||
return null; | ||
} | ||
for (int i = 0; i < clzPaths.size(); i++) { | ||
String path = clzPaths.get(i) + convertName(className); | ||
File f = new File(path); | ||
if(f.exists()){ | ||
try { | ||
return readFile(f); | ||
} catch (FileNotFoundException e) { | ||
e.printStackTrace(); | ||
} | ||
}else{ | ||
f = null; | ||
continue; | ||
} | ||
} | ||
System.err.println("classpath:" +getClassPath()+ "class:" + convertName(className)+" not found."); | ||
return null; | ||
} | ||
/** | ||
* 文件读取二进制字节流 | ||
* @param f | ||
* @return | ||
* @throws FileNotFoundException | ||
*/ | ||
private byte[] readFile(File f) throws FileNotFoundException { | ||
FileInputStream fis = new FileInputStream(f); | ||
ByteArrayOutputStream baos = new ByteArrayOutputStream(); | ||
byte[] b = new byte[BUFFERSIZE]; | ||
try { | ||
int len = 0; | ||
while((len = fis.read(b))!=-1){ | ||
baos.write(b,0,len); | ||
} | ||
} catch (IOException e) { | ||
e.printStackTrace(); | ||
} finally{ | ||
try { | ||
fis.close(); | ||
baos.flush(); | ||
baos.close(); | ||
} catch (IOException e) { | ||
e.printStackTrace(); | ||
} | ||
|
||
} | ||
return baos.toByteArray(); | ||
} | ||
|
||
public void addClassPath(String path) { | ||
clzPaths.add(path); | ||
} | ||
|
||
public String getClassPath() { | ||
StringBuilder sb = new StringBuilder(); | ||
for (int i = 0; i < clzPaths.size(); i++) { | ||
sb.append(clzPaths.get(i)).append(";"); | ||
} | ||
int len = sb.length(); | ||
if(len!=0){ | ||
sb.deleteCharAt(len-1); | ||
} | ||
return sb.toString(); | ||
} | ||
|
||
/** | ||
* convert className to FilePath style className <br/> | ||
* For example:com.sun.lang to \com\sun\lang | ||
* | ||
* @param className | ||
* @return FilePath style className | ||
*/ | ||
private String convertName(String className) { | ||
StringBuilder sb = new StringBuilder(); | ||
String[] pack = className.split("\\."); | ||
for (int i = 0; i < pack.length; i++) { | ||
sb.append("\\").append(pack[i]); | ||
} | ||
sb.append(".class"); | ||
return sb.toString(); | ||
} | ||
|
||
public static void main(String[] args) { | ||
String d = "com.taiji.array.Load"; | ||
ClassFileLoader cc = new ClassFileLoader(); | ||
System.out.print(cc.convertName(d)); | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
group17/82427129/JavaUtil/src/main/java/com/coderising/jvm/test/EmployeeV1.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 |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package com.coderising.jvm.test; | ||
|
||
public class EmployeeV1 { | ||
private String name; | ||
private int age; | ||
|
||
public EmployeeV1(String name, int age) { | ||
this.name = name; | ||
this.age = age; | ||
} | ||
|
||
public void setName(String name) { | ||
this.name = name; | ||
} | ||
|
||
public void setAge(int age) { | ||
this.age = age; | ||
} | ||
|
||
public void sayHello() { | ||
System.out.println("Hello , this is class Employee "); | ||
} | ||
|
||
public static void main(String[] args) { | ||
EmployeeV1 p = new EmployeeV1("Andy", 29); | ||
p.sayHello(); | ||
|
||
} | ||
} |
147 changes: 147 additions & 0 deletions
147
group17/82427129/JavaUtil/src/main/java/com/coding/basic/LRU/LRUPageFrame.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 |
---|---|---|
@@ -0,0 +1,147 @@ | ||
package com.coding.basic.LRU; | ||
|
||
public class LRUPageFrame { | ||
private int capacity; | ||
private Node first;// 链表头 | ||
private Node last;// 链表尾 | ||
private int length = 0; | ||
|
||
public LRUPageFrame(int capacity) { | ||
this.capacity = capacity; | ||
} | ||
|
||
/** | ||
* 获取缓存中对象 | ||
* | ||
* @param key | ||
* @return | ||
*/ | ||
public void access(int pageNum) { | ||
// this loop select for pageNum,grow it first when 'found'. | ||
for (Node n = first; n != null; n = n.next) { | ||
if (n.pageNum == pageNum) { | ||
growFirst(n); | ||
return; | ||
} | ||
} | ||
// if didn't found it | ||
if (ensureFull()) { | ||
removeLast(); | ||
} | ||
add(pageNum); | ||
} | ||
|
||
private void add(int pageNum) { | ||
if (isEmpty()) { | ||
Node newNode = new Node(null, null, pageNum); | ||
first = newNode; | ||
last = newNode; | ||
length++; | ||
} else { | ||
addToFirst(pageNum); | ||
} | ||
} | ||
|
||
private void addToFirst(int pageNum) { | ||
Node newNode = new Node(null, null, pageNum); | ||
newNode.next = first; | ||
first.prev = newNode; | ||
first = newNode; | ||
length++; | ||
} | ||
|
||
/** | ||
* ensure the LRUPageFrame is full or Not | ||
* | ||
* @return if full return true,else false | ||
*/ | ||
private boolean ensureFull() { | ||
if (length < capacity) { | ||
return false; | ||
} else { | ||
return true; | ||
} | ||
} | ||
|
||
/** | ||
* grow the Node'position to first | ||
* | ||
* @param n | ||
*/ | ||
private void growFirst(Node n) { | ||
// if the node is already first ,return. | ||
if (first.pageNum == n.pageNum) { | ||
return; | ||
} | ||
remove(n); | ||
addToFirst(n.pageNum); | ||
} | ||
|
||
private void remove(Node n) { | ||
if (isEmpty()) { | ||
return; | ||
} | ||
if (n.next == null) { | ||
removeLast(); | ||
return; | ||
} | ||
if (n.prev == null) { | ||
removeFirst(); | ||
return; | ||
} | ||
Node prev = n.prev; | ||
Node next = n.next; | ||
n.next = null; | ||
n.prev = null; | ||
prev.next = next; | ||
next.prev = prev; | ||
length--; | ||
} | ||
|
||
private void removeFirst() { | ||
Node next = first.next; | ||
first.next = null; | ||
first = next; | ||
} | ||
|
||
private void removeLast() { | ||
Node prev = last.prev; | ||
prev.next = null; | ||
last.prev = null; | ||
last = prev; | ||
length--; | ||
} | ||
/** | ||
* ensure the LRUPageFrame is empty or Not. | ||
* @return | ||
*/ | ||
public boolean isEmpty() { | ||
return length < 1; | ||
} | ||
|
||
public String toString() { | ||
StringBuilder buffer = new StringBuilder(); | ||
Node node = first; | ||
while (node != null) { | ||
buffer.append(node.pageNum); | ||
|
||
node = node.next; | ||
if (node != null) { | ||
buffer.append(","); | ||
} | ||
} | ||
return buffer.toString(); | ||
} | ||
|
||
private static class Node { | ||
Node prev; | ||
Node next; | ||
int pageNum; | ||
|
||
Node(Node prev, Node next, int pageNum) { | ||
this.prev = prev; | ||
this.next = next; | ||
this.pageNum = pageNum; | ||
} | ||
} | ||
} |
73 changes: 73 additions & 0 deletions
73
group17/82427129/JavaUtil/src/test/java/com/coderising/jvm/loader/ClassFileLoaderTest.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 |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package com.coderising.jvm.loader; | ||
|
||
import org.junit.After; | ||
import org.junit.Assert; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
public class ClassFileLoaderTest { | ||
static String path1 = "C:\\Users\\liuxin\\git\\coding2017\\liuxin\\mini-jvm\\bin"; | ||
static String path2 = "D:\\workProgram\\GitRepo\\coding2017\\group17\\82427129\\JavaUtil\\target\\classes"; | ||
@Before | ||
public void setUp() throws Exception { | ||
} | ||
|
||
@After | ||
public void tearDown() throws Exception { | ||
} | ||
|
||
@Test | ||
public void testClassFileLength() { | ||
|
||
ClassFileLoader loader = new ClassFileLoader(); | ||
loader.addClassPath(path2); | ||
|
||
String className = "com.coderising.jvm.test.EmployeeV1"; | ||
|
||
byte[] byteCodes = loader.readBinaryCode(className); | ||
|
||
// 注意:这个字节数可能和你的JVM版本有关系, 你可以看看编译好的类到底有多大 | ||
Assert.assertEquals(1056, byteCodes.length); | ||
|
||
} | ||
|
||
@Test | ||
public void testGetClassPath() { | ||
ClassFileLoader loader = new ClassFileLoader(); | ||
loader.addClassPath(path1); | ||
loader.addClassPath(path2); | ||
|
||
String clzPath = loader.getClassPath(); | ||
|
||
Assert.assertEquals(path1+";"+path2,clzPath); | ||
} | ||
|
||
@Test | ||
public void testMagicNumber(){ | ||
ClassFileLoader loader = new ClassFileLoader(); | ||
loader.addClassPath(path2); | ||
String className = "com.coderising.jvm.test.EmployeeV1"; | ||
byte[] byteCodes = loader.readBinaryCode(className); | ||
byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]}; | ||
|
||
|
||
String acctualValue = this.byteToHexString(codes); | ||
|
||
Assert.assertEquals("cafebabe", acctualValue); | ||
} | ||
|
||
private String byteToHexString(byte[] codes) { | ||
StringBuffer buffer = new StringBuffer(); | ||
for (int i = 0; i < codes.length; i++) { | ||
byte b = codes[i]; | ||
int value = b & 0xFF; | ||
String strHex = Integer.toHexString(value); | ||
if (strHex.length() < 2) { | ||
strHex = "0" + strHex; | ||
} | ||
buffer.append(strHex); | ||
} | ||
return buffer.toString(); | ||
} | ||
|
||
} |
29 changes: 29 additions & 0 deletions
29
group17/82427129/JavaUtil/src/test/java/com/coding/basic/LRU/LRUPageFrameTest.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 |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package com.coding.basic.LRU; | ||
|
||
import org.junit.Assert; | ||
import org.junit.Test; | ||
|
||
public class LRUPageFrameTest { | ||
|
||
@Test | ||
public void testAccess() { | ||
LRUPageFrame frame = new LRUPageFrame(3); | ||
frame.access(7); | ||
frame.access(0); | ||
frame.access(1); | ||
Assert.assertEquals("1,0,7", frame.toString()); | ||
frame.access(2); | ||
Assert.assertEquals("2,1,0", frame.toString()); | ||
frame.access(0); | ||
Assert.assertEquals("0,2,1", frame.toString()); | ||
frame.access(0); | ||
Assert.assertEquals("0,2,1", frame.toString()); | ||
frame.access(3); | ||
Assert.assertEquals("3,0,2", frame.toString()); | ||
frame.access(0); | ||
Assert.assertEquals("0,3,2", frame.toString()); | ||
frame.access(4); | ||
Assert.assertEquals("4,0,3", frame.toString()); | ||
} | ||
|
||
} |