KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > recovery > DirtyINMap


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: DirtyINMap.java,v 1.4 2006/10/30 21:14:22 bostic Exp $
7  */

8
9 package com.sleepycat.je.recovery;
10
11 import java.util.HashSet JavaDoc;
12 import java.util.Iterator JavaDoc;
13 import java.util.Set JavaDoc;
14 import java.util.SortedMap JavaDoc;
15 import java.util.TreeMap JavaDoc;
16
17 import com.sleepycat.je.DatabaseException;
18 import com.sleepycat.je.dbi.DatabaseId;
19 import com.sleepycat.je.dbi.DatabaseImpl;
20 import com.sleepycat.je.dbi.EnvironmentImpl;
21 import com.sleepycat.je.dbi.INList;
22 import com.sleepycat.je.dbi.MemoryBudget;
23 import com.sleepycat.je.recovery.Checkpointer.CheckpointReference;
24 import com.sleepycat.je.tree.IN;
25
26 /**
27  * Map of Integer->Set
28  * level->Set of checkpoint references
29  */

30 class DirtyINMap {
31
32     private EnvironmentImpl envImpl;
33     private SortedMap JavaDoc dirtyMap;
34     private int numEntries;
35     private int highestLevelSeen;
36
37     DirtyINMap(EnvironmentImpl envImpl) {
38         this.envImpl = envImpl;
39     }
40
41     /**
42      * Scan the INList for all dirty INs, excluding deferred write INs that
43      * are not in the must-sync set. Save them in a tree-level ordered map for
44      * level ordered flushing.
45      *
46      * Take this opportunity to reset the memory budget tree value.
47      */

48     void selectDirtyINsForCheckpoint(Set JavaDoc mustSyncSet)
49         throws DatabaseException {
50
51         dirtyMap = new TreeMap JavaDoc();
52         numEntries = 0;
53         highestLevelSeen = IN.MIN_LEVEL;
54
55         INList inMemINs = envImpl.getInMemoryINs();
56         inMemINs.latchMajor();
57
58         /*
59      * Opportunistically recalculate the environment wide memory count.
60      * Incurs no extra cost because we're walking the IN list anyway. Not
61      * the best in terms of encapsulation as preferably all memory
62      * calculations are done in MemoryBudget, but done this way to avoid
63      * any extra latching.
64          *
65          * Note: this addition is not taking the "side" added INList into
66          * account properly! Need to fix, but seems to rarely be an issue.
67      */

68         long totalSize = 0;
69         MemoryBudget mb = envImpl.getMemoryBudget();
70
71         try {
72             Iterator JavaDoc iter = inMemINs.iterator();
73             while (iter.hasNext()) {
74                 IN in = (IN) iter.next();
75                 in.latch(false);
76
77                 try {
78                     totalSize = mb.accumulateNewUsage(in, totalSize);
79                     
80                     /*
81                      * Skip deferred-write nodes that are not in the must-sync
82                      * set.
83                      */

84                     if (in.getDatabase().isDeferredWrite() &&
85                         !mustSyncSet.contains(in.getDatabase().getId())){
86                         continue;
87                     }
88
89                     addDirtyIN(in, false);
90                 } finally {
91                     in.releaseLatch();
92                 }
93             }
94
95             /* Set the tree cache size. */
96             mb.refreshTreeMemoryUsage(totalSize);
97
98         } finally {
99             inMemINs.releaseMajorLatchIfHeld();
100         }
101     }
102
103     /**
104      * Scan the INList for all dirty INs for a given database. Arrange them in
105      * level sorted map for level ordered flushing.
106      */

107     void selectDirtyINsForDb(DatabaseImpl dbImpl)
108         throws DatabaseException {
109
110         dirtyMap = new TreeMap JavaDoc();
111         DatabaseId dbId = dbImpl.getId();
112         INList inMemINs = envImpl.getInMemoryINs();
113         inMemINs.latchMajor();
114
115         try {
116             Iterator JavaDoc iter = inMemINs.iterator();
117             while (iter.hasNext()) {
118                 IN in = (IN) iter.next();
119                 if (in.getDatabaseId().equals(dbId)) {
120                     in.latch(false);
121                     try {
122                         addDirtyIN(in, false);
123                     } finally {
124                         in.releaseLatch();
125                     }
126                 }
127             }
128         } finally {
129             inMemINs.releaseMajorLatchIfHeld();
130         }
131     }
132
133     int getNumLevels() {
134         return dirtyMap.size();
135     }
136
137     int getHighestLevel() {
138         return highestLevelSeen;
139     }
140
141     void addCostToMemoryBudget() {
142         MemoryBudget mb = envImpl.getMemoryBudget();
143         int cost = numEntries * MemoryBudget.CHECKPOINT_REFERENCE_SIZE;
144         mb.updateMiscMemoryUsage(cost);
145     }
146     
147     void removeCostFromMemoryBudget() {
148         MemoryBudget mb = envImpl.getMemoryBudget();
149         int cost = numEntries * MemoryBudget.CHECKPOINT_REFERENCE_SIZE;
150         mb.updateMiscMemoryUsage(0 - cost);
151     }
152
153     /**
154      * Add a node to the dirty map. The dirty map is keyed by level (Integers)
155      * and holds sets of IN references.
156      */

157     void addDirtyIN(IN in, boolean updateMemoryBudget) {
158         if (in.getDirty()) {
159             int levelVal = in.getLevel();
160             if (levelVal > highestLevelSeen) {
161                 highestLevelSeen = levelVal;
162             }
163
164             Integer JavaDoc level = new Integer JavaDoc(levelVal);
165             Set JavaDoc dirtySet;
166             if (dirtyMap.containsKey(level)) {
167                 dirtySet = (Set JavaDoc) dirtyMap.get(level);
168             } else {
169                 dirtySet = new HashSet JavaDoc();
170                 dirtyMap.put(level, dirtySet);
171             }
172
173             dirtySet.add(new CheckpointReference(in.getDatabase(),
174                                                  in.getNodeId(),
175                                                  in.containsDuplicates(),
176                                                  in.isDbRoot(),
177                                                  in.getMainTreeKey(),
178                                                  in.getDupTreeKey()));
179             numEntries++;
180
181         if (updateMemoryBudget) {
182         MemoryBudget mb = envImpl.getMemoryBudget();
183         mb.updateMiscMemoryUsage
184             (MemoryBudget.CHECKPOINT_REFERENCE_SIZE);
185         }
186         }
187     }
188
189     /**
190      * Get the lowest level currently stored in the map.
191      */

192     Integer JavaDoc getLowestLevelSet() {
193         return (Integer JavaDoc) dirtyMap.firstKey();
194     }
195
196     /**
197      * Get the set corresponding to this level.
198      */

199     Set JavaDoc getSet(Integer JavaDoc level) {
200         return (Set JavaDoc) dirtyMap.get(level);
201     }
202     
203     /**
204      * Get the set corresponding to this level.
205      */

206     void removeSet(Integer JavaDoc level) {
207         dirtyMap.remove(level);
208     }
209 }
210
Popular Tags