Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
Difference between revisions of "EclipseLink/Examples/JPA/Simulation"
< EclipseLink | Examples | JPA
m (→Hierarchy) |
m (→Purpose) |
||
Line 3: | Line 3: | ||
*This sumulation will serve as a ''near real world'' enterprise application that showcases utilizing JPA as the persistence or integration layer - specifically using [http://wiki.eclipse.org/EclipseLink/Examples/JPA EclipseLink JPA] as the provider. | *This sumulation will serve as a ''near real world'' enterprise application that showcases utilizing JPA as the persistence or integration layer - specifically using [http://wiki.eclipse.org/EclipseLink/Examples/JPA EclipseLink JPA] as the provider. | ||
*The software will also showcase the distributed performance capabilities of EclipseLink by using the 1st level cache and an optional 2nd level distributed memory cache in clustered mode. | *The software will also showcase the distributed performance capabilities of EclipseLink by using the 1st level cache and an optional 2nd level distributed memory cache in clustered mode. | ||
+ | *Additionally, the process and result of this analysis will use and showcase an example UML based design approach. | ||
*This enterprise application will offer the services of a simulated connection machine ''(Ref: [http://en.wikipedia.org/wiki/Connection_Machine Thinking Machines CM-2], MIT Cosmic Cube, Burroughs Illiac IV etc.)'' symbolic vector processor. | *This enterprise application will offer the services of a simulated connection machine ''(Ref: [http://en.wikipedia.org/wiki/Connection_Machine Thinking Machines CM-2], MIT Cosmic Cube, Burroughs Illiac IV etc.)'' symbolic vector processor. | ||
**Why are we choosing an older architecture to simulate? | **Why are we choosing an older architecture to simulate? |
Revision as of 11:19, 13 April 2010
Contents
Simulation JPA Application Example
Purpose
- This sumulation will serve as a near real world enterprise application that showcases utilizing JPA as the persistence or integration layer - specifically using EclipseLink JPA as the provider.
- The software will also showcase the distributed performance capabilities of EclipseLink by using the 1st level cache and an optional 2nd level distributed memory cache in clustered mode.
- Additionally, the process and result of this analysis will use and showcase an example UML based design approach.
- This enterprise application will offer the services of a simulated connection machine (Ref: Thinking Machines CM-2, MIT Cosmic Cube, Burroughs Illiac IV etc.) symbolic vector processor.
- Why are we choosing an older architecture to simulate?
- a) The architecture is very clean and even though it is very large - is simple enough to implement.
- b) The Design by Danny Hillis in his dissertation is out of print as of 2005 and Thinking Machines no longer exists in whole but was partially acquired by Oracle - so we are free to simulate the device.
- b) The design is proven and static - as it has been superceeded by more powerfull designs).
- c) The massively parallel processing design of the CM-2 matches our goal of utilizing parallelism at both the thread and multi-core processor level on our host machine.
- Why are we choosing an older architecture to simulate?
Goals
- We would like to explore the following limits of the JPA provider and hosting application server.
- Performance and Volumetrics: We require 65536 processor objects.
Infrastructure
- OS: Windows XP or Vista 32/64 bit
- Database: Oracle 11gR1
- JPA provider: EclipseLink 1.2
- JDK: Sun 1.6.0_14
Analysis
Data Model
Processor Architecture
- Each CM-2 processor is composed of up to 64k (65536) 1-bit processors arranged in a 12-dimensional hypercube.
- There are 16 1-bit processors per chip along with 1 routing processor per chip.
- There are 32 cpu chips and 32 ram chips per backplane board
- There are 16 boards per quadrant
- There are 8 quadrands to a CM-2
- There are 16 boards per quadrant
- There are 32 cpu chips and 32 ram chips per backplane board
- We therefore have (2^4=16) x (2^5=32) x (2^4=16) x (2^3=8) = 2^16 = 65536 possible processors in a fully configured system.
- There are 16 1-bit processors per chip along with 1 routing processor per chip.
Static Class Hierarchy
- Hypercube (quadrants(1:M), input, output, program)
- Quadrant (boards(1:M), hypercube(1:1))
- Board (processorChips(1:M), ramChips(1:M))
- Chip(A)
- ProcessorChip (processors (1:M), router (1:1))
- MemoryChip
- Processor(A)
- VectorProcessor(alu, stateMachine, uProgram)
- RouterProcessor (routers(1:M))
Design
JPA Data Model
Board.java
@Entity @Table(name="CM_BOARD") public class Board implements Serializable { @Id @GeneratedValue(strategy=TABLE, generator="BOARD_CM_TABLE_GENERATOR") @TableGenerator( name="BOARD_CM_TABLE_GENERATOR", table="CM_BOARD_SEQ", pkColumnName="SEQ_CM_NAME", valueColumnName="SEQ_CM_COUNT", pkColumnValue="CUST_CM_SEQ" ) @Column(name="BOARD_ID") private Integer id; @Version @Column(name="BOARD_VERSION") private int version; // If a JoinTable with a JoinColumn is used - then we need a mappedBy on the inverse side here @OneToMany(cascade=ALL, mappedBy="board") private List<ProcessorChip> processorChips = new ArrayList<ProcessorChip>(); // The M:1 side is the owning side @ManyToOne(fetch=EAGER)//LAZY) @JoinTable(name="CM_QUADRANT_CM_BOARD", joinColumns = @JoinColumn(name="BOARD_ID"), inverseJoinColumns =@JoinColumn(name="QUADRANT_ID")) private Quadrant quadrant; public List<VectorProcessor> getVectorProcessors() { List<VectorProcessor> allProcessors = new ArrayList<VectorProcessor>(); for(ProcessorChip aProcessorChip : processorChips) { allProcessors.addAll(aProcessorChip.getVectorProcessors()); } return allProcessors; }
Chip.java
@MappedSuperclass public abstract class Chip implements Serializable { @Id @GeneratedValue(strategy=TABLE, generator="CHIP_CM_TABLE_GENERATOR") @TableGenerator( name="CHIP_CM_TABLE_GENERATOR", table="CM_CHIP_SEQ", pkColumnName="SEQ_CM_NAME", valueColumnName="SEQ_CM_COUNT", pkColumnValue="CUST_CM_SEQ" ) @Column(name="CHIP_ID") private Integer id; // The M:1 side is the owning side @ManyToOne(fetch=EAGER)//LAZY) @JoinTable(name="CM_BOARD_CM_CHIP", joinColumns = @JoinColumn(name="CHIP_ID"), inverseJoinColumns =@JoinColumn(name="BOARD_ID")) private Board board;
Hypercube.java
@Entity @Table(name="CM_HYPERCUBE") public class Hypercube implements Serializable { @Id @GeneratedValue(strategy=TABLE, generator="HYPERCUBE_CM_TABLE_GENERATOR") @TableGenerator( name="HYPERCUBE_CM_TABLE_GENERATOR", table="CM_HYPERCUBE_SEQ", pkColumnName="SEQ_CM_NAME", valueColumnName="SEQ_CM_COUNT", pkColumnValue="CUST_CM_SEQ" ) @Column(name="HYPERCUBE_ID") private Integer id; // If a JoinTable with a JoinColumn is used - then we need a mappedBy on the inverse side here @OneToMany(cascade=ALL, mappedBy="hypercube") private List<Quadrant> quadrants = new ArrayList<Quadrant>(); public List<VectorProcessor> getVectorProcessors() { List<VectorProcessor> allProcessors = new ArrayList<VectorProcessor>(); for(Quadrant aQuadrant : quadrants) { allProcessors.addAll(aQuadrant.getVectorProcessors()); } return allProcessors; }
Processor.java
@MappedSuperclass public abstract class Processor implements Serializable { @Id @GeneratedValue(strategy=TABLE, generator="PROCESSOR_CM_TABLE_GENERATOR") @TableGenerator( name="PROCESSOR_CM_TABLE_GENERATOR", table="CM_PROCESSOR_SEQ", pkColumnName="SEQ_CM_NAME", valueColumnName="SEQ_CM_COUNT", pkColumnValue="CUST_CM_SEQ" ) @Column(name="PROCESSOR_ID") private Integer id;
ProcessorChip.java
@Entity @Table(name="CM_PROCESSORCHIP") public class ProcessorChip extends Chip implements Serializable { private List<Boolean> stateMachine; private boolean input; private boolean output; private ProcessorChip leftChip; private ProcessorChip rightChip; private ProcessorChip upChip; @OneToOne @JoinColumn(name="PROCESSOR_ID") private ProcessorChip downChip; // If a JoinTable with a JoinColumn is used - then we need a mappedBy on the inverse side here @OneToMany(cascade=ALL, mappedBy="besideProcessorChip") private List<ProcessorChip> adjacentChips = new ArrayList<ProcessorChip>(); // The M:1 side is the owning side @ManyToOne(fetch=EAGER)//LAZY) @JoinTable(name="CM_PROCESSOR_CM_PROCESSOR", joinColumns = @JoinColumn(name="PROCESSOR_ID"), inverseJoinColumns =@JoinColumn(name="PROCESSOR_ID")) private ProcessorChip besideProcessorChip; // If a JoinTable with a JoinColumn is used - then we need a mappedBy on the inverse side here @OneToMany(cascade=ALL, mappedBy="processorChip") private List<VectorProcessor> vectorProcessors = new ArrayList<VectorProcessor>();
Quadrant.java
@Entity @Table(name="CM_QUADRANT") public class Quadrant implements Serializable { @Id @GeneratedValue(strategy=TABLE, generator="QUADRANT_CM_TABLE_GENERATOR") @TableGenerator( name="QUADRANT_CM_TABLE_GENERATOR", table="CM_QUADRANT_SEQ", pkColumnName="SEQ_CM_NAME", valueColumnName="SEQ_CM_COUNT", pkColumnValue="CUST_CM_SEQ" ) @Column(name="QUADRANT_ID") private Integer id; // If a JoinTable with a JoinColumn is used - then we need a mappedBy on the inverse side here @OneToMany(cascade=ALL, mappedBy="quadrant") private List<Board> boards = new ArrayList<Board>(); // The M:1 side is the owning side @ManyToOne(fetch=EAGER)//LAZY) @JoinTable(name="CM_HYPERCUBE_CM_QUADRANT", joinColumns = @JoinColumn(name="QUADRANT_ID"), inverseJoinColumns =@JoinColumn(name="HYPERCUBE_ID")) private Hypercube hypercube; public List<VectorProcessor> getVectorProcessors() { List<VectorProcessor> allProcessors = new ArrayList<VectorProcessor>(); for(Board aBoard : boards) { allProcessors.addAll(aBoard.getVectorProcessors()); } return allProcessors; }
VectorProcessor.java
@Entity @Table(name="CM_VECTORPROCESSOR") public class VectorProcessor extends Processor implements Serializable { // The M:1 side is the owning side @ManyToOne(fetch=EAGER)//LAZY) @JoinTable(name="CM_CHIP_CM_PROCESSOR", joinColumns = @JoinColumn(name="PROCESSOR_ID"), inverseJoinColumns =@JoinColumn(name="CHIP_ID")) private ProcessorChip processorChip;
CM2Console.java
- This is a minimum Java SE JPA client
package org.eclipse.persistence.example.jpa.cm.presentation; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Persistence; import javax.persistence.metamodel.Metamodel; import org.eclipse.persistence.example.jpa.cm.business.Board; import org.eclipse.persistence.example.jpa.cm.business.Hypercube; import org.eclipse.persistence.example.jpa.cm.business.ProcessorChip; import org.eclipse.persistence.example.jpa.cm.business.Quadrant; import org.eclipse.persistence.example.jpa.cm.business.VectorProcessor; import org.eclipse.persistence.example.jpa.cm.integration.CM2; public class CM2Console { CM2 connectionMachine; public CM2Console() { connectionMachine = new CM2(); } public CM2 getConnectionMachine() { return connectionMachine; } public void setConnectionMachine(CM2 connectionMachine) { this.connectionMachine = connectionMachine; } // Application managed EMF and EM public EntityManagerFactory emf = null; public EntityManager entityManager = null; // Reference the database specific persistence unit in persistence.xml public static final String PU_NAME_CREATE = "CMJPA_create"; /** * Create the EMF and EM and start a transaction (out of container context) * @param puName */ private void initialize(String puName) { try { // Initialize an application managed JPA emf and em via META-INF emf = Persistence.createEntityManagerFactory(puName); entityManager = emf.createEntityManager(); } catch (Exception e) { e.printStackTrace(); } } /** * Close the application managed EM and EMF */ @Override public void finalize() { // close JPA try { if(null != getEntityManager()) { getEntityManager().close(); getEmf().close(); } } catch (Exception e) { e.printStackTrace(); } } private void populate(PrintWriter out) { // register atomic entities first before creating relationships try { EntityManager em = getEntityManager(); if(null == em) { System.out.println("EntityManager is null: Check your persistence.xml properties"); } else { EntityTransaction transaction = em.getTransaction(); if(null == transaction) { System.out.println("Cannot get a transaction from entityManager: " + em); } else { transaction.begin(); // Insert schema and classes into the database CM2 cm2 = new CM2(); // 1 Hypercube Hypercube hypercube = new Hypercube(); // 8 Quadrants List<Quadrant> quadrants = new ArrayList<Quadrant>(); for(int i=0; i<8; i++) { Quadrant aQuadrant = new Quadrant(); aQuadrant.setHypercube(hypercube); quadrants.add(aQuadrant); // 16 Backplane Boards List<Board> boards = new ArrayList<Board>(); for(int j=0; j<16; j++) { Board aBoard = new Board(); aBoard.setQuadrant(aQuadrant); boards.add(aBoard); // 32 processor chips per board List<ProcessorChip> chips = new ArrayList<ProcessorChip>(); for(int k=0; k<32; k++) { ProcessorChip aChip = new ProcessorChip(); aChip.setBoard(aBoard); chips.add(aChip); // 16 vector processors per chip List<VectorProcessor> processors = new ArrayList<VectorProcessor>(); for(int l=0; l<16; l++) { VectorProcessor aProcessor = new VectorProcessor(); aProcessor.setProcessorChip(aChip); processors.add(aProcessor); em.merge(aProcessor); } aChip.setProcessors(processors); em.merge(aChip); } aBoard.setChips(chips); em.merge(aBoard); } aQuadrant.setBoards(boards); em.merge(aQuadrant); } hypercube.setQuadrants(quadrants); cm2.setHypercube(hypercube); em.merge(hypercube); // 8 Quadrants long processorCount = 0; em.persist(hypercube); for(Quadrant aQuadrant : hypercube.getQuadrants()) { em.persist(aQuadrant); // 16 Backplane Boards for(Board aBoard : aQuadrant.getBoards()) { em.persist(aBoard); // 32 processor chips per board for(ProcessorChip aChip : aBoard.getProcessorChips()) { em.persist(aChip); // 16 vector processors per chip for(VectorProcessor aProcessor : aChip.getVectorProcessors()) { //System.out.println("_persisting: " + count++ + " : " + aProcessor); em.persist(aProcessor); processorCount++; } } } } System.out.println("_persisted " + processorCount + " Processor Entities"); System.out.println("_All Processors: " + hypercube.getVectorProcessors().size()); Metamodel aMetamodel = em.getMetamodel(); System.out.println("_Metamodel: " + aMetamodel); } // Store objects transaction.commit(); } } catch (Exception e) { e.printStackTrace(); } } public EntityManagerFactory getEmf() { return emf; } public void setEmf(EntityManagerFactory emf) { this.emf = emf; } public EntityManager getEntityManager() { return entityManager; } public void setEntifyManager(EntityManager entityManager) { this.entityManager = entityManager; } public static void main(String[] args) { CM2Console aConsole = new CM2Console(); aConsole.initialize(PU_NAME_CREATE); aConsole.populate(null); aConsole.finalize(); System.out.println(aConsole.getConnectionMachine()); System.exit(0); } }
Implementation
Schema Model
Persistence Unit
<?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="CMJPA_create" transaction-type="RESOURCE_LOCAL"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <class>org.eclipse.persistence.example.jpa.cm.business.Board</class> <class>org.eclipse.persistence.example.jpa.cm.business.Hypercube</class> <class>org.eclipse.persistence.example.jpa.cm.business.MemoryChip</class> <class>org.eclipse.persistence.example.jpa.cm.business.ProcessorChip</class> <class>org.eclipse.persistence.example.jpa.cm.business.Quadrant</class> <class>org.eclipse.persistence.example.jpa.cm.business.RouterProcessor</class> <class>org.eclipse.persistence.example.jpa.cm.business.VectorProcessor</class> <properties> <property name="eclipselink.jdbc.driver" value="oracle.jdbc.driver.OracleDriver"/> <property name="eclipselink.target-database" value="org.eclipse.persistence.platform.database.oracle.OraclePlatform"/> <property name="eclipselink.jdbc.url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/> <property name="eclipselink.jdbc.user" value="scott"/> <property name="eclipselink.jdbc.password" value="pw"/> <!-- property name="eclipselink.logging.level" value="ALL"/--> <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/> <property name="eclipselink.ddl-generation.output-mode" value="database"/> </properties> </persistence-unit> </persistence>
Testing
- In order to accommidate a 65MB heap size use the JVM parameter
- -Xmx1024m
Console Output
Logs
_persisted 65536 Processor Entities _All Processors: 65536 _Metamodel: MetamodelImpl@31301308 [ 11 Types: , 9 ManagedTypes: , 7 EntityTypes: , 2 MappedSuperclassTypes: , 0 EmbeddableTypes: ] [EL Info]: 2009-09-01 15:52:30.633--ServerSession(23979164)--file:/E:/wse/view_w35a/CM2JPA/bin/-CMJPA_create logout successful org.eclipse.persistence.example.jpa.cm.integration.CM2@2a72b6