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; }
@Override protected Action onVisitingTObject(Visitor visitor, TObject object) { Action action = super.onVisitingTObject(visitor, object); if (action == Action.VISIT) { /* * TODO write version to a cache, for now writer will snapshot entire object * for each change. */ // Object union = ((Version) object).getUnion(); // // if (!(union instanceof Record)) // return Action.SKIP; // // if (((Record) union).getRecord() == Record.NULL) // return Action.SKIP; Version shared = (Version) object; long record = getOrFetchRecord(shared); int id = shared.getClassId(); if (record != Record.NOT_STORED) { // TODO: temporary: other objects should not be snapshotted if (id == DefaultObjectModel.COM_OBJECTFABRIC_TMAP_CLASS_ID || id == DefaultObjectModel.COM_OBJECTFABRIC_TSET_CLASS_ID) return Action.VISIT; _writer.snapshot(shared); } else { /* * Lazy objects must always be stored, otherwise during construction their * content can get GCed before the lazy object is added to the store. */ if (id == DefaultObjectModelBase.COM_OBJECTFABRIC_LAZYMAP_CLASS_ID) return Action.VISIT; } } return Action.SKIP; }
final long getRecord(Version shared) { int index = _updatedVersions.indexOf(shared); if (index >= 0) return _updatedVersionsRecords[index]; Object union = shared.getUnion(); if (union instanceof Record) return ((Record) union).getRecord(); return Record.NOT_STORED; }
@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); }