1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 *
19 */
20 package org.apache.directory.server.core.partition.impl.btree.jdbm;
21
22
23 import jdbm.RecordManager;
24 import jdbm.helper.LongSerializer;
25 import jdbm.helper.Serializer;
26 import jdbm.helper.StringComparator;
27
28 import org.apache.directory.server.xdbm.MasterTable;
29 import org.apache.directory.server.core.entry.ServerEntrySerializer;
30 import org.apache.directory.server.schema.SerializableComparator;
31 import org.apache.directory.server.schema.registries.Registries;
32
33
34 /**
35 * The master table used to store the Attributes of entries.
36 *
37 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
38 * @version $Rev: 678777 $
39 */
40 public class JdbmMasterTable<E> extends JdbmTable<Long,E> implements MasterTable<E>
41 {
42 private static final StringComparator STRCOMP = new StringComparator();
43
44
45 private static final SerializableComparator<Long> LONG_COMPARATOR =
46 new SerializableComparator<Long>( "1.3.6.1.4.1.18060.0.4.1.1.2" )
47 {
48 private static final long serialVersionUID = 4048791282048841016L;
49
50
51 public int compare( Long o1, Long o2 )
52 {
53 if ( o1 == null )
54 {
55 throw new IllegalArgumentException( "Argument 'obj1' is null" );
56 }
57 else if ( o2 == null )
58 {
59 throw new IllegalArgumentException( "Argument 'obj2' is null" );
60 }
61
62 if ( o1 == ( long ) o2 )
63 {
64 return 0;
65 }
66
67 if ( o1 == ( long ) o2 )
68 {
69 return 0;
70 }
71
72 if ( o1 >= 0 )
73 {
74 if ( o2 >= 0 )
75 {
76 return ( o1 > ( long ) o2 ) ? 1 : -1;
77 }
78 else
79 {
80 return -1;
81 }
82 }
83 else if ( o2 >= 0 )
84 {
85 return 1;
86 }
87 else
88 {
89 return ( o1 < ( long ) o2 ) ? -1 : 1;
90 }
91 }
92 };
93
94
95 private static final SerializableComparator<String> STRING_COMPARATOR =
96 new SerializableComparator<String>( "1.3.6.1.4.1.18060.0.4.1.1.3" )
97 {
98 private static final long serialVersionUID = 3258689922792961845L;
99
100
101 public int compare( String o1, String o2 )
102 {
103 return STRCOMP.compare( o1, o2 );
104 }
105 };
106
107
108 protected final JdbmTable<String,String> adminTbl;
109
110
111 /**
112 * Creates the master table using JDBM B+Trees for the backing store.
113 *
114 * @param recMan the JDBM record manager
115 * @param registries the schema registries
116 * @throws Exception if there is an error opening the Db file.
117 */
118 public JdbmMasterTable( RecordManager recMan, Registries registries ) throws Exception
119 {
120 super( DBF, recMan, LONG_COMPARATOR, LongSerializer.INSTANCE, new ServerEntrySerializer( registries ) );
121 adminTbl = new JdbmTable<String,String>( "admin", recMan, STRING_COMPARATOR, null, null );
122 String seqValue = adminTbl.get( SEQPROP_KEY );
123
124 if ( null == seqValue )
125 {
126 adminTbl.put( SEQPROP_KEY, "0" );
127 }
128 }
129
130
131 protected JdbmMasterTable( RecordManager recMan, String dbName, Serializer serializer ) throws Exception
132 {
133 super( DBF, recMan, LONG_COMPARATOR, LongSerializer.INSTANCE, serializer );
134 adminTbl = new JdbmTable<String,String>( dbName, recMan, STRING_COMPARATOR, null, null );
135 String seqValue = adminTbl.get( SEQPROP_KEY );
136
137 if ( null == seqValue )
138 {
139 adminTbl.put( SEQPROP_KEY, "0" );
140 }
141 }
142
143 /**
144 * Gets the ServerEntry from this MasterTable.
145 *
146 * @param id the Long id of the entry to retrieve.
147 * @return the ServerEntry with operational attributes and all.
148 * @throws Exception if there is a read error on the underlying Db.
149 */
150 public E get( Long id ) throws Exception
151 {
152 return super.get( id );
153 }
154
155
156 /**
157 * Puts the ServerEntry into this master table at an index
158 * specified by id. Used both to create new entries and update existing
159 * ones.
160 *
161 * @param entry the ServerEntry w/ operational attributes
162 * @param id the Long id of the entry to put
163 * @throws Exception if there is a write error on the underlying Db.
164 */
165 public void put( Long id, E entry ) throws Exception
166 {
167 super.put( id, entry );
168 }
169
170
171 /**
172 * Deletes a ServerEntry from the master table at an index specified by id.
173 *
174 * @param id the Long id of the entry to delete
175 * @throws Exception if there is a write error on the underlying Db
176 */
177 public void delete( Long id ) throws Exception
178 {
179 super.remove( id );
180 }
181
182
183 public Long getCurrentId() throws Exception
184 {
185 Long id;
186
187 synchronized ( adminTbl )
188 {
189 id = new Long( adminTbl.get( SEQPROP_KEY ) );
190 }
191
192 return id;
193 }
194
195
196 /**
197 * Get's the next value from this SequenceBDb. This has the side-effect of
198 * changing the current sequence values permanently in memory and on disk.
199 * Master table sequence begins at BigInteger.ONE. The BigInteger.ZERO is
200 * used for the fictitious parent of the suffix root entry.
201 *
202 * @return the current value incremented by one.
203 * @throws Exception if the admin table storing sequences cannot be
204 * read and written to.
205 */
206 public Long getNextId() throws Exception
207 {
208 Long nextVal;
209 Long lastVal;
210
211 synchronized ( adminTbl )
212 {
213 lastVal = new Long( adminTbl.get( SEQPROP_KEY ) );
214 nextVal = lastVal + 1L;
215 adminTbl.put( SEQPROP_KEY, nextVal.toString() );
216 }
217
218 return nextVal;
219 }
220
221
222 /**
223 * Gets a persistent property stored in the admin table of this MasterTable.
224 *
225 * @param property the key of the property to get the value of
226 * @return the value of the property
227 * @throws Exception when the underlying admin table cannot be read
228 */
229 public String getProperty( String property ) throws Exception
230 {
231 synchronized ( adminTbl )
232 {
233 return adminTbl.get( property );
234 }
235 }
236
237
238 /**
239 * Sets a persistent property stored in the admin table of this MasterTable.
240 *
241 * @param property the key of the property to set the value of
242 * @param value the value of the property
243 * @throws Exception when the underlying admin table cannot be writen
244 */
245 public void setProperty( String property, String value ) throws Exception
246 {
247 synchronized ( adminTbl )
248 {
249 adminTbl.put( property, value );
250 }
251 }
252 }