Changeset 5280
- Timestamp:
- 2011-12-19 16:24:00 (17 months ago)
- Location:
- trunk/cr/repository
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/cr/repository/impl/src/main/java/org/lilyproject/repository/impl/AbstractSchemaCache.java
r5271 r5280 47 47 private FieldTypes fieldTypesSnapshot; 48 48 private FieldTypesCache fieldTypesCache = new FieldTypesCache(); 49 private boolean updatedFieldTypes = false;49 private volatile boolean updatedFieldTypes = false; 50 50 51 51 private RecordTypesCache recordTypes = new RecordTypesCache(); … … 438 438 lilyNodes = zooKeeper.getChildren(LILY_NODES_PATH, watcher); 439 439 lilyNodesWatcher = watcher; 440 } catch (KeeperException.NoNodeException e) { 440 } catch (KeeperException e) { 441 if (log.isDebugEnabled()) 442 log.debug("Failed getting lilyNodes from Zookeeper", e); 441 443 // The path does not exist yet. 442 444 // Set the lilyNodesWatcher to null so that we retry -
trunk/cr/repository/impl/src/main/java/org/lilyproject/repository/impl/FieldTypesCache.java
r5256 r5280 17 17 18 18 import java.util.HashMap; 19 import java.util.HashSet; 19 20 import java.util.List; 20 21 import java.util.Map; 21 22 import java.util.Map.Entry; 23 import java.util.Set; 22 24 import java.util.concurrent.ConcurrentHashMap; 23 25 … … 42 44 // lead to an inconsistent state (two types could get the same name). 43 45 private volatile int count = 0; 46 47 private ConcurrentHashMap<String, Set<SchemaId>> localUpdateBuckets = new ConcurrentHashMap<String, Set<SchemaId>>(); 44 48 45 49 private Log log = LogFactory.getLog(getClass()); … … 164 168 monitor.wait(); 165 169 } 166 // The nameCache can be made up to date as well since everything is 167 // being updated 168 nameCacheOutOfDate = false; 169 nameCache = new HashMap<QName, FieldType>(fieldTypes.size()); 170 nameCacheOutOfDate = true; 170 171 // One would expect that existing buckets need to be cleared first. 171 172 // But since field types cannot be deleted we will just overwrite 172 173 // them. 173 174 for (FieldType fieldType : fieldTypes) { 174 nameCache.put(fieldType.getName(), fieldType);175 175 String bucketId = AbstractSchemaCache.encodeHex(fieldType.getId().getBytes()); 176 Map<SchemaId, FieldType> bucket = buckets.get(bucketId); 177 if (bucket == null) { 178 bucket = new ConcurrentHashMap<SchemaId, FieldType>(8, .75f, 1); 179 buckets.put(bucketId, bucket); 180 } 181 bucket.put(fieldType.getId(), fieldType); 176 // Only update if it was not updated locally 177 // If it was updated locally either this is the refresh of that 178 // update, 179 // or the refresh for this update will follow. 180 if (!removeFromLocalUpdateBucket(fieldType.getId(), bucketId)) { 181 Map<SchemaId, FieldType> bucket = buckets.get(bucketId); 182 if (bucket == null) { 183 bucket = new ConcurrentHashMap<SchemaId, FieldType>(8, .75f, 1); 184 buckets.put(bucketId, bucket); 185 } 186 bucket.put(fieldType.getId(), fieldType); 187 } 182 188 } 183 189 } … … 208 214 // Fill a the bucket with the new field types 209 215 for (FieldType fieldType : fieldTypes) { 210 bucket.put(fieldType.getId(), fieldType); 216 if (!removeFromLocalUpdateBucket(fieldType.getId(), bucketId)) { 217 bucket.put(fieldType.getId(), fieldType); 218 } 211 219 } 212 220 } … … 236 244 } 237 245 bucket.put(id, ftToCache); 246 // Mark that this fieldType is updated locally 247 // and that the next refresh can be ignored 248 // since this refresh can contain an old fieldType 249 addToLocalUpdateBucket(id, bucketId); 238 250 } 239 251 // Decrement the number of buckets that are being updated again. 240 252 decCount(); 241 253 } 254 255 // Add the id of a field type that has been updated locally 256 // in a bucket. This field type will be skipped in a next 257 // cache refresh sequence. 258 // This avoids that a locally updated field type will be 259 // overwritten by old data by a cache refresh. 260 private void addToLocalUpdateBucket(SchemaId id, String bucketId) { 261 Set<SchemaId> localUpdateBucket = localUpdateBuckets.get(bucketId); 262 if (localUpdateBucket == null) { 263 localUpdateBucket = new HashSet<SchemaId>(); 264 localUpdateBuckets.put(bucketId, localUpdateBucket); 265 } 266 localUpdateBucket.add(id); 267 } 268 269 // Check if the field type is present in the local update bucket. 270 // If so, return true and remove it, in which case the refresh 271 // should skip it to avoid replacing the field type with old data. 272 private boolean removeFromLocalUpdateBucket(SchemaId id, String bucketId) { 273 Set<SchemaId> localUpdateBucket = localUpdateBuckets.get(bucketId); 274 if (localUpdateBucket == null) { 275 return false; 276 } 277 return localUpdateBucket.remove(id); 278 } 242 279 } -
trunk/cr/repository/test/src/test/java/org/lilyproject/repository/impl/test/SchemaCacheTest.java
r5236 r5280 225 225 QName ftName = new QName("testRenameFieldType", "f"); 226 226 FieldType fieldType = typeManager.fieldTypeBuilder().name(ftName).create(); 227 for (int i = 0; i < 10; i++) {227 for (int i = 0; i < 100; i++) { 228 228 QName newFtName = new QName("testRenameFieldType", "f"+i); 229 229 fieldType.setName(newFtName);
Note: See TracChangeset
for help on using the changeset viewer.