示例#1
0
 private boolean unlinkPropertyRecord(PropertyRecord propRecord, PrimitiveRecord primitive) {
   assert propRecord.size() == 0;
   boolean primitiveChanged = false;
   long prevProp = propRecord.getPrevProp();
   long nextProp = propRecord.getNextProp();
   if (primitive.getNextProp() == propRecord.getId()) {
     assert propRecord.getPrevProp() == Record.NO_PREVIOUS_PROPERTY.intValue()
         : propRecord + " for " + primitive;
     primitive.setNextProp(nextProp);
     primitiveChanged = true;
   }
   if (prevProp != Record.NO_PREVIOUS_PROPERTY.intValue()) {
     PropertyRecord prevPropRecord = getPropertyStore().getRecord(prevProp);
     assert prevPropRecord.inUse() : prevPropRecord + "->" + propRecord + " for " + primitive;
     prevPropRecord.setNextProp(nextProp);
     getPropertyStore().updateRecord(prevPropRecord);
   }
   if (nextProp != Record.NO_NEXT_PROPERTY.intValue()) {
     PropertyRecord nextPropRecord = getPropertyStore().getRecord(nextProp);
     assert nextPropRecord.inUse() : propRecord + "->" + nextPropRecord + " for " + primitive;
     nextPropRecord.setPrevProp(prevProp);
     getPropertyStore().updateRecord(nextPropRecord);
   }
   propRecord.setInUse(false);
   /*
    *  The following two are not needed - the above line does all the work (PropertyStore
    *  does not write out the prev/next for !inUse records). It is nice to set this
    *  however to check for consistency when assertPropertyChain().
    */
   propRecord.setPrevProp(Record.NO_PREVIOUS_PROPERTY.intValue());
   propRecord.setNextProp(Record.NO_NEXT_PROPERTY.intValue());
   getPropertyStore().updateRecord(propRecord);
   return primitiveChanged;
 }
示例#2
0
 @Override
 public void checkReference(
     PropertyRecord record,
     PrimitiveRecord owner,
     ConsistencyReport.PropertyConsistencyReport report,
     RecordAccess records) {
   if (!owner.inUse() || Record.NO_NEXT_PROPERTY.is(owner.getNextProp())) {
     wrongOwner(report);
   } else if (owner.getNextProp() != record.getId()) {
     report.forReference(
         property((DiffRecordAccess) records, owner.getNextProp()), OwnerChain.this);
   }
 }
示例#3
0
 private boolean removePrimitiveProperty(PrimitiveRecord primitive, String property) {
   PropertyRecord current = null;
   PropertyBlock target = null;
   long nextProp = primitive.getNextProp();
   int propIndex = indexHolder.getKeyId(property);
   if (nextProp == Record.NO_NEXT_PROPERTY.intValue() || propIndex == -1) {
     // No properties or no one has that property, nothing changed
     return false;
   }
   while (nextProp != Record.NO_NEXT_PROPERTY.intValue()) {
     current = getPropertyStore().getRecord(nextProp);
     if ((target = current.removePropertyBlock(propIndex)) != null) {
       if (target.isLight()) {
         getPropertyStore().makeHeavy(target);
       }
       for (DynamicRecord dynRec : target.getValueRecords()) {
         current.addDeletedRecord(dynRec);
       }
       break;
     }
     nextProp = current.getNextProp();
   }
   if (current.size() > 0) {
     getPropertyStore().updateRecord(current);
     return false;
   } else {
     return unlinkPropertyRecord(current, primitive);
   }
 }
示例#4
0
 private boolean removePrimitiveProperty(PrimitiveRecord primitive, String property) {
   PropertyRecord current = null;
   PropertyBlock target;
   long nextProp = primitive.getNextProp();
   int propIndex = propertyKeyTokens.idOf(property);
   if (nextProp == Record.NO_NEXT_PROPERTY.intValue() || propIndex == -1) {
     // No properties or no one has that property, nothing changed
     return false;
   }
   while (nextProp != Record.NO_NEXT_PROPERTY.intValue()) {
     current = getPropertyStore().getRecord(nextProp);
     if ((target = current.removePropertyBlock(propIndex)) != null) {
       getPropertyStore().ensureHeavy(target);
       for (DynamicRecord dynRec : target.getValueRecords()) {
         dynRec.setInUse(false);
         current.addDeletedRecord(dynRec);
       }
       break;
     }
     nextProp = current.getNextProp();
   }
   assert current != null : "the if statement above prevents it";
   if (current.size() > 0) {
     getPropertyStore().updateRecord(current);
     return false;
   } else {
     current.setInUse(false);
     return unlinkPropertyRecord(current, primitive);
   }
 }
 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();
 }
示例#6
0
  private boolean primitiveHasProperty(PrimitiveRecord record, String propertyName) {
    long nextProp = record.getNextProp();
    int propertyIndex = indexHolder.getKeyId(propertyName);
    if (nextProp == Record.NO_NEXT_PROPERTY.intValue() || propertyIndex == -1) {
      return false;
    }

    PropertyRecord current = null;
    while (nextProp != Record.NO_NEXT_PROPERTY.intValue()) {
      current = getPropertyStore().getRecord(nextProp);
      if (current.getPropertyBlock(propertyIndex) != null) {
        return true;
      }
      nextProp = current.getNextProp();
    }
    return false;
  }
示例#7
0
  /** @return true if the passed primitive needs updating in the store. */
  private boolean setPrimitiveProperty(PrimitiveRecord primitive, String name, Object value) {
    boolean result = false;
    long nextProp = primitive.getNextProp();
    int index = indexHolder.getKeyId(name);

    if (index == -1) {
      index = createNewPropertyIndex(name);
    }
    PropertyBlock block = new PropertyBlock();
    getPropertyStore().encodeValue(block, index, value);
    int size = block.getSize();

    /*
     * current is the current record traversed
     * thatFits is the earliest record that can host the block
     * thatHas is the record that already has a block for this index
     */
    PropertyRecord current = null, thatFits = null, thatHas = null;
    /*
     * We keep going while there are records or until we both found the
     * property if it exists and the place to put it, if exists.
     */
    while (!(nextProp == Record.NO_NEXT_PROPERTY.intValue()
        || (thatHas != null && thatFits != null))) {
      current = getPropertyStore().getRecord(nextProp);
      /*
       * current.getPropertyBlock() is cheap but not free. If we already
       * have found thatHas, then we can skip this lookup.
       */
      if (thatHas == null && current.getPropertyBlock(index) != null) {
        thatHas = current;
        PropertyBlock removed = thatHas.removePropertyBlock(index);
        if (removed.isLight()) {
          getPropertyStore().makeHeavy(removed);
          for (DynamicRecord dynRec : removed.getValueRecords()) {
            thatHas.addDeletedRecord(dynRec);
          }
        }
        getPropertyStore().updateRecord(thatHas);
      }
      /*
       * We check the size after we remove - potentially we can put in the same record.
       *
       * current.size() is cheap but not free. If we already found somewhere
       * where it fits, no need to look again.
       */
      if (thatFits == null && (PropertyType.getPayloadSize() - current.size() >= size)) {
        thatFits = current;
      }
      nextProp = current.getNextProp();
    }
    /*
     * thatHas is of no importance here. We know that the block is definitely not there.
     * However, we can be sure that if the property existed, thatHas is not null and does
     * not contain the block.
     *
     * thatFits is interesting. If null, we need to create a new record and link, otherwise
     * just add the block there.
     */
    if (thatFits == null) {
      thatFits = new PropertyRecord(getPropertyStore().nextId());
      thatFits.setInUse(true);
      result = true;

      if (primitive.getNextProp() != Record.NO_NEXT_PROPERTY.intValue()) {
        PropertyRecord first = getPropertyStore().getRecord(primitive.getNextProp());
        thatFits.setNextProp(first.getId());
        first.setPrevProp(thatFits.getId());
        getPropertyStore().updateRecord(first);
      }
      primitive.setNextProp(thatFits.getId());
    }
    thatFits.addPropertyBlock(block);
    getPropertyStore().updateRecord(thatFits);
    return result;
  }