View Javadoc

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 }