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 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; }
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 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; }
private void clearRecordsMap(Map<Data, Record> excludeRecords) { InMemoryFormat inMemoryFormat = recordFactory.getStorageFormat(); switch (inMemoryFormat) { case BINARY: case OBJECT: records.clear(); if (excludeRecords != null && !excludeRecords.isEmpty()) { records.putAll(excludeRecords); } return; case OFFHEAP: Iterator<Record> iter = records.values().iterator(); while (iter.hasNext()) { Record record = iter.next(); if (excludeRecords == null || !excludeRecords.containsKey(record.getKey())) { record.invalidate(); iter.remove(); } } return; default: throw new IllegalArgumentException("Unknown storage format: " + inMemoryFormat); } }
public boolean containsValue(Object value) { checkIfLoaded(); for (Record record : records.values()) { if (mapService.compare(name, value, record.getValue())) return true; } return false; }
private int evictExpiredEntriesInternal(int maxIterationCount, long now, boolean backup) { int evictedCount = 0; int checkedEntryCount = 0; initExpirationIterator(); while (expirationIterator.hasNext()) { if (checkedEntryCount >= maxIterationCount) { break; } checkedEntryCount++; final Record record = expirationIterator.next(); final Data key = record.getKey(); if (isLocked(key)) { continue; } if (isReachable(record, now)) { continue; } // !!! get entry value here because evictInternal(key) nulls the record value. final Object value = record.getValue(); evictInternal(key, backup); evictedCount++; // do post eviction operations if this partition is an owner partition. if (!backup) { doPostEvictionOperations(key, value, backup); } } return evictedCount; }
private RecordInfo constructRecordInfo(MapContainer mapContainer, Record record, int extraDelay) { final RecordInfo info = new RecordInfo(); info.setStatistics(record.getStatistics()); info.setVersion(record.getVersion()); setDelays(mapContainer, info, record.getKey(), extraDelay); return info; }
public void put(Map.Entry<Data, Object> entry) { checkIfLoaded(); Data dataKey = entry.getKey(); Object value = entry.getValue(); Record record = records.get(dataKey); if (record == null) { value = mapService.interceptPut(name, null, value); value = writeMapStore(dataKey, value, null); record = mapService.createRecord(name, dataKey, value, DEFAULT_TTL); records.put(dataKey, record); // increase size. updateSizeEstimator(calculateRecordSize(record)); saveIndex(record); } else { final Object 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)); saveIndex(record); } }
public boolean set(Data dataKey, Object value, long ttl) { checkIfLoaded(); Record record = records.get(dataKey); boolean newRecord = false; if (record == null) { 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)); newRecord = true; } else { value = mapService.interceptPut(name, record.getValue(), 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 newRecord; }
public Collection<Data> valuesData() { checkIfLoaded(); Collection<Data> values = new ArrayList<Data>(records.size()); for (Record record : records.values()) { values.add(mapService.toData(record.getValue())); } return values; }
public void scheduleTtlEviction(String mapName, Record record, long delay) { if (record.getStatistics() != null) { record.getStatistics().setExpirationTime(Clock.currentTimeMillis() + delay); } getMapContainer(mapName) .getTtlEvictionScheduler() .schedule(delay, toData(record.getKey()), null); }
@Override public void run() { recordStore.unlock(dataKey, getCallerUuid(), getThreadId()); Record record = recordStore.getRecord(dataKey); if (record == null || version == record.getVersion()) { shouldBackup = recordStore.remove(dataKey) != null; } }
private void saveIndex(Record record) { Data dataKey = record.getKey(); final IndexService indexService = mapContainer.getIndexService(); if (indexService.hasIndex()) { SerializationService ss = mapService.getSerializationService(); QueryableEntry queryableEntry = new QueryEntry(ss, dataKey, dataKey, record.getValue()); indexService.saveEntryIndex(queryableEntry); } }
private void accessRecord(Record record) { increaseRecordEvictionCounter(record, mapContainer.getMapConfig().getEvictionPolicy()); record.onAccess(); final int maxIdleSeconds = mapContainer.getMapConfig().getMaxIdleSeconds(); if (maxIdleSeconds > 0) { mapService.scheduleIdleEviction( name, record.getKey(), TimeUnit.SECONDS.toMillis(maxIdleSeconds)); } }
public void run() { SimpleEntryView entryView = (SimpleEntryView) mergingEntry; entryView.setKey(mapService.toObject(mergingEntry.getKey())); entryView.setValue(mapService.toObject(mergingEntry.getValue())); merged = recordStore.merge(dataKey, mergingEntry, mergePolicy); if (merged) { Record record = recordStore.getRecord(dataKey); if (record != null) dataValue = mapService.toData(record.getValue()); } }
public Map.Entry<Data, Object> getMapEntryForBackup(Data dataKey) { checkIfLoaded(); Record record = records.get(dataKey); if (record == null) { record = getRecordInternal(dataKey, false); } else { accessRecord(record); } final Object data = record != null ? record.getValue() : null; return new AbstractMap.SimpleImmutableEntry<Data, Object>(dataKey, data); }
public Object evict(Data dataKey) { checkIfLoaded(); Record record = records.get(dataKey); Object oldValue = null; if (record != null) { flush(dataKey); mapService.interceptRemove(name, record.getValue()); oldValue = record.getValue(); // reduce size updateSizeEstimator(-calculateRecordSize(record)); deleteRecord(dataKey); removeIndex(dataKey); cancelAssociatedSchedulers(dataKey); } return oldValue; }
private void updateTtl(Record record, long ttl) { if (ttl > 0) { mapService.scheduleTtlEviction(name, record, ttl); } else if (ttl == 0) { mapContainer.getTtlEvictionScheduler().cancel(record.getKey()); } }
public void putFromLoad(Data dataKey, Object value, long ttl) { Record record = records.get(dataKey); if (record == null) { value = mapService.interceptPut(name, null, value); record = mapService.createRecord(name, dataKey, value, ttl); records.put(dataKey, record); updateSizeEstimator(calculateRecordSize(record)); } else { value = mapService.interceptPut(name, record.getValue(), value); updateSizeEstimator(-calculateRecordSize(record)); setRecordValue(record, value); updateSizeEstimator(calculateRecordSize(record)); updateTtl(record, ttl); } saveIndex(record); }
public boolean replace(Data dataKey, Object testValue, Object newValue) { checkIfLoaded(); Record record = records.get(dataKey); if (record == null) return false; if (mapService.compare(name, record.getValue(), testValue)) { newValue = mapService.interceptPut(name, record.getValue(), newValue); newValue = writeMapStore(dataKey, newValue, record); updateSizeEstimator(-calculateRecordSize(record)); setRecordValue(record, newValue); updateSizeEstimator(calculateRecordSize(record)); } else { return false; } saveIndex(record); return true; }
protected void increaseRecordEvictionCriteriaNumber( Record record, MapConfig.EvictionPolicy evictionPolicy) { switch (evictionPolicy) { case LRU: ++lruAccessSequenceNumber; record.setEvictionCriteriaNumber(lruAccessSequenceNumber); break; case LFU: record.setEvictionCriteriaNumber(record.getEvictionCriteriaNumber() + 1L); break; case NONE: break; default: throw new IllegalArgumentException( "Not an appropriate eviction policy [" + evictionPolicy + ']'); } }
public QueryResult queryOnPartition(String mapName, Predicate predicate, int partitionId) { final QueryResult result = new QueryResult(); List<QueryEntry> list = new LinkedList<QueryEntry>(); PartitionContainer container = getPartitionContainer(partitionId); RecordStore recordStore = container.getRecordStore(mapName); Map<Data, Record> records = recordStore.getReadonlyRecordMap(); SerializationService serializationService = nodeEngine.getSerializationService(); final PagingPredicate pagingPredicate = predicate instanceof PagingPredicate ? (PagingPredicate) predicate : null; Comparator<Map.Entry> wrapperComparator = SortingUtil.newComparator(pagingPredicate); for (Record record : records.values()) { Data key = record.getKey(); Object value = record.getValue(); if (value == null) { continue; } QueryEntry queryEntry = new QueryEntry(serializationService, key, key, value); if (predicate.apply(queryEntry)) { if (pagingPredicate != null) { Map.Entry anchor = pagingPredicate.getAnchor(); if (anchor != null && SortingUtil.compare( pagingPredicate.getComparator(), pagingPredicate.getIterationType(), anchor, queryEntry) >= 0) { continue; } } list.add(queryEntry); } } if (pagingPredicate != null) { Collections.sort(list, wrapperComparator); if (list.size() > pagingPredicate.getPageSize()) { list = list.subList(0, pagingPredicate.getPageSize()); } } for (QueryEntry entry : list) { result.add( new QueryResultEntryImpl(entry.getKeyData(), entry.getKeyData(), entry.getValueData())); } return result; }
/** * Check if record is reachable according to ttl or idle times. If not reachable return null. * * @param record {@link com.hazelcast.map.record.Record} * @return null if evictable. */ private Record evictIfNotReachable(Record record, boolean backup) { if (record == null) { return null; } final Data key = record.getKey(); if (isLocked(key)) { return record; } if (isReachable(record)) { return record; } final Object value = record.getValue(); evict(key, backup); if (!backup) { doPostEvictionOperations(key, value, backup); } return null; }
public Object replace(Data dataKey, Object value) { checkIfLoaded(); Record record = records.get(dataKey); Object oldValue = null; if (record != null && record.getValue() != null) { oldValue = record.getValue(); value = mapService.interceptPut(name, oldValue, value); value = writeMapStore(dataKey, value, record); updateSizeEstimator(-calculateRecordSize(record)); setRecordValue(record, value); updateSizeEstimator(calculateRecordSize(record)); } else { return null; } saveIndex(record); return oldValue; }
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 void flush() { checkIfLoaded(); Set<Data> keys = new HashSet<Data>(); for (Record record : records.values()) { keys.add(record.getKey()); } EntryTaskScheduler writeScheduler = mapContainer.getMapStoreScheduler(); if (writeScheduler != null) { Set<Data> processedKeys = writeScheduler.flush(keys); for (Data key : processedKeys) { records.get(key).onStore(); } } EntryTaskScheduler deleteScheduler = mapContainer.getMapStoreScheduler(); if (deleteScheduler != null) { deleteScheduler.flush(toBeRemovedKeys); toBeRemovedKeys.clear(); } }
private void migrateIndex(PartitionMigrationEvent event) { final PartitionContainer container = partitionContainers[event.getPartitionId()]; for (RecordStore recordStore : container.getMaps().values()) { final MapContainer mapContainer = getMapContainer(recordStore.getName()); final IndexService indexService = mapContainer.getIndexService(); if (indexService.hasIndex()) { for (Record record : recordStore.getReadonlyRecordMap().values()) { if (event.getMigrationEndpoint() == MigrationEndpoint.SOURCE) { indexService.removeEntryIndex(record.getKey()); } else { Object value = record.getValue(); if (value != null) { indexService.saveEntryIndex( new QueryEntry( getSerializationService(), record.getKey(), record.getKey(), value)); } } } } } }
private Record isTTLExpired(Record record, long time) { if (record == null) { return null; } boolean result; final long ttl = record.getTtl(); // when ttl is zero or negative, it should remain eternally. if (ttl < 1L) { return record; } final long creationTime = record.getCreationTime(); assert ttl > 0L : String.format("wrong ttl %d", ttl); assert creationTime > 0L : String.format("wrong creationTime %d", creationTime); assert time > 0L : String.format("wrong time %d", time); assert time >= creationTime : String.format("time >= lastUpdateTime (%d >= %d)", time, creationTime); result = time - creationTime >= ttl; return result ? null : record; }
public boolean tryPut(Data dataKey, Object value, long ttl) { checkIfLoaded(); Record record = records.get(dataKey); if (record == null) { 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)); } else { value = mapService.interceptPut(name, record.getValue(), value); value = writeMapStore(dataKey, value, record); updateSizeEstimator(-calculateRecordSize(record)); setRecordValue(record, value); updateSizeEstimator(calculateRecordSize(record)); updateTtl(record, ttl); } saveIndex(record); return true; }