static <K> void rename(final K key, final K newKey, RedisOperations<K, ?> operations) { operations.execute(new SessionCallback<Object>() { @SuppressWarnings("unchecked") public Object execute(RedisOperations operations) throws DataAccessException { do { operations.watch(key); if (operations.hasKey(key)) { operations.multi(); operations.rename(key, newKey); } else { operations.multi(); } } while (operations.exec() == null); return null; } }); } }
/** * Execute {@link RedisCallback} via underlying {@link RedisOperations}. * * @param callback must not be {@literal null}. * @see RedisOperations#execute(RedisCallback) * @return */ @Nullable public <T> T execute(RedisCallback<T> callback) { return redisOps.execute(callback); }
/** * Atomically set the value to the given updated value if the current value {@code ==} the expected value. * * @param expect the expected value. * @param update the new value. * @return {@literal true} if successful. {@literal false} indicates that the actual value was not equal to the * expected value. */ public boolean compareAndSet(long expect, long update) { return generalOps.execute(new CompareAndSet<>(this::get, this::set, key, expect, update)); }
/** * Atomically set the value to the given updated value if the current value {@code ==} the expected value. * * @param expect the expected value. * @param update the new value. * @return {@literal true} if successful. {@literal false} indicates that the actual value was not equal to the * expected value. */ public boolean compareAndSet(double expect, double update) { return generalOps.execute(new CompareAndSet<>(this::get, this::set, key, expect, update)); }
/** * Atomically set the value to the given updated value if the current value {@code ==} the expected value. * * @param expect the expected value. * @param update the new value. * @return {@literal true} if successful. {@literal false} indicates that the actual value was not equal to the * expected value. */ public boolean compareAndSet(int expect, int update) { return generalOps.execute(new CompareAndSet<>(this::get, this::set, key, expect, update)); }
@Override @Nullable public Map<byte[], byte[]> resolveReference(Object id, String keyspace) { byte[] key = converter.convert(keyspace + ":" + id); return redisOps.execute((RedisCallback<Map<byte[], byte[]>>) connection -> connection.hGetAll(key)); } }
@Override public boolean replace(K key, V oldValue, V newValue) { if (oldValue == null || newValue == null) { throw new NullPointerException(); } return hashOps.getOperations().execute(new SessionCallback<Boolean>() { @Override @SuppressWarnings({ "unchecked", "rawtypes" }) public Boolean execute(RedisOperations ops) { for (;;) { ops.watch(Collections.singleton(getKey())); V v = get(key); if (oldValue.equals(v)) { ops.multi(); put(key, newValue); if (ops.exec(ops.getHashValueSerializer()) != null) { return true; } } else { return false; } } } }); }
public List<?> getAllOf(String keyspace, long offset, int rows) { byte[] binKeyspace = toBytes(keyspace); Set<byte[]> ids = redisOps.execute((RedisCallback<Set<byte[]>>) connection -> connection.sMembers(binKeyspace)); List<Object> result = new ArrayList<>(); List<byte[]> keys = new ArrayList<>(ids); if (keys.isEmpty() || keys.size() < offset) { return Collections.emptyList(); } offset = Math.max(0, offset); if (rows > 0) { keys = keys.subList((int) offset, Math.min((int) offset + rows, keys.size())); } for (byte[] key : keys) { result.add(get(key, keyspace)); } return result; }
@Override public boolean remove(Object key, Object value) { if (value == null) { throw new NullPointerException(); } return hashOps.getOperations().execute(new SessionCallback<Boolean>() { @Override @SuppressWarnings({ "unchecked", "rawtypes" }) public Boolean execute(RedisOperations ops) { for (;;) { ops.watch(Collections.singleton(getKey())); V v = get(key); if (value.equals(v)) { ops.multi(); remove(key); if (ops.exec(ops.getHashValueSerializer()) != null) { return true; } } else { return false; } } } }); }
@Override @Nullable public V replace(K key, V value) { if (value == null) { throw new NullPointerException(); } return hashOps.getOperations().execute(new SessionCallback<V>() { @Override @SuppressWarnings({ "unchecked", "rawtypes" }) public V execute(RedisOperations ops) { for (;;) { ops.watch(Collections.singleton(getKey())); V v = get(key); if (v != null) { ops.multi(); put(key, value); if (ops.exec(ops.getHashValueSerializer()) != null) { return v; } } else { return null; } } } }); }
@Override public long count(String keyspace) { Long count = redisOps.execute((RedisCallback<Long>) connection -> connection.sCard(toBytes(keyspace))); return count != null ? count : 0; }
@Override public boolean contains(Object id, String keyspace) { Boolean exists = redisOps .execute((RedisCallback<Boolean>) connection -> connection.sIsMember(toBytes(keyspace), toBytes(id))); return exists != null ? exists : false; }
@Override public void deleteAllOf(String keyspace) { redisOps.execute((RedisCallback<Void>) connection -> { connection.del(toBytes(keyspace)); new IndexWriter(connection, converter).removeAllIndexes(asString(keyspace)); return null; }); }
@Nullable @Override public <T> T get(Object id, String keyspace, Class<T> type) { String stringId = asString(id); String stringKeyspace = asString(keyspace); byte[] binId = createKey(stringKeyspace, stringId); Map<byte[], byte[]> raw = redisOps .execute((RedisCallback<Map<byte[], byte[]>>) connection -> connection.hGetAll(binId)); RedisData data = new RedisData(raw); data.setId(stringId); data.setKeyspace(stringKeyspace); return readBackTimeToLiveIfSet(binId, converter.read(type, data)); }
Long timeout = redisOps.execute((RedisCallback<Long>) connection -> {
@Override public void onMessage(Message message, @Nullable byte[] pattern) { if (!isKeyExpirationMessage(message)) { return; } byte[] key = message.getBody(); byte[] phantomKey = ByteUtils.concat(key, converter.getConversionService().convert(KeyspaceIdentifier.PHANTOM_SUFFIX, byte[].class)); Map<byte[], byte[]> hash = ops.execute((RedisCallback<Map<byte[], byte[]>>) connection -> { Map<byte[], byte[]> hash1 = connection.hGetAll(phantomKey); if (!CollectionUtils.isEmpty(hash1)) { connection.del(phantomKey); } return hash1; }); Object value = converter.read(Object.class, new RedisData(hash)); String channel = !ObjectUtils.isEmpty(message.getChannel()) ? converter.getConversionService().convert(message.getChannel(), String.class) : null; RedisKeyExpiredEvent event = new RedisKeyExpiredEvent(channel, key, value); ops.execute((RedisCallback<Void>) connection -> { connection.sRem(converter.getConversionService().convert(event.getKeyspace(), byte[].class), event.getId()); new IndexWriter(connection, converter).removeKeyFromIndexes(event.getKeyspace(), event.getId()); return null; }); publishEvent(event); }
@Override public <T> T delete(Object id, String keyspace, Class<T> type) { byte[] binId = toBytes(id); byte[] binKeyspace = toBytes(keyspace); T o = get(id, keyspace, type); if (o != null) { byte[] keyToDelete = createKey(asString(keyspace), asString(id)); redisOps.execute((RedisCallback<Void>) connection -> { connection.del(keyToDelete); connection.sRem(binKeyspace, binId); new IndexWriter(connection, converter).removeKeyFromIndexes(asString(keyspace), binId); return null; }); } return o; }
this.converter.write(update, rdo); redisOps.execute((RedisCallback<Void>) connection -> {
/** * Perform an {@code INFO} command on the provided {@link RedisOperations} to check * the Redis server version to be sure that {@code UNLINK} is available or not. * @param redisOperations the {@link RedisOperations} to perform {@code INFO} command. * @return true or false if {@code UNLINK} Redis command is available or not. * @throws IllegalStateException when {@code INFO} returns null from the Redis. */ public static boolean isUnlinkAvailable(RedisOperations<?, ?> redisOperations) { return unlinkAvailable.computeIfAbsent(redisOperations, key -> { Properties info = redisOperations.execute( (RedisCallback<Properties>) connection -> connection.serverCommands().info(SECTION)); if (info != null) { int majorVersion = Integer.parseInt(info.getProperty(VERSION_PROPERTY).split("\\.")[0]); return majorVersion >= 4; } else { throw new IllegalStateException("The INFO command cannot be used in pipeline/transaction."); } }); }
redisOps.execute((RedisCallback<Object>) connection -> {