Skip to content

Commit 7eb668e

Browse files
fresh commit
0 parents  commit 7eb668e

File tree

114 files changed

+14452
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+14452
-0
lines changed

.clang-format

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
BasedOnStyle: LLVM
2+
IndentWidth: 4
3+
TabWidth: 4
4+
UseTab: Never
5+
ContinuationIndentWidth: 8

.github/workflows/maven.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
2+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven
3+
# This workflow uses actions that are not certified by GitHub.
4+
# They are provided by a third-party and are governed by
5+
# separate terms of service, privacy policy, and support
6+
# documentation.
7+
8+
name: Java CI with Maven
9+
10+
on:
11+
push:
12+
branches: [ "master" ]
13+
pull_request:
14+
branches: [ "master" ]
15+
16+
jobs:
17+
build:
18+
runs-on: ubuntu-latest
19+
20+
env:
21+
LD_LIBRARY_PATH: ./src/main/c/build
22+
23+
steps:
24+
- uses: actions/checkout@v4
25+
26+
- name: Set up JDK 21
27+
uses: actions/setup-java@v4
28+
with:
29+
java-version: '21'
30+
distribution: 'temurin'
31+
cache: maven
32+
33+
- name: Verify JAVA_HOME is set
34+
run: echo "JAVA_HOME is set to $JAVA_HOME"
35+
36+
- name: Install system dependencies
37+
run: |
38+
sudo apt-get update
39+
sudo apt-get install -y cmake clang-format
40+
41+
- name: Install Conan
42+
run: pip install 'conan==2.24.0'
43+
44+
- name: Make build script executable
45+
run: chmod +x tasks.sh
46+
47+
- name: Check dependencies
48+
run: ./tasks.sh check_deps
49+
50+
- name: Compile OGO
51+
run: ./tasks.sh compile
52+
53+
- name: Run tests
54+
run: ./tasks.sh tests

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.venv/
2+
build/
3+
surefire-reports/
4+
target/
5+
.cache/
6+
.vscode/
7+
.ekstazi/
8+
.idea/
9+
src/main/c/generated/

README.md

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
## OGO ##
2+
<img src="images/ogo_logo.png" width="700" />
3+
4+
Object Graph Programming (OGO) enables manipulating the JVM heap
5+
declaratively through queries. The queries are written using the
6+
[Cypher Query Language](https://neo4j.com/developer/cypher/). OGO
7+
supports two high-level modes, $OGO^{Neo}$ and $OGO^{Mem}$. The former
8+
serializes a sub-graph of the entire JVM heap object graph, loads it
9+
into a standalone Neo4J database and executes queries inside it. The
10+
latter executes queries in-memory (inside the native agent) using
11+
[Antlr](https://www.antlr.org/) to parse the query and visitors to
12+
execute it Currently, $OGO^{Mem}$ is under construction and not all
13+
functionalities may work.
14+
15+
## Examples ##
16+
17+
1. Searching an `ArrayList` for a given element.
18+
```java
19+
ArrayList<Long> lst = new ArrayList<Long>();
20+
lst.add(10L);
21+
lst.add(20L);
22+
lst.add(30L);
23+
query("MATCH ({$1})-[:elementData]->()-[]->({value : 20}) RETURN TRUE");
24+
```
25+
In this example, we use imperative code to instantiate and add elements to
26+
an `ArrayList` and then use `Cypher` query through `OGO` to query `lst` to
27+
check if it contains element 20.
28+
29+
2. Implementing the `containsKey` method of `java.util.HashMap` class.
30+
```java
31+
public boolean containsKeyOgoImpl(HashMap map, object key){
32+
queryBool("MATCH ({$1})-[:table]->()-[]->()-[:key]->(n)"
33+
+"MATCH (m {$2})"
34+
+"WHERE n.`equals`(m)"
35+
+"RETURN COUNT(n) <> 0", map, key);
36+
}
37+
```
38+
In this example, the first `MATCH` clause matches a pattern that collects
39+
all the objects corresponding to the `key` field of `HashMap's` inner class
40+
`Node` into the variable `n`. The second `MATCH` clause collects the given key
41+
object into the variable `m`. The `WHERE` clause filters the elements of `n`
42+
based on the output of the `java.lang.Object` class's `equals` method evaluating to
43+
true for pairwise inputs from `n` and `m`. This predicate is expected to filter number of
44+
elements of `n` to 1 if the given key is present in the `map` and to 0 if absent.
45+
Finally, we use the `RETURN` clause to return the value of the expression that
46+
compares equality of number of elements of `n` to 0. The query is hence expected to
47+
return true iff the number of elements in `n` is non-zero which is true only if the
48+
given key is contained in `map`.
49+
50+
51+
## Getting Started ##
52+
53+
### Prerequisites
54+
The project requires the following dependencies:
55+
- **Maven**
56+
- **Java 21**
57+
- **Conan 2.24.0**
58+
- **CMake**
59+
- **Clang Format**
60+
61+
### Installation
62+
63+
#### 1. Install Dependencies
64+
Run the installation script to automatically install all required dependencies:
65+
66+
```bash
67+
./tasks.sh install_deps
68+
```
69+
70+
This will check for and install any missing dependencies on your system.
71+
72+
Alternatively, verify your dependencies are correctly installed:
73+
```bash
74+
./tasks.sh check_deps
75+
```
76+
77+
#### 2. Build the Project
78+
Compile the OGO project:
79+
80+
```bash
81+
./tasks.sh compile
82+
```
83+
84+
#### 3. Full Installation
85+
To compile and install the complete project:
86+
87+
```bash
88+
./tasks.sh install
89+
```
90+
91+
### Running the Project
92+
93+
#### Run Tests
94+
Execute the test suite:
95+
96+
```bash
97+
./tasks.sh tests
98+
```
99+
100+
#### Run the Application
101+
Test out the OGO application by running it against Main.java
102+
103+
```bash
104+
./tasks.sh exec
105+
```
106+
107+
#### Format Code
108+
Auto-format Java and C++ code according to project standards:
109+
110+
```bash
111+
./tasks.sh format
112+
```
113+
114+
#### End-to-End Setup
115+
Perform a complete setup with dependency checks and full installation:
116+
117+
```bash
118+
./tasks.sh end_to_end
119+
```
120+
121+
## Using OGO in a Maven Project
122+
123+
After packaging, OGO can be used in any maven project.
124+
125+
1. ### Include Client dependency:
126+
127+
The client jar can be added as a dependency to a third-party project by adding the following to its pom.
128+
```xml
129+
<dependency>
130+
<groupId>org.ogo</groupId>
131+
<artifactId>ogo</artifactId>
132+
<version>0.1.0</version>
133+
<scope>system</scope>
134+
<systemPath><!-- ENTER full path to client jar including jar name --></systemPath>
135+
</dependency>
136+
```
137+
138+
2. ### Include Native Agent:
139+
140+
The native agent can be included during execution by adding the following to the third-party pom.
141+
```xml
142+
<configuration>
143+
<!-- for adding native agent ogoAgent -->
144+
<argLine>-agentpath:<!-- ENTER full path to native agent including native agent name --></argLine>
145+
</configuration>
146+
```
147+
Some third-party project tend to use other plugins which may overwrite `argLine`. It may be necessary
148+
to explicitly specify this argument while running the tests using maven. This can be done using:
149+
```bash
150+
mvn test -DargLine="-agentpath:<ENTER full path to native agent including native agent name>"
151+
```
152+
153+
## Citation ##
154+
If you use OGO in your research, please cite the following paper:
155+
156+
```bibtex
157+
@inproceedings{ThimmaiahETAL24OGO,
158+
author = {Thimmaiah, Aditya and Lampropoulos, Leonidas and Rossbach, Christopher and Gligoric, Milos},
159+
title = {Object Graph Programming},
160+
year = {2024},
161+
doi = {10.1145/3597503.3623319},
162+
booktitle = {International Conference on Software Engineering},
163+
pages = {1--13},
164+
}
165+
```
166+
167+
The paper can be found
168+
[here](https://users.ece.utexas.edu/~gligoric/papers/ThimmaiahETAL24OGO.pdf).

descriptor-client.xml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0"?>
2+
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.1 http://maven.apache.org/xsd/assembly-2.1.1.xsd">
3+
<id>client</id>
4+
<formats>
5+
<format>jar</format>
6+
</formats>
7+
<includeBaseDirectory>false</includeBaseDirectory>
8+
<fileSets>
9+
<fileSet>
10+
<directory>${basedir}/target/classes</directory>
11+
<includes>
12+
<include>ogo.properties</include>
13+
<include>org/ogo/client/*.class</include>
14+
<include>org/ogo/util/*.class</include>
15+
<include>org/ogo/bridge/*.class</include>
16+
<include>org/ogo/*.class</include>
17+
</includes>
18+
<outputDirectory>/</outputDirectory>
19+
</fileSet>
20+
</fileSets>
21+
</assembly>

examples/ArrayListExamples.java

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import org.ogo.client.OGO;
2+
import java.util.ArrayList;
3+
4+
import static org.ogo.client.OGO.queryBool;
5+
import static org.ogo.client.OGO.queryInt;
6+
7+
/**
8+
* Example class to demonstrate the usage of OGO
9+
* for querying ArrayLists.
10+
*/
11+
public class ArrayListExamples{
12+
13+
/**
14+
* @brief Example that demonstrates using OGO to query an
15+
* ArrayList to search for a given element.
16+
* @returns true/false
17+
*/
18+
public boolean containsMethodExample() throws Exception{
19+
// Create an ArrayList instance and insert elements into it
20+
// using imperative style.
21+
ArrayList<Long> lst = new ArrayList<Long>();
22+
lst.add(10L);
23+
lst.add(20L);
24+
lst.add(30L);
25+
26+
// Query the ArrayList instance to check if it contains the
27+
// element 20L and return True if it does and false if it doesn't.
28+
return queryBool("MATCH ({$1})-[:elementData]->()-[]->({value:20}) RETURN TRUE", lst);
29+
}
30+
31+
/**
32+
* @brief Example that demonstrates using OGO to query an
33+
* ArrayList to find its size.
34+
* @returns size of the ArrayList
35+
*/
36+
public int arrayListSizeExample() throws Exception{
37+
// Create an ArrayList instance and insert elements into it
38+
// using imperative style.
39+
ArrayList<Long> lst = new ArrayList<Long>();
40+
lst.add(10L);
41+
lst.add(20L);
42+
lst.add(30L);
43+
44+
// Query the ArrayList instance to find its size.
45+
return queryInt("MATCH ({$1})-[:elementData]->()-[]->(n) RETURN COUNT(n)", lst);
46+
}
47+
48+
/**
49+
* @brief Example that demonstrates using OGO to query an
50+
* ArrayList to retrieve an element at a given index.
51+
* @returns element at index 1
52+
*/
53+
public long arrayGetElementAtExample() throws Exception{
54+
// Create an ArrayList instance and insert elements into it
55+
// using imperative style.
56+
ArrayList<Long> lst = new ArrayList<Long>();
57+
lst.add(10L);
58+
lst.add(20L);
59+
lst.add(30L);
60+
61+
// Query the ArrayList instance to retrieve the element at
62+
// index 1.
63+
return queryLong("MATCH ({$1})-[:elementData]->()-[:`1`]->(n) RETURN n", lst);
64+
}
65+
}

images/ogo_logo.png

107 KB
Loading

0 commit comments

Comments
 (0)