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.api.ldap.model.csn;
21  
22  
23  /**
24   * Generates a new {@link Csn}.
25   * 
26   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
27   */
28  public class CsnFactory
29  {
30      /** The last timestamp */
31      private static volatile long lastTimestamp;
32  
33      /** The integer used to disambiguate CSN generated at the same time */
34      private int changeCount;
35  
36      /** The replicaId to use for every CSN created by this factory */
37      private int replicaId;
38  
39      /** A special instance ID for a purge CSN */
40      private static final int PURGE_INSTANCEID = 0x0FFF;
41  
42      /** A lock used during the instance creation */
43      private Object lock = new Object();
44  
45  
46      /**
47       * Creates a new CsnFactory instance
48       * @param replicaId The replica ID
49       */
50      public CsnFactory( int replicaId )
51      {
52          changeCount = 0;
53          this.replicaId = replicaId;
54      }
55  
56  
57      /**
58       * Returns a new {@link Csn}.
59       * Generated CSN can be duplicate if user generates CSNs more than 2G 
60       * times a milliseconds.
61       * 
62       * @return The new generated CSN 
63       */
64      public Csn newInstance()
65      {
66          int tmpChangeCount = 0;
67  
68          synchronized ( lock )
69          {
70              long newTimestamp = System.currentTimeMillis();
71  
72              // We will be able to generate 2 147 483 647 CSNs each 10 ms max
73              if ( lastTimestamp == newTimestamp )
74              {
75                  changeCount++;
76              }
77              else
78              {
79                  lastTimestamp = newTimestamp;
80                  changeCount = 0;
81              }
82  
83              tmpChangeCount = changeCount;
84          }
85  
86          return new Csn( lastTimestamp, tmpChangeCount, replicaId, 0 );
87      }
88  
89  
90      /**
91       * Returns a new {@link Csn} created from the given values.
92       * 
93       * This method is <b>not</b> to be used except for test purposes.
94       * 
95       * @param timestamp The timestamp to use
96       * @param changeCount The change count to use
97       * @return The new generated CSN 
98       */
99      public Csn newInstance( long timestamp, int changeCount )
100     {
101         return new Csn( timestamp, changeCount, replicaId, 0 );
102     }
103 
104 
105     /**
106      * Generates a CSN used to purge data. Its replicaID is not associated
107      * to a server. 
108      * 
109      * @param expirationDate The time up to the first CSN we want to keep
110      * @return The new generated CSN 
111      */
112     public Csn newPurgeCsn( long expirationDate )
113     {
114         return new Csn( expirationDate, Integer.MAX_VALUE, PURGE_INSTANCEID, Integer.MAX_VALUE );
115     }
116 
117 
118     /**
119      * Sets the replica ID
120      * @param replicaId The replica ID
121      */
122     public void setReplicaId( int replicaId )
123     {
124         this.replicaId = replicaId;
125     }
126 }