public boolean remove(Data dataKey, Object testValue) { checkIfLoaded(); Record record = records.get(dataKey); Object oldValue = null; boolean removed = false; if (record == null) { if (mapContainer.getStore() != null) { oldValue = mapContainer.getStore().load(mapService.toObject(dataKey)); } if (oldValue == null) return false; } else { oldValue = record.getValue(); } if (mapService.compare(name, testValue, oldValue)) { mapService.interceptRemove(name, oldValue); removeIndex(dataKey); mapStoreDelete(record, dataKey); // reduce size updateSizeEstimator(-calculateRecordSize(record)); deleteRecord(dataKey); cancelAssociatedSchedulers(dataKey); removed = true; } return removed; }
public Object putIfAbsent(Data dataKey, Object value, long ttl) { checkIfLoaded(); Record record = records.get(dataKey); Object oldValue = null; if (record == null) { if (mapContainer.getStore() != null) { oldValue = mapContainer.getStore().load(mapService.toObject(dataKey)); if (oldValue != null) { record = mapService.createRecord(name, dataKey, oldValue, DEFAULT_TTL); records.put(dataKey, record); updateSizeEstimator(calculateRecordSize(record)); } } } else { accessRecord(record); oldValue = record.getValue(); } if (oldValue == null) { value = mapService.interceptPut(name, null, value); value = writeMapStore(dataKey, value, record); record = mapService.createRecord(name, dataKey, value, ttl); records.put(dataKey, record); updateSizeEstimator(calculateRecordSize(record)); updateTtl(record, ttl); } saveIndex(record); return oldValue; }
public Object put(Data dataKey, Object value, long ttl) { checkIfLoaded(); Record record = records.get(dataKey); Object oldValue = null; if (record == null) { if (mapContainer.getStore() != null) { oldValue = mapContainer.getStore().load(mapService.toObject(dataKey)); } value = mapService.interceptPut(name, null, value); value = writeMapStore(dataKey, value, null); record = mapService.createRecord(name, dataKey, value, ttl); records.put(dataKey, record); updateSizeEstimator(calculateRecordSize(record)); saveIndex(record); } else { oldValue = record.getValue(); value = mapService.interceptPut(name, oldValue, value); value = writeMapStore(dataKey, value, record); // if key exists before, first reduce size updateSizeEstimator(-calculateRecordSize(record)); setRecordValue(record, value); // then increase size. updateSizeEstimator(calculateRecordSize(record)); updateTtl(record, ttl); saveIndex(record); } return oldValue; }
public Object remove(Data dataKey) { checkIfLoaded(); Record record = records.get(dataKey); Object oldValue = null; if (record == null) { if (mapContainer.getStore() != null) { oldValue = mapContainer.getStore().load(mapService.toObject(dataKey)); if (oldValue != null) { removeIndex(dataKey); mapStoreDelete(null, dataKey); } } } else { oldValue = record.getValue(); oldValue = mapService.interceptRemove(name, oldValue); if (oldValue != null) { removeIndex(dataKey); mapStoreDelete(record, dataKey); } // reduce size updateSizeEstimator(-calculateRecordSize(record)); deleteRecord(dataKey); cancelAssociatedSchedulers(dataKey); } return oldValue; }
private Record getRecordInternal(Data dataKey, boolean enableIndex) { Record record = null; if (mapContainer.getStore() != null) { final Object value = mapContainer.getStore().load(mapService.toObject(dataKey)); if (value != null) { record = mapService.createRecord(name, dataKey, value, DEFAULT_TTL); records.put(dataKey, record); if (enableIndex) { saveIndex(record); } updateSizeEstimator(calculateRecordSize(record)); } } return record; }
public void clear() { checkIfLoaded(); resetSizeEstimator(); final Collection<Data> lockedKeys = lockStore != null ? lockStore.getLockedKeys() : Collections.<Data>emptySet(); final Map<Data, Record> lockedRecords = new HashMap<Data, Record>(lockedKeys.size()); // Locked records should not be removed! for (Data key : lockedKeys) { Record record = records.get(key); if (record != null) { lockedRecords.put(key, record); updateSizeEstimator(calculateRecordSize(record)); } } Set<Data> keysToDelete = records.keySet(); keysToDelete.removeAll(lockedRecords.keySet()); final MapStoreWrapper store = mapContainer.getStore(); // Use an ArrayList so that we don't trigger calls to equals or hashCode on the key objects Collection<Object> keysObject = new ArrayList<Object>(keysToDelete.size()); for (Data key : keysToDelete) { // todo ea have a clear(Keys) method for optimizations removeIndex(key); keysObject.add(mapService.toObject(key)); } if (store != null) { store.deleteAll(keysObject); toBeRemovedKeys.removeAll(keysToDelete); } clearRecordsMap(lockedRecords); cancelAssociatedSchedulers(keysToDelete); resetAccessSequenceNumber(); }
private void destroyMapStores() { for (MapContainer mapContainer : mapContainers.values()) { MapStoreWrapper store = mapContainer.getStore(); if (store != null) { store.destroy(); } } }
public MapEntrySet getAll(Set<Data> keySet) { checkIfLoaded(); final MapEntrySet mapEntrySet = new MapEntrySet(); Map<Object, Data> keyMapForLoader = null; if (mapContainer.getStore() != null) { keyMapForLoader = new HashMap<Object, Data>(); } for (Data dataKey : keySet) { Record record = records.get(dataKey); if (record == null) { if (mapContainer.getStore() != null) { keyMapForLoader.put(mapService.toObject(dataKey), dataKey); } } else { accessRecord(record); Object value = record.getValue(); value = mapService.interceptGet(name, value); if (value != null) { mapEntrySet.add(new AbstractMap.SimpleImmutableEntry(dataKey, mapService.toData(value))); } } } if (mapContainer.getStore() == null || keyMapForLoader.size() == 0) { return mapEntrySet; } final Map<Object, Object> loadedKeys = mapContainer.getStore().loadAll(keyMapForLoader.keySet()); for (Map.Entry entry : loadedKeys.entrySet()) { final Object objectKey = entry.getKey(); Object value = entry.getValue(); Data dataKey = keyMapForLoader.get(objectKey); if (value != null) { Record record = mapService.createRecord(name, dataKey, value, DEFAULT_TTL); records.put(dataKey, record); saveIndex(record); updateSizeEstimator(calculateRecordSize(record)); } value = mapService.interceptGet(name, value); if (value != null) { mapEntrySet.add(new AbstractMap.SimpleImmutableEntry(dataKey, mapService.toData(value))); } } return mapEntrySet; }
public boolean containsKey(Data dataKey) { checkIfLoaded(); Record record = records.get(dataKey); if (record == null) { if (mapContainer.getStore() != null) { Object value = mapContainer.getStore().load(mapService.toObject(dataKey)); if (value != null) { record = mapService.createRecord(name, dataKey, value, DEFAULT_TTL); records.put(dataKey, record); updateSizeEstimator(calculateRecordSize(record)); } } } boolean contains = record != null; if (contains) { accessRecord(record); } return contains; }
public Object get(Data dataKey) { checkIfLoaded(); Record record = records.get(dataKey); Object value = null; if (record == null) { if (mapContainer.getStore() != null) { value = mapContainer.getStore().load(mapService.toObject(dataKey)); if (value != null) { record = mapService.createRecord(name, dataKey, value, DEFAULT_TTL); records.put(dataKey, record); saveIndex(record); updateSizeEstimator(calculateRecordSize(record)); } } } else { accessRecord(record); value = record.getValue(); } value = mapService.interceptGet(name, value); return value; }
private void mapStoreDelete(Record record, Data key) { final MapStoreWrapper store = mapContainer.getStore(); if (store != null) { long writeDelayMillis = mapContainer.getWriteDelayMillis(); if (writeDelayMillis == 0) { store.delete(mapService.toObject(key)); // todo ea record will be deleted then why calling onStore if (record != null) { record.onStore(); } } else { mapService.scheduleMapStoreDelete(name, key, writeDelayMillis); toBeRemovedKeys.add(key); } } }
private Object writeMapStore(Data dataKey, Object recordValue, Record record) { final MapStoreWrapper store = mapContainer.getStore(); if (store != null) { if (mapContainer.getWriteDelayMillis() <= 0) { Object objectValue = mapService.toObject(recordValue); store.store(mapService.toObject(dataKey), objectValue); if (record != null) { record.onStore(); } // if store is not a post-processing map-store, then avoid extra de-serialization phase. return store.isPostProcessingMapStore() ? objectValue : recordValue; } else { mapService.scheduleMapStoreWrite( name, dataKey, recordValue, mapContainer.getWriteDelayMillis()); } } return recordValue; }
public DefaultRecordStore(String name, MapService mapService, int partitionId) { this.name = name; this.partitionId = partitionId; this.mapService = mapService; this.mapContainer = mapService.getMapContainer(name); this.logger = mapService.getNodeEngine().getLogger(this.getName()); recordFactory = mapContainer.getRecordFactory(); NodeEngine nodeEngine = mapService.getNodeEngine(); final LockService lockService = nodeEngine.getSharedService(LockService.SERVICE_NAME); this.lockStore = lockService == null ? null : lockService.createLockStore( partitionId, new DefaultObjectNamespace(MapService.SERVICE_NAME, name)); this.sizeEstimator = SizeEstimators.createMapSizeEstimator(); final int mapLoadChunkSize = nodeEngine.getGroupProperties().MAP_LOAD_CHUNK_SIZE.getInteger(); final Queue<Map> chunks = new LinkedList<Map>(); if (nodeEngine .getThisAddress() .equals(nodeEngine.getPartitionService().getPartitionOwner(partitionId))) { if (mapContainer.getStore() != null && !loaded.get()) { Map<Data, Object> loadedKeys = mapContainer.getInitialKeys(); if (loadedKeys != null && !loadedKeys.isEmpty()) { Map<Data, Object> partitionKeys = new HashMap<Data, Object>(); Iterator<Map.Entry<Data, Object>> iterator = loadedKeys.entrySet().iterator(); while (iterator.hasNext()) { final Map.Entry<Data, Object> entry = iterator.next(); final Data data = entry.getKey(); if (partitionId == nodeEngine.getPartitionService().getPartitionId(data)) { partitionKeys.put(data, entry.getValue()); // split into chunks if (partitionKeys.size() >= mapLoadChunkSize) { chunks.add(partitionKeys); partitionKeys = new HashMap<Data, Object>(); } iterator.remove(); } } if (!partitionKeys.isEmpty()) { chunks.add(partitionKeys); } if (!chunks.isEmpty()) { try { Map<Data, Object> chunkedKeys; final AtomicInteger checkIfMapLoaded = new AtomicInteger(chunks.size()); while ((chunkedKeys = chunks.poll()) != null) { nodeEngine .getExecutionService() .submit("hz:map-load", new MapLoadAllTask(chunkedKeys, checkIfMapLoaded)); } } catch (Throwable t) { throw ExceptionUtil.rethrow(t); } } else { loaded.set(true); } } else { loaded.set(true); } } } else { loaded.set(true); } }
public void checkIfLoaded() { if (mapContainer.getStore() != null && !loaded.get()) { throw ExceptionUtil.rethrow(new RetryableHazelcastException("Map is not ready!!!")); } }