1 /*
2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package org.openjdk.jigsaw;
27
28 import java.io.Closeable;
29 import java.io.File;
30 import java.io.IOException;
31 import java.security.AccessController;
32 import java.security.PrivilegedAction;
33
34 // Not really a java.util.TreeMap ...
35
36 public class PersistentTreeMap implements Closeable {
37
38 private final long db;
39 private final boolean readOnly;
40
41 protected PersistentTreeMap(long db) {
42 this(db, true);
43 }
44
45 protected PersistentTreeMap(long db, boolean readOnly) {
46 this.db = db;
47 this.readOnly = readOnly;
48 }
49
50 private static native long create0(String f) throws IOException;
51
52 // creates file if doesn't exist, truncates.
53 public static PersistentTreeMap create(File f) throws IOException {
54 return new PersistentTreeMap(create0(f.getPath()), false);
55 }
56
57 private static native long open0(String f) throws IOException;
58
59 public static PersistentTreeMap open(File f) throws IOException {
60 return new PersistentTreeMap(open0(f.getPath()));
61 }
62
63 private native void put0(long db, String k, String v)
64 throws IOException;
65
66 // overwrites existing value, if there is one
67 public void put(String key, String value) throws IOException {
68 if (readOnly)
69 throw new IOException("attempt to modify a read-only database");
70
71 put0(db, key, value);
72 }
73
74 private native String get0(long db, String k)
75 throws IOException;
76
77 // null if key not found
78 public String get(String key) throws IOException {
79 return get0(db, key);
80 }
81
82 private native void put1(long db, String k, int v)
83 throws IOException;
84
85 // overwrites existing value, if there is one
86 public void put(String key, int value) throws IOException {
87 if (readOnly)
88 throw new IOException("attempt to modify a read-only database");
89
90 put1(db, key, value);
91 }
92
93 private native int get1(long db, String k)
94 throws IOException;
95
96 // Returns -1 if key not found
97 public int getInt(String key) throws IOException {
98 return get1(db, key);
99 }
100
101 private native void put2(long db, String k, String sv, int iv)
102 throws IOException;
103
104 // overwrites existing value, if there is one
105 public void put(String key, String sval, int ival) throws IOException {
106 if (readOnly)
107 throw new IOException("attempt to modify a read-only database");
108
109 put2(db, key, sval, ival);
110 }
111
112 public static class StringAndInt {
113 public final String s;
114 public final int i;
115 public StringAndInt(String s, int i) {
116 this.s = s;
117 this.i = i;
118 }
119 }
120
121 private native boolean get2(long db, String k, String[] svala, int[] ivala)
122 throws IOException;
123
124 // This is simpler than hassling with creating the result object
125 // directly in JNI
126
127 private String[] svala = new String[1];
128 private int[] ivala = new int[1];
129
130 // null if key not found
131 public StringAndInt getStringAndInt(String key)
132 throws IOException
133 {
134 synchronized(this) {
135 if (!get2(db, key, svala, ivala))
136 return null;
137 return new StringAndInt(svala[0], ivala[0]);
138 }
139 }
140
141 private native void close0(long db) throws IOException;
142
143 @Override
144 public void close() throws IOException {
145 close0(db);
146 }
147
148 private static native void initialize();
149
150 static {
151 initialize();
152 }
153 }