001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020 package org.apache.directory.server.core.partition.impl.btree.jdbm; 021 022 023 import jdbm.RecordManager; 024 import jdbm.helper.LongSerializer; 025 import jdbm.helper.Serializer; 026 import jdbm.helper.StringComparator; 027 028 import org.apache.directory.server.i18n.I18n; 029 import org.apache.directory.server.xdbm.MasterTable; 030 import org.apache.directory.shared.ldap.schema.SchemaManager; 031 import org.apache.directory.shared.ldap.schema.comparators.SerializableComparator; 032 033 034 /** 035 * The master table used to store the Attributes of entries. 036 * 037 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 038 * @version $Rev: 902308 $ 039 */ 040 public class JdbmMasterTable<E> extends JdbmTable<Long,E> implements MasterTable<E> 041 { 042 private static final StringComparator STRCOMP = new StringComparator(); 043 044 045 private static final SerializableComparator<Long> LONG_COMPARATOR = 046 new SerializableComparator<Long>( "1.3.6.1.4.1.18060.0.4.1.1.2" ) 047 { 048 private static final long serialVersionUID = 4048791282048841016L; 049 050 051 public int compare( Long o1, Long o2 ) 052 { 053 if ( o1 == null ) 054 { 055 throw new IllegalArgumentException( I18n.err( I18n.ERR_525 ) ); 056 } 057 else if ( o2 == null ) 058 { 059 throw new IllegalArgumentException( I18n.err( I18n.ERR_526 ) ); 060 } 061 062 if ( o1 == ( long ) o2 ) 063 { 064 return 0; 065 } 066 067 if ( o1 == ( long ) o2 ) 068 { 069 return 0; 070 } 071 072 if ( o1 >= 0 ) 073 { 074 if ( o2 >= 0 ) 075 { 076 return ( o1 > ( long ) o2 ) ? 1 : -1; 077 } 078 else 079 { 080 return -1; 081 } 082 } 083 else if ( o2 >= 0 ) 084 { 085 return 1; 086 } 087 else 088 { 089 return ( o1 < ( long ) o2 ) ? -1 : 1; 090 } 091 } 092 }; 093 094 095 private static final SerializableComparator<String> STRING_COMPARATOR = 096 new SerializableComparator<String>( "1.3.6.1.4.1.18060.0.4.1.1.3" ) 097 { 098 private static final long serialVersionUID = 3258689922792961845L; 099 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 schemaManager the schema mamanger 116 * @throws Exception if there is an error opening the Db file. 117 */ 118 public JdbmMasterTable( RecordManager recMan, SchemaManager schemaManager ) throws Exception 119 { 120 super( schemaManager, DBF, recMan, LONG_COMPARATOR, LongSerializer.INSTANCE, new ServerEntrySerializer( schemaManager ) ); 121 adminTbl = new JdbmTable<String,String>( schemaManager, "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 LONG_COMPARATOR.setSchemaManager( schemaManager ); 130 STRING_COMPARATOR.setSchemaManager( schemaManager ); 131 } 132 133 134 protected JdbmMasterTable( RecordManager recMan, SchemaManager schemaManager, String dbName, Serializer serializer ) throws Exception 135 { 136 super( schemaManager, DBF, recMan, LONG_COMPARATOR, LongSerializer.INSTANCE, serializer ); 137 adminTbl = new JdbmTable<String,String>( schemaManager, dbName, recMan, STRING_COMPARATOR, null, null ); 138 String seqValue = adminTbl.get( SEQPROP_KEY ); 139 140 if ( null == seqValue ) 141 { 142 adminTbl.put( SEQPROP_KEY, "0" ); 143 } 144 } 145 146 /** 147 * Gets the ServerEntry from this MasterTable. 148 * 149 * @param id the Long id of the entry to retrieve. 150 * @return the ServerEntry with operational attributes and all. 151 * @throws Exception if there is a read error on the underlying Db. 152 */ 153 public E get( Long id ) throws Exception 154 { 155 return super.get( id ); 156 } 157 158 159 /** 160 * Puts the ServerEntry into this master table at an index 161 * specified by id. Used both to create new entries and update existing 162 * ones. 163 * 164 * @param entry the ServerEntry w/ operational attributes 165 * @param id the Long id of the entry to put 166 * @throws Exception if there is a write error on the underlying Db. 167 */ 168 public void put( Long id, E entry ) throws Exception 169 { 170 super.put( id, entry ); 171 } 172 173 174 /** 175 * Deletes a ServerEntry from the master table at an index specified by id. 176 * 177 * @param id the Long id of the entry to delete 178 * @throws Exception if there is a write error on the underlying Db 179 */ 180 public void delete( Long id ) throws Exception 181 { 182 super.remove( id ); 183 } 184 185 186 public Long getCurrentId() throws Exception 187 { 188 Long id; 189 190 synchronized ( adminTbl ) 191 { 192 id = new Long( adminTbl.get( SEQPROP_KEY ) ); 193 } 194 195 return id; 196 } 197 198 199 /** 200 * Get's the next value from this SequenceBDb. This has the side-effect of 201 * changing the current sequence values permanently in memory and on disk. 202 * Master table sequence begins at BigInteger.ONE. The BigInteger.ZERO is 203 * used for the fictitious parent of the suffix root entry. 204 * 205 * @return the current value incremented by one. 206 * @throws Exception if the admin table storing sequences cannot be 207 * read and written to. 208 */ 209 public Long getNextId() throws Exception 210 { 211 Long nextVal; 212 Long lastVal; 213 214 synchronized ( adminTbl ) 215 { 216 lastVal = new Long( adminTbl.get( SEQPROP_KEY ) ); 217 nextVal = lastVal + 1L; 218 adminTbl.put( SEQPROP_KEY, nextVal.toString() ); 219 } 220 221 return nextVal; 222 } 223 224 225 /** 226 * Gets a persistent property stored in the admin table of this MasterTable. 227 * 228 * @param property the key of the property to get the value of 229 * @return the value of the property 230 * @throws Exception when the underlying admin table cannot be read 231 */ 232 public String getProperty( String property ) throws Exception 233 { 234 synchronized ( adminTbl ) 235 { 236 return adminTbl.get( property ); 237 } 238 } 239 240 241 /** 242 * Sets a persistent property stored in the admin table of this MasterTable. 243 * 244 * @param property the key of the property to set the value of 245 * @param value the value of the property 246 * @throws Exception when the underlying admin table cannot be writen 247 */ 248 public void setProperty( String property, String value ) throws Exception 249 { 250 synchronized ( adminTbl ) 251 { 252 adminTbl.put( property, value ); 253 } 254 } 255 }