final long fetchRecord(Version shared) { if (Debug.ENABLED) Debug.assertion(!_updatedVersions.contains(shared)); long record = Record.NOT_STORED; Object union = shared.getUnion(); if (union instanceof Descriptor) { Descriptor descriptor = (Descriptor) union; Session session = descriptor.getSession(); long records = session.getRecords(); if (records == Record.NOT_STORED) { records = _sessions.fetch(session.getSharedVersion_objectfabric().getUID()); session.setRecords(records); } record = fetchRecord(records, descriptor.getId() & 0xff); } else { byte[] uid = shared.getUID(); if (uid != null) { long records = _sessions.fetch(uid); record = fetchRecord(records, Session.UID_OBJECT_ID & 0xff); } } if (Debug.ENABLED) Debug.assertion(record != Record.UNKNOWN); return record; }
@SuppressWarnings("unchecked") @Override protected void getAsync(UserTObject object, Object key, FutureWithCallback<Object> future) { if (object.getSharedVersion_objectfabric().getUnion() instanceof Record) { long record = getOrFetchRecord(object.getSharedVersion_objectfabric()); if (Record.isStored(record)) { BTree tree = BTree.load(getRecordManager(), record, false); _writer.write(key); byte[] data = new byte[_writer.getOffset()]; PlatformAdapter.arraycopy(_writer.getBuffer(), 0, data, 0, data.length); long id = tree.fetch(data); if (id != 0) { data = getRecordManager().fetch(id); Object value = _reader.read(data); _reader.readVersions(); Version version = _reader.getOrCreateVersion(object); TKeyedEntry entry = new TKeyedEntry(key, TKeyed.hash(key), value, false); if (Debug.ENABLED) Debug.assertion(value != TKeyedEntry.REMOVAL); ((LazyMapVersion) version).putEntry(key, entry, true, true); _reader.importVersions(); future.set(value); return; } } } future.set(null); }
protected final void onStarted() { if (!_state.compareAndSet(STARTING, IDLE)) { if (Debug.ENABLED) Debug.assertion(_state.get() == STARTING_SCHEDULED); _state.set(IDLE); requestRun(); } }
final void updateRecord(Version shared, Session session, byte[] uid, long currentRecord, long newRecord, int id) { if (Debug.ENABLED) Debug.assertion(newRecord != currentRecord); int index = _updatedVersions.add(shared); if (index == _updatedVersionsRecords.length) _updatedVersionsRecords = Utils.extend(_updatedVersionsRecords); _updatedVersionsRecords[index] = newRecord; // Sessions int sessionIndex = _updatedSessions.indexOf(session); long records = sessionIndex >= 0 ? _updatedSessionsRecords[sessionIndex] : session.getRecords(); final long initialRecords = records; if (records == Record.NOT_STORED) records = _sessions.fetch(uid); if (records != Record.NOT_STORED) { byte[] data = getRecordManager().fetch(records); if (Debug.ENABLED) { Debug.assertion(data.length == Session.TOTAL_LENGTH * 8); Debug.assertion(Utils.readLong(data, id * 8) == currentRecord); } Utils.writeLong(data, id * 8, newRecord); getRecordManager().update(records, data, 0, data.length); } else { byte[] data = new byte[Session.TOTAL_LENGTH * 8]; Utils.writeLong(data, id * 8, newRecord); records = getRecordManager().insert(data, 0, data.length); _sessions.put(uid, records); } if (records != initialRecords) { index = _updatedSessions.add(session); if (index == _updatedSessionsRecords.length) _updatedSessionsRecords = Utils.extend(_updatedSessionsRecords); _updatedSessionsRecords[index] = records; } }
protected final boolean onRunStarting() { if (!_state.compareAndSet(SCHEDULED, RUNNING)) { if (Debug.ENABLED) Debug.assertion(_state.get() == DISPOSED); return false; } return true; }
@Override protected void onVisitingVersions(Visitor visitor, Version shared) { super.onVisitingVersions(visitor, shared); if (Debug.ENABLED) Debug.assertion(_writer.getLimit() == _writer.getBuffer().length); _writer.reset(); }
final long getOrFetchRecord(Version shared) { long record = getRecord(shared); if (record == Record.UNKNOWN) record = fetchRecord(shared); if (Debug.ENABLED) Debug.assertion(record != Record.UNKNOWN); return record; }
private final long fetchRecord(long records, int id) { if (records != Record.NOT_STORED) { byte[] session = getRecordManager().fetch(records); if (Debug.ENABLED) Debug.assertion(session.length == Session.TOTAL_LENGTH * 8); return Utils.readLong(session, id * 8); } return Record.NOT_STORED; }
protected final void onRunEnded() { for (; ; ) { if (_state.get() == RUNNING) { if (_state.compareAndSet(RUNNING, IDLE)) break; } else { if (Debug.ENABLED) Debug.assertion(_state.get() == RUNNING_SCHEDULED); if (_state.compareAndSet(RUNNING_SCHEDULED, SCHEDULED)) { startRun(); break; } } } }
protected final void assertRunning() { if (!Debug.ENABLED) throw new RuntimeException(); int state = _state.get(); Debug.assertion(state == RUNNING || state == RUNNING_SCHEDULED); }
protected final void assertScheduled() { if (!Debug.ENABLED) throw new RuntimeException(); int state = _state.get(); Debug.assertion(state == SCHEDULED || state == DISPOSED); }
protected final void assertStarting() { if (!Debug.ENABLED) throw new RuntimeException(); int state = _state.get(); Debug.assertion(state == STARTING); }
@Override protected void checkedRun() { if (Debug.THREADS) { ThreadAssert.resume(this, false); ThreadAssert.exchangeTake(this); } Exception ex; try { onRunStarting(); runTasks(); // while (_inserts.size() > 0) _refs.add(writeObject(_inserts.poll())); // if (Debug.ENABLED) Debug.assertion(!_writer.interrupted()); for (;;) { BinaryStore.this.run(_writer); if (!_writer.interrupted()) break; _writer.grow(); } _writer.writeSnapshots(); // Exception wrongStore = null; int toremove; if (_writer.getWrongStore() == null) _jdbm.commit(); else { _jdbm.rollback(); wrongStore = new RuntimeException(Strings.WRONG_STORE + _writer.getWrongStore()); } while (_processed.size() > 0) { Transaction branch = _processed.pollPartOfClear(); byte interception = _processedInterceptions[_processed.size()]; if (wrongStore == null) Interceptor.ack(branch, interception, true); else Interceptor.nack(branch, null, wrongStore); } if (wrongStore != null) { if (Debug.ENABLED) { // Assert old records have been restored on rollback for (int i = 0; i < _updatedVersions.size(); i++) { Version shared = _updatedVersions.get(i); Debug.assertion(_jdbm.fetch(shared.getRecord()) != null); } } _updatedVersions.clear(); _updatedSessions.clear(); } else { while (_updatedVersions.size() > 0) { Version shared = _updatedVersions.pollPartOfClear(); long record = _updatedVersionsRecords[_updatedVersions.size()]; shared.setRecord(record); } while (_updatedSessions.size() > 0) { Session session = _updatedSessions.pollPartOfClear(); long records = _updatedSessionsRecords[_updatedSessions.size()]; session.setRecords(records); } } // while (_callbacks.size() > 0) { AsyncCallback<byte[]> callback = _callbacks.poll(); byte[] ref = _refs.poll(); if (wrongStore == null) callback.onSuccess(ref); else callback.onFailure(wrongStore); } // _writer.resetWrongStore(); if (Debug.THREADS) ThreadAssert.suspend(this); setFlushes(); onRunEnded(); return; } catch (Exception e) { ex = e; } while (_callbacks.size() > 0) _callbacks.poll().onFailure(ex); // Only in case of exception (can be closing) onException(ex); }