private void deletePropertyChain(long nextProp) { PropertyStore propStore = getPropertyStore(); while (nextProp != Record.NO_NEXT_PROPERTY.intValue()) { PropertyRecord propRecord = propStore.getRecord(nextProp); /* * The only reason to loop over the blocks is to handle the dynamic * records that possibly hang under them. Otherwise, we could just * set the property record not in use and be done with it. The * residue of the convenience is that we do not remove individual * property blocks - we just mark the whole record as !inUse. */ for (PropertyBlock propBlock : propRecord.getPropertyBlocks()) { if (propBlock.isLight()) { propStore.makeHeavy(propBlock); } for (DynamicRecord rec : propBlock.getValueRecords()) { rec.setInUse(false); propRecord.addDeletedRecord(rec); } } propRecord.setInUse(false); nextProp = propRecord.getNextProp(); propStore.updateRecord(propRecord); } }
private long createPropertyChain(Map<String, Object> properties) { if (properties == null || properties.isEmpty()) { return Record.NO_NEXT_PROPERTY.intValue(); } PropertyStore propStore = getPropertyStore(); List<PropertyRecord> propRecords = new ArrayList<PropertyRecord>(); PropertyRecord currentRecord = new PropertyRecord(propStore.nextId()); currentRecord.setInUse(true); currentRecord.setCreated(); propRecords.add(currentRecord); for (Entry<String, Object> entry : properties.entrySet()) { int keyId = indexHolder.getKeyId(entry.getKey()); if (keyId == -1) { keyId = createNewPropertyIndex(entry.getKey()); } PropertyBlock block = new PropertyBlock(); propStore.encodeValue(block, keyId, entry.getValue()); if (currentRecord.size() + block.getSize() > PropertyType.getPayloadSize()) { // Here it means the current block is done for PropertyRecord prevRecord = currentRecord; // Create new record long propertyId = propStore.nextId(); currentRecord = new PropertyRecord(propertyId); currentRecord.setInUse(true); currentRecord.setCreated(); // Set up links prevRecord.setNextProp(propertyId); currentRecord.setPrevProp(prevRecord.getId()); propRecords.add(currentRecord); // Now current is ready to start picking up blocks } currentRecord.addPropertyBlock(block); } /* * Add the property records in reverse order, which means largest * id first. That is to make sure we expand the property store file * only once. */ for (int i = propRecords.size() - 1; i >= 0; i--) { propStore.updateRecord(propRecords.get(i)); } /* * 0 will always exist, if the map was empty we wouldn't be here * and even one property will create at least one record. */ return propRecords.get(0).getId(); }
public void updateIdGenerators() { this.updateHighId(); relTypeStore.updateIdGenerators(); propStore.updateIdGenerators(); relStore.updateHighId(); nodeStore.updateHighId(); }
public boolean isStoreOk() { return getStoreOk() && relTypeStore.getStoreOk() && propStore.getStoreOk() && relStore.getStoreOk() && nodeStore.getStoreOk(); }
private void deleteNode2( long node, DefinedProperty prop1, DefinedProperty prop2, DefinedProperty prop3) throws IOException { ArrayMap<Integer, Pair<DefinedProperty, Long>> props = new ArrayMap<>(); xaCon.getTransaction().nodeLoadProperties(node, false, newPropertyReceiver(props)); int count = 0; for (int keyId : props.keySet()) { long id = props.get(keyId).other(); PropertyRecord record = pStore.getRecord(id); PropertyBlock block = record.getPropertyBlock(props.get(keyId).first().propertyKeyId()); DefinedProperty data = block.newPropertyData(pStore); if (data.propertyKeyId() == prop1.propertyKeyId()) { assertEquals("prop1", MyPropertyKeyToken.getIndexFor(keyId).name()); assertEquals("-string2", data.value()); } else if (data.propertyKeyId() == prop2.propertyKeyId()) { assertEquals("prop2", MyPropertyKeyToken.getIndexFor(keyId).name()); assertEquals(-2, data.value()); } else if (data.propertyKeyId() == prop3.propertyKeyId()) { assertEquals("prop3", MyPropertyKeyToken.getIndexFor(keyId).name()); assertEquals(true, data.value()); xaCon.getTransaction().nodeRemoveProperty(node, prop3.propertyKeyId()); } else { throw new IOException(); } count++; } assertEquals(3, count); CountingPropertyReceiver propertyCounter = new CountingPropertyReceiver(); xaCon.getTransaction().nodeLoadProperties(node, false, propertyCounter); assertEquals(3, propertyCounter.count); MutableRelationshipLoadingPosition pos = getPosition(xaCon, node); Iterator<RelationshipRecord> rels = getMore(xaCon, node, pos).iterator(); assertTrue(rels.hasNext()); xaCon.getTransaction().nodeDelete(node); }
public void logIdUsage(StringLogger.LineLogger msgLog) { msgLog.logLine("Id usage:"); nodeStore.logIdUsage(msgLog); relStore.logIdUsage(msgLog); relTypeStore.logIdUsage(msgLog); propStore.logIdUsage(msgLog); stringLogger.flush(); }
@Override public void rebuildIdGenerators() { relTypeStore.rebuildIdGenerators(); propStore.rebuildIdGenerators(); relStore.rebuildIdGenerators(); nodeStore.rebuildIdGenerators(); super.rebuildIdGenerators(); }
public String getStringFor(T nameRecord) { int recordToFind = nameRecord.getNameId(); Iterator<DynamicRecord> records = nameRecord.getNameRecords().iterator(); Collection<DynamicRecord> relevantRecords = new ArrayList<DynamicRecord>(); while (recordToFind != Record.NO_NEXT_BLOCK.intValue() && records.hasNext()) { DynamicRecord record = records.next(); if (record.inUse() && record.getId() == recordToFind) { recordToFind = (int) record.getNextBlock(); // // TODO: optimize here, high chance next is right one relevantRecords.add(record); records = nameRecord.getNameRecords().iterator(); } } return (String) PropertyStore.getStringFor( PropertyStore.readFullByteArray(nameRecord.getNameId(), relevantRecords, nameStore)); }
@Override public List<WindowPoolStats> getAllWindowPoolStats() { List<WindowPoolStats> list = new ArrayList<WindowPoolStats>(); list.addAll(nodeStore.getAllWindowPoolStats()); list.addAll(propStore.getAllWindowPoolStats()); list.addAll(relStore.getAllWindowPoolStats()); list.addAll(relTypeStore.getAllWindowPoolStats()); return list; }
@Override public void makeStoreOk() { relTypeStore.makeStoreOk(); propStore.makeStoreOk(); relStore.makeStoreOk(); nodeStore.makeStoreOk(); super.makeStoreOk(); isStarted = true; }
@Override public void flushAll() { if (relTypeStore == null || propStore == null || relStore == null || nodeStore == null) { return; } relTypeStore.flushAll(); propStore.flushAll(); relStore.flushAll(); nodeStore.flushAll(); }
private Map<String, Object> getPropertyChain(long nextProp) { PropertyStore propStore = getPropertyStore(); Map<String, Object> properties = new HashMap<String, Object>(); while (nextProp != Record.NO_NEXT_PROPERTY.intValue()) { PropertyRecord propRecord = propStore.getRecord(nextProp); for (PropertyBlock propBlock : propRecord.getPropertyBlocks()) { String key = indexHolder.getStringKey(propBlock.getKeyIndexId()); PropertyData propertyData = propBlock.newPropertyData(propRecord); Object value = propertyData.getValue() != null ? propertyData.getValue() : propBlock.getType().getValue(propBlock, getPropertyStore()); properties.put(key, value); } nextProp = propRecord.getNextProp(); } return properties; }
@Override public void logVersions(StringLogger.LineLogger msgLog) { msgLog.logLine("Store versions:"); super.logVersions(msgLog); nodeStore.logVersions(msgLog); relStore.logVersions(msgLog); relTypeStore.logVersions(msgLog); propStore.logVersions(msgLog); stringLogger.flush(); }
@Test public void testSetBlockSize() throws Exception { targetDirectory.cleanup(); Config config = new Config( MapUtil.stringMap("string_block_size", "62", "array_block_size", "302"), GraphDatabaseSettings.class); StoreFactory sf = new StoreFactory( config, new DefaultIdGeneratorFactory(), new DefaultWindowPoolFactory(), fs.get(), StringLogger.DEV_NULL, null); sf.createNeoStore(file("neo")).close(); initializeStores(); assertEquals(62 + AbstractDynamicStore.BLOCK_HEADER_SIZE, pStore.getStringBlockSize()); assertEquals(302 + AbstractDynamicStore.BLOCK_HEADER_SIZE, pStore.getArrayBlockSize()); ds.stop(); }
private void deleteRel1( long rel, DefinedProperty prop1, DefinedProperty prop2, DefinedProperty prop3, long firstNode, long secondNode, int relType) throws IOException { ArrayMap<Integer, Pair<DefinedProperty, Long>> props = new ArrayMap<>(); xaCon.getTransaction().relLoadProperties(rel, false, newPropertyReceiver(props)); int count = 0; for (int keyId : props.keySet()) { long id = props.get(keyId).other(); PropertyRecord record = pStore.getRecord(id); PropertyBlock block = record.getPropertyBlock(props.get(keyId).first().propertyKeyId()); DefinedProperty data = block.newPropertyData(pStore); if (data.propertyKeyId() == prop1.propertyKeyId()) { assertEquals("prop1", MyPropertyKeyToken.getIndexFor(keyId).name()); assertEquals("-string1", data.value()); } else if (data.propertyKeyId() == prop2.propertyKeyId()) { assertEquals("prop2", MyPropertyKeyToken.getIndexFor(keyId).name()); assertEquals(-1, data.value()); } else if (data.propertyKeyId() == prop3.propertyKeyId()) { assertEquals("prop3", MyPropertyKeyToken.getIndexFor(keyId).name()); assertEquals(false, data.value()); xaCon.getTransaction().relRemoveProperty(rel, prop3.propertyKeyId()); } else { throw new IOException(); } count++; } assertEquals(3, count); CountingPropertyReceiver propertyCounter = new CountingPropertyReceiver(); xaCon.getTransaction().relLoadProperties(rel, false, propertyCounter); assertEquals(3, propertyCounter.count); RelationshipRecord relData = xaCon.getTransaction().relLoadLight(rel); assertEquals(firstNode, relData.getFirstNode()); assertEquals(secondNode, relData.getSecondNode()); assertEquals(relType, relData.getType()); xaCon.getTransaction().relDelete(rel); MutableRelationshipLoadingPosition firstPos = getPosition(xaCon, firstNode); Iterator<RelationshipRecord> first = getMore(xaCon, firstNode, firstPos).iterator(); first.next(); MutableRelationshipLoadingPosition secondPos = getPosition(xaCon, secondNode); Iterator<RelationshipRecord> second = getMore(xaCon, secondNode, secondPos).iterator(); second.next(); assertTrue(first.hasNext()); assertTrue(second.hasNext()); }
private Iterator<Property> loadAllPropertiesOf(PrimitiveRecord primitiveRecord) { Collection<PropertyRecord> records = propertyStore.getPropertyRecordChain(primitiveRecord.getNextProp()); if (null == records) { return IteratorUtil.emptyIterator(); } List<Property> properties = new ArrayList<>(); for (PropertyRecord record : records) { for (PropertyBlock block : record.getPropertyBlocks()) { properties.add(block.getType().readProperty(block.getKeyIndexId(), block, propertyStore)); } } return properties.iterator(); }
@Test public void testProps1() throws Exception { initializeStores(); startTx(); long nodeId = ds.nextId(Node.class); xaCon.getTransaction().nodeCreate(nodeId); pStore.nextId(); DefinedProperty prop = xaCon.getTransaction().nodeAddProperty(nodeId, index("nisse"), new Integer(10)); commitTx(); ds.stop(); initializeStores(); startTx(); xaCon.getTransaction().nodeChangeProperty(nodeId, prop.propertyKeyId(), new Integer(5)); xaCon.getTransaction().nodeRemoveProperty(nodeId, prop.propertyKeyId()); xaCon.getTransaction().nodeDelete(nodeId); commitTx(); ds.stop(); }
/** Closes the node,relationship,property and relationship type stores. */ @Override protected void closeStorage() { if (lastCommittedTxIdSetter != null) lastCommittedTxIdSetter.close(); if (relTypeStore != null) { relTypeStore.close(); relTypeStore = null; } if (propStore != null) { propStore.close(); propStore = null; } if (relStore != null) { relStore.close(); relStore = null; } if (nodeStore != null) { nodeStore.close(); nodeStore = null; } }
private void validateRel2( long rel, DefinedProperty prop1, DefinedProperty prop2, DefinedProperty prop3, long firstNode, long secondNode, int relType) throws IOException { ArrayMap<Integer, Pair<DefinedProperty, Long>> props = new ArrayMap<>(); xaCon.getTransaction().relLoadProperties(rel, false, newPropertyReceiver(props)); int count = 0; for (int keyId : props.keySet()) { long id = props.get(keyId).other(); PropertyRecord record = pStore.getRecord(id); PropertyBlock block = record.getPropertyBlock(props.get(keyId).first().propertyKeyId()); DefinedProperty data = block.newPropertyData(pStore); if (data.propertyKeyId() == prop1.propertyKeyId()) { assertEquals("prop1", MyPropertyKeyToken.getIndexFor(keyId).name()); assertEquals("string2", data.value()); xaCon.getTransaction().relChangeProperty(rel, prop1.propertyKeyId(), "-string2"); } else if (data.propertyKeyId() == prop2.propertyKeyId()) { assertEquals("prop2", MyPropertyKeyToken.getIndexFor(keyId).name()); assertEquals(2, data.value()); xaCon.getTransaction().relChangeProperty(rel, prop2.propertyKeyId(), new Integer(-2)); } else if (data.propertyKeyId() == prop3.propertyKeyId()) { assertEquals("prop3", MyPropertyKeyToken.getIndexFor(keyId).name()); assertEquals(false, data.value()); xaCon.getTransaction().relChangeProperty(rel, prop3.propertyKeyId(), true); } else { throw new IOException(); } count++; } assertEquals(3, count); RelationshipRecord relData = xaCon.getTransaction().relLoadLight(rel); assertEquals(firstNode, relData.getFirstNode()); assertEquals(secondNode, relData.getSecondNode()); assertEquals(relType, relData.getType()); }
private void validateNodeRel2( long node, DefinedProperty prop1, DefinedProperty prop2, DefinedProperty prop3, long rel1, long rel2, int relType1, int relType2) throws IOException { NodeRecord nodeRecord = xaCon.getTransaction().nodeLoadLight(node); assertTrue(nodeRecord != null); ArrayMap<Integer, Pair<DefinedProperty, Long>> props = new ArrayMap<>(); xaCon.getTransaction().nodeLoadProperties(node, false, newPropertyReceiver(props)); int count = 0; for (int keyId : props.keySet()) { long id = props.get(keyId).other(); PropertyRecord record = pStore.getRecord(id); PropertyBlock block = record.getPropertyBlock(props.get(keyId).first().propertyKeyId()); DefinedProperty data = block.newPropertyData(pStore); if (data.propertyKeyId() == prop1.propertyKeyId()) { assertEquals("prop1", MyPropertyKeyToken.getIndexFor(keyId).name()); assertEquals("string2", data.value()); xaCon.getTransaction().nodeChangeProperty(node, prop1.propertyKeyId(), "-string2"); } else if (data.propertyKeyId() == prop2.propertyKeyId()) { assertEquals("prop2", MyPropertyKeyToken.getIndexFor(keyId).name()); assertEquals(2, data.value()); xaCon.getTransaction().nodeChangeProperty(node, prop2.propertyKeyId(), new Integer(-2)); } else if (data.propertyKeyId() == prop3.propertyKeyId()) { assertEquals("prop3", MyPropertyKeyToken.getIndexFor(keyId).name()); assertEquals(false, data.value()); xaCon.getTransaction().nodeChangeProperty(node, prop3.propertyKeyId(), true); } else { throw new IOException(); } count++; } assertEquals(3, count); count = 0; MutableRelationshipLoadingPosition pos = getPosition(xaCon, node); while (true) { Iterable<RelationshipRecord> relData = getMore(xaCon, node, pos); if (!relData.iterator().hasNext()) { break; } for (RelationshipRecord rel : relData) { if (rel.getId() == rel1) { assertEquals(node, rel.getSecondNode()); assertEquals(relType1, rel.getType()); } else if (rel.getId() == rel2) { assertEquals(node, rel.getFirstNode()); assertEquals(relType2, rel.getType()); } else { throw new IOException(); } count++; } } assertEquals(2, count); }
private Pair<byte[], byte[]> loadArray(Collection<DynamicRecord> records) { return PropertyStore.readFullByteArray( first(records).getId(), records, arrayStore, PropertyType.ARRAY); }