@Override public void init(InitializationContext ctx) { this.ctx = ctx; cache = ctx.getCache().getAdvancedCache(); rpcManager = cache.getRpcManager(); this.configuration = ctx.getConfiguration(); }
@Override public void start() throws CacheLoaderException { final Marshaller marshaller; if (configuration.marshaller() != null) { marshaller = Util.getInstance( configuration.marshaller(), ctx.getCache().getCacheConfiguration().classLoader()); } else if (configuration.hotRodWrapping()) { marshaller = new HotRodEntryMarshaller(ctx.getByteBufferFactory()); } else if (configuration.rawValues()) { marshaller = new GenericJBossMarshaller(); } else { marshaller = ctx.getMarshaller(); } ConfigurationBuilder builder = buildRemoteConfiguration(configuration, marshaller); remoteCacheManager = new RemoteCacheManager(builder.build()); if (configuration.remoteCacheName().equals(BasicCacheContainer.DEFAULT_CACHE_NAME)) remoteCache = remoteCacheManager.getCache(); else remoteCache = remoteCacheManager.getCache(configuration.remoteCacheName()); if (configuration.rawValues() && iceFactory == null) { iceFactory = ctx.getCache() .getAdvancedCache() .getComponentRegistry() .getComponent(InternalEntryFactory.class); } }
private MarshalledEntry<K, V> _load(Object key, boolean loadValue, boolean loadMetadata) { final FileEntry fe; resizeLock.readLock().lock(); try { synchronized (entries) { // lookup FileEntry of the key fe = entries.get(key); if (fe == null) return null; // Entries are removed due to expiration from {@link SingleFileStore#purge} if (fe.isExpired(timeService.wallClockTime())) { return null; } else { // lock entry for reading before releasing entries monitor fe.lock(); } } } finally { resizeLock.readLock().unlock(); } org.infinispan.commons.io.ByteBuffer valueBb = null; org.infinispan.commons.io.ByteBuffer metadataBb = null; // If we only require the key, then no need to read disk if (!loadValue && !loadMetadata) { try { return ctx.getMarshalledEntryFactory().newMarshalledEntry(key, valueBb, metadataBb); } finally { fe.unlock(); } } final byte[] data; try { // load serialized data from disk data = new byte[fe.keyLen + fe.dataLen + (loadMetadata ? fe.metadataLen : 0)]; // The entry lock will prevent clear() from truncating the file at this point channel.read(ByteBuffer.wrap(data), fe.offset + KEY_POS); } catch (Exception e) { throw new PersistenceException(e); } finally { // No need to keep the lock for deserialization. // FileEntry is immutable, so its members can't be changed by another thread. fe.unlock(); } if (trace) log.tracef("Read entry %s at %d:%d", key, fe.offset, fe.actualSize()); ByteBufferFactory factory = ctx.getByteBufferFactory(); org.infinispan.commons.io.ByteBuffer keyBb = factory.newByteBuffer(data, 0, fe.keyLen); if (loadValue) { valueBb = factory.newByteBuffer(data, fe.keyLen, fe.dataLen); } if (loadMetadata && fe.metadataLen > 0) { metadataBb = factory.newByteBuffer(data, fe.keyLen + fe.dataLen, fe.metadataLen); } return ctx.getMarshalledEntryFactory().newMarshalledEntry(keyBb, valueBb, metadataBb); }
@Override public void init(InitializationContext ctx) { this.configuration = ctx.getConfiguration(); this.emfRegistry = ctx.getCache() .getAdvancedCache() .getComponentRegistry() .getGlobalComponentRegistry() .getComponent(EntityManagerFactoryRegistry.class); this.marshallerEntryFactory = ctx.getMarshalledEntryFactory(); this.marshaller = ctx.getMarshaller(); this.timeService = ctx.getTimeService(); }
@Override public void start() { try { // open the data file String location = configuration.location(); if (location == null || location.trim().length() == 0) location = "Infinispan-SingleFileStore"; file = new File(location, ctx.getCache().getName() + ".dat"); if (!file.exists()) { File dir = file.getParentFile(); if (!dir.mkdirs() && !dir.exists()) { throw log.directoryCannotBeCreated(dir.getAbsolutePath()); } } channel = new RandomAccessFile(file, "rw").getChannel(); // initialize data structures entries = newEntryMap(); freeList = Collections.synchronizedSortedSet(new TreeSet<FileEntry>()); // check file format and read persistent state if enabled for the cache byte[] header = new byte[MAGIC.length]; if (channel.read(ByteBuffer.wrap(header), 0) == MAGIC.length && Arrays.equals(MAGIC, header)) { rebuildIndex(); processFreeEntries(); } else clear(); // otherwise (unknown file format or no preload) just reset the file // Initialize the fragmentation factor fragmentationFactor = configuration.fragmentationFactor(); } catch (Exception e) { throw new PersistenceException(e); } }
private <Key> Map<Key, FileEntry> newEntryMap() { // only use LinkedHashMap (LRU) for entries when cache store is bounded final Map<Key, FileEntry> entryMap; Equivalence<Object> keyEq = ctx.getCache().getCacheConfiguration().dataContainer().keyEquivalence(); if (configuration.maxEntries() > 0) entryMap = CollectionFactory.makeLinkedMap(16, 0.75f, true, null, null); else entryMap = CollectionFactory.makeMap(keyEq, AnyEquivalence.<FileEntry>getInstance()); return Collections.synchronizedMap(entryMap); }
@Override public void start() { try { String name = ctx.getCache().getName(); EmbeddedCacheManager cacheManager = ctx.getCache().getCacheManager(); Cache<?, ?> metaCache = cacheManager.getCache(name + "-meta"); Cache<?, ?> dataCache = cacheManager.getCache(name + "-chunk"); BuildContext bcontext = DirectoryBuilder.newDirectoryInstance(metaCache, dataCache, metaCache, name); bcontext.chunkSize(1024 * 1024); Directory directory = bcontext.create(); this.central = CentralConfig.oldFromDir(directory) .indexConfigBuilder() .executorService(new WithinThreadExecutor()) .build(); this.configuration.store(this); } catch (Exception e) { throw new PersistenceException(e); } }
private MarshalledEntry entryFromDoc(TreeNodeKey key, ReadDocument findDoc) { InternalMetadata metadataBb = null; AtomicHashMap<PropertyId, PropertyValue> nodeValue = new AtomicHashMap<PropertyId, PropertyValue>(); JsonObject raw = JsonObject.fromString(findDoc.asString(EntryKey.VALUE)); JsonObject props = raw.asJsonObject(EntryKey.PROPS); for (Entry<String, JsonElement> entry : props.entrySet()) { String pkey = entry.getKey(); JsonElement pvalue = entry.getValue(); PropertyId propId = PropertyId.fromIdString(pkey); nodeValue.put(propId, PropertyValue.loadFrom(key, propId, pvalue)); } return ctx.getMarshalledEntryFactory().newMarshalledEntry(key, nodeValue, metadataBb); }
/** Rebuilds the in-memory index from file. */ private void rebuildIndex() throws Exception { ByteBuffer buf = ByteBuffer.allocate(KEY_POS); for (; ; ) { // read FileEntry fields from file (size, keyLen etc.) buf.clear().limit(KEY_POS); channel.read(buf, filePos); // return if end of file is reached if (buf.remaining() > 0) return; buf.flip(); // initialize FileEntry from buffer int entrySize = buf.getInt(); int keyLen = buf.getInt(); int dataLen = buf.getInt(); int metadataLen = buf.getInt(); long expiryTime = buf.getLong(); FileEntry fe = new FileEntry(filePos, entrySize, keyLen, dataLen, metadataLen, expiryTime); // sanity check if (fe.size < KEY_POS + fe.keyLen + fe.dataLen + fe.metadataLen) { throw log.errorReadingFileStore(file.getPath(), filePos); } // update file pointer filePos += fe.size; // check if the entry is used or free if (fe.keyLen > 0) { // load the key from file if (buf.capacity() < fe.keyLen) buf = ByteBuffer.allocate(fe.keyLen); buf.clear().limit(fe.keyLen); channel.read(buf, fe.offset + KEY_POS); // deserialize key and add to entries map // Marshaller should allow for provided type return for safety K key = (K) ctx.getMarshaller().objectFromByteBuffer(buf.array(), 0, fe.keyLen); entries.put(key, fe); } else { // add to free list freeList.add(fe); } } }
@Override public void stop() { try { if (channel != null) { log.tracef( "Stopping store %s, size = %d, file size = %d", ctx.getCache().getName(), entries.size(), channel.size()); // reset state channel.close(); channel = null; entries = null; freeList = null; filePos = MAGIC.length; } } catch (Exception e) { throw new PersistenceException(e); } }
@Override public void process( KeyFilter filter, final CacheLoaderTask task, Executor executor, final boolean fetchValue, final boolean fetchMetadata) { if (true) return; filter = PersistenceUtil.notNull(filter); Set<Object> keysToLoad = new HashSet<Object>(ctx.getCache().keySet()); ExecutorAllCompletionService eacs = new ExecutorAllCompletionService(executor); final TaskContextImpl taskContext = new TaskContextImpl(); for (final Object key : keysToLoad) { if (taskContext.isStopped()) break; eacs.submit( new Callable<Void>() { @Override public Void call() throws Exception { try { final MarshalledEntry marshalledEntry = _load(key, fetchValue, fetchMetadata); if (marshalledEntry != null) { Debug.line(task, marshalledEntry, fetchValue, fetchMetadata); task.processEntry(marshalledEntry, taskContext); } return null; } catch (Exception e) { log.errorExecutingParallelStoreTask(e); throw e; } } }); } eacs.waitUntilAllCompleted(); if (eacs.isExceptionThrown()) { throw new PersistenceException("Execution exception!", eacs.getFirstException()); } }
@Override public MarshalledEntry load(Object key) throws PersistenceException { if (!isCacheReady()) return null; ClusteredGetCommand clusteredGetCommand = new ClusteredGetCommand( key, cache.getName(), EnumUtil.EMPTY_BIT_SET, false, null, cache.getCacheConfiguration().dataContainer().keyEquivalence()); Collection<Response> responses = doRemoteCall(clusteredGetCommand); if (responses.isEmpty()) return null; Response response; if (responses.size() > 1) { // Remove duplicates before deciding if multiple responses were received Set<Response> setResponses = new HashSet<>(responses); if (setResponses.size() > 1) throw new PersistenceException( String.format( "Responses contains more than 1 element and these elements are not equal, so can't decide which one to use: %s", setResponses)); response = setResponses.iterator().next(); } else { response = responses.iterator().next(); } if (response.isSuccessful() && response instanceof SuccessfulResponse) { InternalCacheValue value = (InternalCacheValue) ((SuccessfulResponse) response).getResponseValue(); return value == null ? null : ctx.getMarshalledEntryFactory().newMarshalledEntry(key, value.getValue(), null); } log.unknownResponsesFromRemoteCache(responses); throw new PersistenceException("Unknown responses"); }
private MarshalledEntry _load(Object _key, boolean fetchValue, boolean fetchMetaValue) { try { TreeNodeKey key = (TreeNodeKey) _key; if (key.action() == Action.RESET || key.action() == Action.CREATE) return null; // if log, return if (key.getType().isStructure()) { List<ReadDocument> docs = central .newSearcher() .createRequest(new TermQuery(new Term(EntryKey.PARENT, key.fqnString()))) .selections(IKeywordField.DocKey) .offset(1000000) .find() .getDocument(); AtomicHashMap<String, Fqn> values = new AtomicHashMap<String, Fqn>(); for (ReadDocument doc : docs) { Fqn fqn = Fqn.fromString(doc.idValue()); values.put(fqn.name(), fqn); } InternalMetadata metadataBb = null; return ctx.getMarshalledEntryFactory().newMarshalledEntry(key, values, metadataBb); } ReadDocument findDoc = central .newSearcher() .createRequestByKey(key.idString()) .selections(EntryKey.VALUE) .findOne(); if (findDoc == null) { return null; } return entryFromDoc(key, findDoc); } catch (IOException e) { return null; } catch (ParseException ex) { return null; } }
@Override public MarshalledEntry load(Object key) throws CacheLoaderException { if (configuration.rawValues()) { MetadataValue<?> value = remoteCache.getWithMetadata(key); if (value != null) { Metadata metadata = new EmbeddedMetadata.Builder() .version(new NumericVersion(value.getVersion())) .lifespan(value.getLifespan(), TimeUnit.SECONDS) .maxIdle(value.getMaxIdle(), TimeUnit.SECONDS) .build(); long created = value.getCreated(); long lastUsed = value.getLastUsed(); return ctx.getMarshalledEntryFactory() .newMarshalledEntry( key, value.getValue(), new InternalMetadataImpl(metadata, created, lastUsed)); } else { return null; } } else { return (MarshalledEntry) remoteCache.get(key); } }
@Override public void init(InitializationContext ctx) { this.ctx = ctx; this.configuration = ctx.getConfiguration(); }