libsmatrix 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,22 @@
1
+ # This file is part of the "libsmatrix" project
2
+ # (c) 2011-2013 Paul Asmuth <paul@paulasmuth.com>
3
+ #
4
+ # Licensed under the MIT License (the "License"); you may not use this
5
+ # file except in compliance with the License. You may obtain a copy of
6
+ # the License at: http://opensource.org/licenses/MIT
7
+
8
+ UNAME = $(shell uname)
9
+ SHELL = /bin/sh
10
+ CC = clang
11
+ CFLAGS ?= -Wall -Wextra -O3 -march=native -mtune=native -D NDEBUG -fPIC
12
+ LDFLAGS = -lpthread -lm
13
+ PREFIX = $(DESTDIR)/usr/local
14
+ LIBDIR = $(PREFIX)/lib
15
+
16
+ LIBFLAGS = -shared
17
+ LIBEXT = so
18
+
19
+ ifeq ($(UNAME), Darwin)
20
+ LIBFLAGS = -dynamic -bundle
21
+ LIBEXT = bundle
22
+ endif
@@ -0,0 +1,35 @@
1
+ # This file is part of the "libsmatrix" project
2
+ # (c) 2011-2013 Paul Asmuth <paul@paulasmuth.com>
3
+ #
4
+ # Licensed under the MIT License (the "License"); you may not use this
5
+ # file except in compliance with the License. You may obtain a copy of
6
+ # the License at: http://opensource.org/licenses/MIT
7
+
8
+ include ../Makefile.in
9
+
10
+ TARGET = smatrix_java.$(LIBEXT)
11
+
12
+ ifeq ($(UNAME), Darwin)
13
+ JNI_FLAGS = -I /System/Library/Frameworks/JavaVM.framework/Headers -I /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Headers
14
+ endif
15
+ ifeq ($(UNAME), Linux)
16
+ JNI_FLAGS = -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux
17
+ endif
18
+
19
+ all: $(TARGET)
20
+ mvn package
21
+
22
+ $(TARGET): ../smatrix.o ../smatrix_jni.c ../smatrix_jni.h
23
+ $(CC) $(JNI_FLAGS) $(LIBFLAGS) $(LDFLAGS) ../smatrix_jni.c ../smatrix.o -o $(TARGET)
24
+ ifeq ($(UNAME), Darwin)
25
+ ln -s $(TARGET) smatrix_java.so
26
+ endif
27
+
28
+ ../smatrix.o:
29
+ cd .. && make
30
+
31
+ test: $(TARGET)
32
+ javac -classpath . test/TestSparseMatrix.java
33
+ java -Djava.library.path=./ -classpath .:./test TestSparseMatrix
34
+
35
+ .PHONY: test
@@ -0,0 +1,146 @@
1
+ /**
2
+ * This file is part of the "libsmatrix" project
3
+ * (c) 2011-2013 Paul Asmuth <paul@paulasmuth.com>
4
+ *
5
+ * Licensed under the MIT License (the "License"); you may not use this
6
+ * file except in compliance with the License. You may obtain a copy of
7
+ * the License at: http://opensource.org/licenses/MIT
8
+ */
9
+ package com.paulasmuth.libsmatrix;
10
+ import java.io.File;
11
+ import java.util.SortedMap;
12
+ import java.util.concurrent.ConcurrentSkipListMap;
13
+
14
+ /**
15
+ * A libsmatrix sparse matrix
16
+ */
17
+ public class SparseMatrix {
18
+ private static String library_path = null;
19
+ private String filename = null;
20
+ private long ptr;
21
+
22
+ /**
23
+ * Create a new sparse matrix that will be stored in main memory only.
24
+ *
25
+ * @param file_path path to the file or null
26
+ * @return a new SparseMatrix
27
+ */
28
+ public SparseMatrix() {
29
+ SparseMatrix.loadLibrary();
30
+ init(null);
31
+ }
32
+
33
+ /**
34
+ * Create a new sparse matrix that will be persisted to disk. A cache of the
35
+ * data is still kept in main memory (the cache size can be adjusted by calling
36
+ * setCacheSize on the instance).
37
+ *
38
+ * If the file pointed to by filename exists it will be opened, otherwise a new
39
+ * file will be created.
40
+ *
41
+ * @param file_path path to the file
42
+ * @return a new SparseMatrix
43
+ */
44
+ public SparseMatrix(String file_path) {
45
+ SparseMatrix.loadLibrary();
46
+ filename = file_path;
47
+ init(file_path);
48
+ }
49
+
50
+ /**
51
+ * Explcitly set the path to the native shared object (libsmatrix.so).
52
+ *
53
+ * @param the path to the native shared object
54
+ */
55
+ public static void setLibraryPath(String path) {
56
+ library_path = path;
57
+ loadLibrary();
58
+ }
59
+
60
+ /**
61
+ * HERE BE DRAGONS
62
+ */
63
+ public String getFilename() {
64
+ return filename;
65
+ }
66
+
67
+ /**
68
+ * HERE BE DRAGONS
69
+ */
70
+ public native int get(int x, int y);
71
+
72
+ /**
73
+ * HERE BE DRAGONS
74
+ */
75
+ public native void set(int x, int y, int val);
76
+
77
+ /**
78
+ * HERE BE DRAGONS
79
+ */
80
+ public native void incr(int x, int y, int val);
81
+
82
+ /**
83
+ * HERE BE DRAGONS
84
+ */
85
+ public native void decr(int x, int y, int val);
86
+
87
+ /**
88
+ * HERE BE DRAGONS
89
+ */
90
+ public native int getRowLength(int x);
91
+
92
+ /**
93
+ * HERE BE DRAGONS
94
+ */
95
+ public SortedMap<Integer,Integer> getRow(int x) {
96
+ return getRow(x, 0);
97
+ }
98
+
99
+ /**
100
+ * HERE BE DRAGONS
101
+ */
102
+ public SortedMap<Integer,Integer> getRow(int x, int maxlen) {
103
+ SortedMap<Integer, Integer> map = new ConcurrentSkipListMap<Integer, Integer>() {
104
+ public void putIntTuple(int k, int v) {
105
+ this.put(k, v);
106
+ }
107
+ };
108
+
109
+ getRowNative(x, map, maxlen);
110
+
111
+ return map;
112
+ }
113
+
114
+ /**
115
+ * Close this matrix. Calling any other method on the instance after it was
116
+ * closed will throw an exception.
117
+ */
118
+ public native void close();
119
+
120
+ /**
121
+ * HERE BE DRAGONS
122
+ */
123
+ private native void getRowNative(int x, SortedMap<Integer,Integer> map, int maxlen);
124
+
125
+ /**
126
+ * Load the native shared object (libsmatrix.so)
127
+ */
128
+ private static void loadLibrary() {
129
+ if (library_path != null) {
130
+ File libfile = new File(library_path);
131
+
132
+ if (libfile.exists()) {
133
+ System.load(libfile.getAbsolutePath());
134
+ return;
135
+ }
136
+ }
137
+
138
+ System.loadLibrary("smatrix");
139
+ }
140
+
141
+ /**
142
+ * Initialize a new native matrix
143
+ */
144
+ private native void init(String file_path);
145
+
146
+ }
@@ -0,0 +1,68 @@
1
+ <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3
+ <modelVersion>4.0.0</modelVersion>
4
+
5
+ <name>libsmatrix sparse matrix</name>
6
+ <url>http://github.com/paulasmuth/libsmatrix</url>
7
+ <groupId>com.paulasmuth.libsmatrix</groupId>
8
+ <artifactId>libsmatrix</artifactId>
9
+ <version>0.3-SNAPSHOT</version>
10
+ <packaging>jar</packaging>
11
+
12
+ <build>
13
+ <sourceDirectory>src/java</sourceDirectory>
14
+
15
+ <plugins>
16
+ <plugin>
17
+ <groupId>com.github.github</groupId>
18
+ <artifactId>site-maven-plugin</artifactId>
19
+ <version>0.8</version>
20
+ <!--
21
+ put this into ~/.m2/settings.xml:
22
+
23
+ <settings>
24
+ <servers>
25
+ <server>
26
+ <id>github</id>
27
+ <username>USERNAME</username>
28
+ <password>PASSWORD</password>
29
+ </server>
30
+ </servers>
31
+ </settings>
32
+ -->
33
+ <configuration>
34
+ <message>Maven artifacts for ${project.version}</message>
35
+ <noJekyll>true</noJekyll>
36
+ <outputDirectory>${project.build.directory}/mvn-repo</outputDirectory>
37
+ <branch>refs/heads/mvn-repo</branch>
38
+ <includes><include>**/*</include></includes>
39
+ <repositoryName>libsmatrix</repositoryName>
40
+ <repositoryOwner>paulasmuth</repositoryOwner>
41
+ </configuration>
42
+ <executions>
43
+ <execution>
44
+ <goals>
45
+ <goal>site</goal>
46
+ </goals>
47
+ <phase>deploy</phase>
48
+ </execution>
49
+ </executions>
50
+ </plugin>
51
+ </plugins>
52
+ </build>
53
+
54
+ <distributionManagement>
55
+ <repository>
56
+ <id>internal.repo</id>
57
+ <name>Temporary Staging Repository</name>
58
+ <url>file://${project.build.directory}/mvn-repo</url>
59
+ <uniqueVersion>false</uniqueVersion>
60
+ </repository>
61
+ </distributionManagement>
62
+
63
+ <properties>
64
+ <!-- github server corresponds to entry in ~/.m2/settings.xml -->
65
+ <github.global.server>github</github.global.server>
66
+ </properties>
67
+
68
+ </project>
@@ -0,0 +1,207 @@
1
+ /**
2
+ * This file is part of the "libsmatrix" project
3
+ * (c) 2011-2013 Paul Asmuth <paul@paulasmuth.com>
4
+ *
5
+ * Licensed under the MIT License (the "License"); you may not use this
6
+ * file except in compliance with the License. You may obtain a copy of
7
+ * the License at: http://opensource.org/licenses/MIT
8
+ */
9
+ import java.util.LinkedList;
10
+ import java.util.Iterator;
11
+ import java.util.SortedMap;
12
+ import com.paulasmuth.libsmatrix.SparseMatrix;
13
+
14
+ interface TestCase {
15
+ public String getName();
16
+ public boolean run(SparseMatrix smx);
17
+ }
18
+
19
+ class TestSparseMatrix {
20
+ static LinkedList<TestCase> testCases = new LinkedList<TestCase>();
21
+
22
+ static { testCases.add(new TestCase() {
23
+ public String getName() {
24
+ return "simple set/get";
25
+ }
26
+ public boolean run(SparseMatrix smx) {
27
+ smx.set(42,23,17);
28
+ return smx.get(42,23) == 17;
29
+ }
30
+ }); }
31
+
32
+ static { testCases.add(new TestCase() {
33
+ public String getName() {
34
+ return "simple increment 1";
35
+ }
36
+ public boolean run(SparseMatrix smx) {
37
+ smx.set(4231,2634,0);
38
+ smx.incr(4231,2634,1);
39
+ return smx.get(4231,2634) == 1;
40
+ }
41
+ }); }
42
+
43
+ static { testCases.add(new TestCase() {
44
+ public String getName() {
45
+ return "simple increment 5";
46
+ }
47
+ public boolean run(SparseMatrix smx) {
48
+ smx.set(1231,2634,0);
49
+ smx.incr(1231,2634,1);
50
+ smx.incr(1231,2634,5);
51
+ return smx.get(1231,2634) == 6;
52
+ }
53
+ }); }
54
+
55
+ static { testCases.add(new TestCase() {
56
+ public String getName() {
57
+ return "1 million increments + 1 million gets";
58
+ }
59
+ public boolean run(SparseMatrix smx) {
60
+ int v = 34;
61
+ int i;
62
+ int n;
63
+
64
+ for (n = 0; n < 1000; n++) {
65
+ for (i = 0; i < 1000; i++) {
66
+ smx.set(i, n, v);
67
+ }
68
+ }
69
+
70
+ for (n = 0; n < 1000; n++) {
71
+ for (i = 0; i < 1000; i++) {
72
+ if ((smx.get(i, n) != v)) {
73
+ return false;
74
+ }
75
+ }
76
+ }
77
+
78
+ return true;
79
+ }
80
+ }); }
81
+
82
+ static { testCases.add(new TestCase() {
83
+ public String getName() {
84
+ return "1000 increments + getRowLength()";
85
+ }
86
+ public boolean run(SparseMatrix smx) {
87
+ int i = 0;
88
+ int n = 42;
89
+
90
+ for (i = 0; i < 1000; i++) {
91
+ smx.incr(i, n, 1);
92
+ }
93
+
94
+ return smx.getRowLength(n) == 1000;
95
+ }
96
+ }); }
97
+
98
+ static { testCases.add(new TestCase() {
99
+ public String getName() {
100
+ return "1000 increments + getRow()";
101
+ }
102
+ public boolean run(SparseMatrix smx) {
103
+ int i = 0;
104
+ int n = 85;
105
+
106
+ for (i = 0; i < 1000; i++) {
107
+ smx.incr(i, n, 1);
108
+ }
109
+
110
+ SortedMap<Integer, Integer> row = smx.getRow(n);
111
+
112
+ return row.size() == 1000;
113
+ }
114
+ }); }
115
+
116
+ static { testCases.add(new TestCase() {
117
+ public String getName() {
118
+ return "1000 increments + getRow() with maxlen";
119
+ }
120
+ public boolean run(SparseMatrix smx) {
121
+ int i = 0;
122
+ int n = 83;
123
+
124
+ for (i = 0; i < 1000; i++) {
125
+ smx.incr(i, n, 1);
126
+ }
127
+
128
+ SortedMap<Integer, Integer> row = smx.getRow(n, 230);
129
+ return row.size() == 230;
130
+ }
131
+ }); }
132
+
133
+ static { testCases.add(new TestCase() {
134
+ public String getName() {
135
+ return "1 million increments; close; 1 million gets";
136
+ }
137
+ public boolean run(SparseMatrix smx1) {
138
+ if (smx1.getFilename() == null) {
139
+ return true;
140
+ }
141
+
142
+ int v = 123;
143
+ int i;
144
+ int n;
145
+
146
+ for (n = 0; n < 1000; n++) {
147
+ for (i = 0; i < 1000; i++) {
148
+ smx1.set(i, n, v);
149
+ }
150
+ }
151
+
152
+ SparseMatrix smx2 = new SparseMatrix("/tmp/fnord.smx");
153
+
154
+ for (n = 0; n < 1000; n++) {
155
+ for (i = 0; i < 1000; i++) {
156
+ if ((smx2.get(i, n) != v)) {
157
+ smx2.close();
158
+ return false;
159
+ }
160
+ }
161
+ }
162
+
163
+ smx2.close();
164
+ return true;
165
+ }
166
+ }); }
167
+
168
+ public static void main(String[] opts) {
169
+ boolean success = true;
170
+ SparseMatrix.setLibraryPath("./smatrix_java.so");
171
+
172
+ SparseMatrix smx1 = new SparseMatrix();
173
+ success &= run_tests(smx1);
174
+ smx1.close();
175
+
176
+ SparseMatrix smx2 = new SparseMatrix("/tmp/fnord.smx");
177
+ success &= run_tests(smx2);
178
+ smx2.close();
179
+
180
+ if (success) {
181
+ System.out.println("\033[1;32mAll tests finished successfully :)\033[0m");
182
+ System.exit(0);
183
+ } else {
184
+ System.out.println("\033[1;31mTests failed :(\033[0m");
185
+ System.exit(1);
186
+ }
187
+ }
188
+
189
+ public static boolean run_tests(SparseMatrix smx) {
190
+ boolean success = true;
191
+ Iterator iter = testCases.iterator();
192
+
193
+ while (iter.hasNext()) {
194
+ TestCase testcase = (TestCase) iter.next();
195
+
196
+ if (testcase.run(smx)) {
197
+ System.out.println("\033[1;32m[SUCCESS] " + testcase.getName() + "\033[0m");
198
+ } else {
199
+ System.out.println("\033[1;31m[FAILED] " + testcase.getName() + "\033[0m");
200
+ success = false;
201
+ }
202
+ }
203
+
204
+ return success;
205
+ }
206
+
207
+ }