Package lupos.datastructures.paged_dbbptree.node.nodedeserializer

Source Code of lupos.datastructures.paged_dbbptree.node.nodedeserializer.LazyLiteralNodeDeSerializer

/**
* Copyright (c) 2013, Institute of Information Systems (Sven Groppe and contributors of LUPOSDATE), University of Luebeck
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
*   - Redistributions of source code must retain the above copyright notice, this list of conditions and the following
*     disclaimer.
*   - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
*     following disclaimer in the documentation and/or other materials provided with the distribution.
*   - Neither the name of the University of Luebeck nor the names of its contributors may be used to endorse or promote
*     products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package lupos.datastructures.paged_dbbptree.node.nodedeserializer;

import java.io.EOFException;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import lupos.datastructures.items.Triple;
import lupos.datastructures.items.TripleComparator;
import lupos.datastructures.items.TripleKey;
import lupos.datastructures.items.literal.LazyLiteral;
import lupos.datastructures.items.literal.LazyLiteralOriginalContent;
import lupos.datastructures.items.literal.Literal;
import lupos.datastructures.paged_dbbptree.node.DBBPTreeEntry;
import lupos.engine.operators.index.adaptedRDF3X.RDF3XIndexScan;
import lupos.io.helper.InputHelper;
import lupos.io.helper.OutHelper;
import lupos.misc.BitVector;
import lupos.misc.Tuple;

public class LazyLiteralNodeDeSerializer implements NodeDeSerializer<TripleKey, Triple> {

  private static final long serialVersionUID = -8131702796960262942L;

  protected final RDF3XIndexScan.CollationOrder order;

  protected final static int[][] map = { { 0, 1, 2 }, // SPO
      { 0, 2, 1 }, // SOP
      { 1, 0, 2 }, // PSO
      { 1, 2, 0 }, // POS
      { 2, 0, 1 }, // OSP
      { 2, 1, 0 } // OPS
  };

  public LazyLiteralNodeDeSerializer(
      final RDF3XIndexScan.CollationOrder order) {
    this.order = order;
  }

  @Override
  public void writeInnerNodeEntry(final int fileName, final TripleKey key,
      final OutputStream out, final TripleKey lastKey)
      throws IOException {
    final BitVector bits = new BitVector(7);
    bits.set(0);
    final Triple lastValue = (lastKey == null) ? null : lastKey.getTriple();
    final Triple v = key.getTriple();
    final boolean mustWriteLazyLiteralOriginalContent = (v.getObject() instanceof LazyLiteralOriginalContent)
        && (lastValue == null || !(lastValue.getObject().equals(v
            .getObject())));
    if (mustWriteLazyLiteralOriginalContent) {
      bits.set(1);
    } else {
      bits.clear(1);
    }
    int value = 0;
    if (lastValue == null) {
      value = 3;
    } else {
      for (int i = 0; i < 3; i++) {
        if (lastValue != null
            && v.getPos(map[this.order.ordinal()][i]).equals(
                lastValue.getPos(map[this.order.ordinal()][i]))) {
          value++;
        } else {
          break;
        }
      }
    }
    if (value <= 1) {
      bits.clear(2);
    } else {
      bits.set(2);
    }
    if (value % 2 == 0) {
      bits.clear(3);
    } else {
      bits.set(3);
    }

    int index = 3;

    for (int i = 0; i < 3; i++) {
      if (lastValue == null
          || !v.getPos(map[this.order.ordinal()][i]).equals(
              lastValue.getPos(map[this.order.ordinal()][i]))) {
        if (lastValue != null) {
          // determine difference
          final int diff = ((LazyLiteral) v.getPos(map[this.order
              .ordinal()][i])).getCode()
              - ((LazyLiteral) lastValue.getPos(map[this.order
                  .ordinal()][i])).getCode();
          index = determineNumberOfBytesForRepresentation(diff, bits, index, out);
        }
        for (int j = i + ((value == 3) ? 0 : 1); j < 3; j++) {
          // deal with the "rest"
          index = determineNumberOfBytesForRepresentation(
              ((LazyLiteral) v.getPos(map[this.order.ordinal()][j]))
                  .getCode(), bits, index, out);
        }
        break;
      }
    }
    if (mustWriteLazyLiteralOriginalContent) {
      index = determineNumberOfBytesForRepresentation(
          ((LazyLiteralOriginalContent) v.getObject())
              .getCodeOriginalContent(), bits, index, out);
    }
    index = determineNumberOfBytesForRepresentation(fileName, bits, index,
        out);
    bits.writeWithoutSize(out);
    writeIntWithoutLeadingZeros(fileName, out);

    if (mustWriteLazyLiteralOriginalContent) {
      writeIntWithoutLeadingZeros(((LazyLiteralOriginalContent) v
          .getObject()).getCodeOriginalContent(), out);
    }

    for (int i = 0; i < 3; i++) {
      if (lastValue == null
          || !v.getPos(map[this.order.ordinal()][i]).equals(
              lastValue.getPos(map[this.order.ordinal()][i]))) {
        if (lastValue != null) {
          // determine difference
          final int diff = ((LazyLiteral) v.getPos(map[this.order
              .ordinal()][i])).getCode()
              - ((LazyLiteral) lastValue.getPos(map[this.order
                  .ordinal()][i])).getCode();
          writeIntWithoutLeadingZeros(diff, out);
        }
        for (int j = i + ((value == 3) ? 0 : 1); j < 3; j++) {
          // deal with the "rest"
          writeIntWithoutLeadingZeros(((LazyLiteral) v
              .getPos(map[this.order.ordinal()][j])).getCode(), out);
        }
        break;
      }
    }
  }

  @Override
  public void writeInnerNodeEntry(final int fileName, final OutputStream out) throws IOException {
    final BitVector bits = new BitVector(7);
    bits.clear(0);
    determineNumberOfBytesForRepresentation(fileName, bits, 0, out);
    bits.writeWithoutSize(out);
    writeIntWithoutLeadingZeros(fileName, out);
  }

  @Override
  public void writeLeafEntry(final TripleKey k, final Triple v,
      final OutputStream out, final TripleKey lastKey,
      final Triple lastValue) throws IOException {
    final BitVector bits = new BitVector(7);
    bits.set(0);
    final boolean mustWriteLazyLiteralOriginalContent = (v.getObject() instanceof LazyLiteralOriginalContent)
        && (lastValue == null || !(lastValue.getObject().equals(v
            .getObject())));
    if (mustWriteLazyLiteralOriginalContent) {
      bits.set(1);
    } else {
      bits.clear(1);
    }
    int value = 0;
    if (lastValue == null) {
      value = 3;
    } else {
      for (int i = 0; i < 3; i++) {
          if(v.getPos(map[this.order.ordinal()][i]).equals(
                lastValue.getPos(map[this.order.ordinal()][i]))) {
            value++;
          } else {
            break;
          }
      }
    }
    if (value <= 1) {
      bits.clear(2);
    } else {
      bits.set(2);
    }
    if (value % 2 == 0) {
      bits.clear(3);
    } else {
      bits.set(3);
    }

    int index = 3;

    for (int i = 0; i < 3; i++) {
      if (lastValue == null
          || !v.getPos(map[this.order.ordinal()][i]).equals(
              lastValue.getPos(map[this.order.ordinal()][i]))) {
        if (lastValue != null) {
          // determine difference
          final int diff = ((LazyLiteral) v.getPos(map[this.order
              .ordinal()][i])).getCode()
              - ((LazyLiteral) lastValue.getPos(map[this.order
                  .ordinal()][i])).getCode();
          index = determineNumberOfBytesForRepresentation(diff, bits,
              index, out);
        }
        for (int j = i + ((value == 3) ? 0 : 1); j < 3; j++) {
          // deal with the "rest"
          index = determineNumberOfBytesForRepresentation(
              ((LazyLiteral) v.getPos(map[this.order.ordinal()][j]))
                  .getCode(), bits, index, out);
        }
        break;
      }
    }
    if (mustWriteLazyLiteralOriginalContent) {
      index = determineNumberOfBytesForRepresentation(
          ((LazyLiteralOriginalContent) v.getObject())
              .getCodeOriginalContent(), bits, index, out);
    }
    bits.writeWithoutSize(out);

    if (mustWriteLazyLiteralOriginalContent) {
      writeIntWithoutLeadingZeros(((LazyLiteralOriginalContent) v
          .getObject()).getCodeOriginalContent(), out);
    }

    for (int i = 0; i < 3; i++) {
      if (lastValue == null
          || !v.getPos(map[this.order.ordinal()][i]).equals(
              lastValue.getPos(map[this.order.ordinal()][i]))) {
        if (lastValue != null) {
          // determine difference
          final int diff = ((LazyLiteral) v.getPos(map[this.order
              .ordinal()][i])).getCode()
              - ((LazyLiteral) lastValue.getPos(map[this.order
                  .ordinal()][i])).getCode();
          writeIntWithoutLeadingZeros(diff, out);
        }
        for (int j = i + ((value == 3) ? 0 : 1); j < 3; j++) {
          // deal with the "rest"
          writeIntWithoutLeadingZeros(((LazyLiteral) v
              .getPos(map[this.order.ordinal()][j])).getCode(), out);
        }
        break;
      }
    }
  }

  @Override
  public void writeLeafEntryNextFileName(final int filename, final OutputStream out) throws IOException {
    final BitVector bits = new BitVector(7);
    bits.clear(0);
    determineNumberOfBytesForRepresentation(filename, bits, 0, out);
    bits.writeWithoutSize(out);
    writeIntWithoutLeadingZeros(filename, out);
  }

  public static void writeIntWithoutLeadingZeros(final int diff,
      final OutputStream out) throws IOException {
    switch (determineNumberOfBytesForRepresentation(diff)) {
    case 0:
      OutHelper.writeLuposInt1Byte(diff, out);
      break;
    case 1:
      OutHelper.writeLuposInt2Bytes(diff, out);
      break;
    case 2:
      OutHelper.writeLuposInt3Bytes(diff, out);
      break;
    default:
    case 3:
      OutHelper.writeLuposInt(diff, out);
      break;
    }
  }

  public static int determineNumberOfBytesForRepresentation(
      final int diff, final BitVector bits, int index,
      final OutputStream out) throws IOException {
    final int number = determineNumberOfBytesForRepresentation(diff);
    index++;
    if (index == 8) {
      bits.writeWithoutSize(out);
      index = 0;
    }
    if (number >= 2) {
      bits.set(index);
    } else {
      bits.clear(index);
    }
    index++;
    if (number % 2 == 0) {
      bits.clear(index);
    } else {
      bits.set(index);
    }
    return index;
  }

  public static int determineNumberOfBytesForRepresentation(int diff) {
    if (diff < 0) {
      diff *= -1;
    }
    int number = 0;
    while (diff >= 256) {
      diff /= 256;
      number++;
    }
    return number;
  }

  public static int readInt(final BitVector bv, final int index,
      final InputStream in) throws IOException {
    if (bv.get(index)) {
      if (bv.get(index + 1)) {
        return InputHelper.readLuposInteger(in);
      } else {
        return  InputHelper.readLuposInteger3Bytes(in);
      }
    } else {
      if (bv.get(index + 1)) {
        return  InputHelper.readLuposInteger2Bytes(in);

      } else {
        return  InputHelper.readLuposInteger1Byte(in);
      }
    }
  }

  public static int getIntSize(final BitVector bits, int index, final InputStream in) throws IOException {
    index++;
    if (index == 8) {
      bits.readWithoutSize(in, 7);
      index = 0;
    }
    int number = 0;
    if (bits.get(index)) {
      number = 2;
    }
    if (bits.get(index + 1)) {
      number += 1;
    }
    return number;
  }

  public static int getInt(final int number,
      final InputStream in) throws IOException {
    switch (number) {
    case 0:
      return 0;
    case 1:
      return InputHelper.readLuposInteger1Byte(in);
    case 2:
      return InputHelper.readLuposInteger2Bytes(in);
    case 3:
      return InputHelper.readLuposInteger3Bytes(in);
    default:
    case 4:
      return InputHelper.readLuposInteger(in);
    }
  }

  @Override
  public DBBPTreeEntry<TripleKey, Triple> getNextLeafEntry(
      final InputStream in, final TripleKey lastKey,
      final Triple lastValue) {
    return this.getNextLeafEntry(lastValue, in);
  }

  private synchronized DBBPTreeEntry<TripleKey, Triple> getNextLeafEntry(
      final Triple lastTriple, final InputStream in) {
    try {
      BitVector bits;
      try {
        bits = new BitVector(in, 7);
      } catch (final EOFException e) {
        return null;
      }
      if (!bits.get(0)) {
        return new DBBPTreeEntry<TripleKey, Triple>(null, null,
            readInt(bits, 1, in));
      }
      final int filenameOfNextLeafNode = -1;

      final boolean objectIsLazyLiteralOriginalContent = bits.get(1);
      int whereDifferentLiteral = 0;
      if (bits.get(2)) {
        whereDifferentLiteral = 2;
      }
      if (bits.get(3)) {
        whereDifferentLiteral += 1;
      }
      final Triple t = new Triple();
      if(whereDifferentLiteral==3 && lastTriple!=null){
        for(int i=0; i<3; i++) {
          t.setPos(i, lastTriple.getPos(i));
        }
      } else {
        final int numberDifferent = (whereDifferentLiteral==3)?3:3 - whereDifferentLiteral;
        final int[] numberBytesForInt = new int[numberDifferent];
        int index = 3;
        for (int i = 0; i < numberDifferent; i++) {
          numberBytesForInt[i] = getIntSize(bits, index, in);
          index = (index + 2) % 8;
        }
        int codeForOriginalContent = 0;
        if (objectIsLazyLiteralOriginalContent) {
          codeForOriginalContent = getInt(
              getIntSize(bits, index, in) + 1, in);
        }

        int index2 = 0;
        for (int i = 0; i < 3; i++) {
          if (i < whereDifferentLiteral && whereDifferentLiteral != 3) {
            t.setPos(map[this.order.ordinal()][i], lastTriple
                .getPos(map[this.order.ordinal()][i]));
          } else {
            if (whereDifferentLiteral != 3) {
              final int diff = getInt(
                  numberBytesForInt[index2++] + 1, in);
              t.setPos(map[this.order.ordinal()][i], getLiteral(diff
                  + ((LazyLiteral) lastTriple.getPos(map[this.order
                      .ordinal()][i])).getCode(), map[this.order
                  .ordinal()][i], codeForOriginalContent,
                  objectIsLazyLiteralOriginalContent));
            }
            for (int j = i + ((whereDifferentLiteral != 3) ? 1 : 0); j < 3; j++) {
              final int code = getInt(
                  numberBytesForInt[index2++] + 1, in);
              t.setPos(map[this.order.ordinal()][j], getLiteral(code,
                  map[this.order.ordinal()][j],
                  codeForOriginalContent,
                  objectIsLazyLiteralOriginalContent));
            }
            break;
          }
        }
      }
      return new DBBPTreeEntry<TripleKey, Triple>(new TripleKey(t,
          new TripleComparator(this.order)), t, filenameOfNextLeafNode);
    } catch (final FileNotFoundException e) {
      e.printStackTrace();
      System.err.println(e);
    } catch (final IOException e) {
    }
    return null;
  }

  @Override
  public synchronized Tuple<TripleKey, Integer> getNextInnerNodeEntry(
      final TripleKey lastKey, final InputStream in) {
    try {
      BitVector bits;
      try {
        bits = new BitVector(in, 7);
      } catch (final EOFException e) {
        return null;
      }
      if (!bits.get(0)) {
        return new Tuple<TripleKey, Integer>(null, readInt(bits, 1, in));
      }
      final Triple lastTriple = (lastKey == null) ? null : lastKey
          .getTriple();

      final boolean objectIsLazyLiteralOriginalContent = bits.get(1);
      int whereDifferentLiteral = 0;
      if (bits.get(2)) {
        whereDifferentLiteral = 2;
      }
      if (bits.get(3)) {
        whereDifferentLiteral += 1;
      }
      final int numberDifferent = (whereDifferentLiteral == 3) ? 3
          : 3 - whereDifferentLiteral;
      final int[] numberBytesForInt = new int[numberDifferent];
      int index = 3;
      for (int i = 0; i < numberDifferent; i++) {
        numberBytesForInt[i] = getIntSize(bits, index, in);
        index = (index + 2) % 8;
      }
      int codeForOriginalContent = 0;
      if (objectIsLazyLiteralOriginalContent) {
        codeForOriginalContent = getInt(
            getIntSize(bits, index, in) + 1, in);
        index = (index + 2) % 8;
      }

      final int fileName = getInt(getIntSize(bits, index, in) + 1, in);

      final Triple t = new Triple();
      int index2 = 0;
      for (int i = 0; i < 3; i++) {
        if (i < whereDifferentLiteral && whereDifferentLiteral != 3) {
          t.setPos(map[this.order.ordinal()][i], lastTriple
              .getPos(map[this.order.ordinal()][i]));
        } else {
          if (whereDifferentLiteral != 3) {
            final int diff = getInt(
                numberBytesForInt[index2++] + 1, in);
            t.setPos(map[this.order.ordinal()][i], getLiteral(diff
                + ((LazyLiteral) lastTriple.getPos(map[this.order
                    .ordinal()][i])).getCode(), map[this.order
                .ordinal()][i], codeForOriginalContent,
                objectIsLazyLiteralOriginalContent));
          }
          for (int j = i + ((whereDifferentLiteral != 3) ? 1 : 0); j < 3; j++) {
            final int code = getInt(
                numberBytesForInt[index2++] + 1, in);
            t.setPos(map[this.order.ordinal()][j], getLiteral(code,
                map[this.order.ordinal()][j],
                codeForOriginalContent,
                objectIsLazyLiteralOriginalContent));
          }
          break;
        }
      }
      return new Tuple<TripleKey, Integer>(new TripleKey(t,
          new TripleComparator(this.order)), fileName);
    } catch (final FileNotFoundException e) {
      e.printStackTrace();
      System.err.println(e);
    } catch (final IOException e) {
      // just ignore...
    }
    return null;
  }

  public static Literal getLiteral(final int code, final int pos, final int codeForOriginalContent, final boolean objectIsLazyLiteralOriginalContent) {
    if (!objectIsLazyLiteralOriginalContent || pos != 2) {
      return new LazyLiteral(code);
    } else {
      return new LazyLiteralOriginalContent(code, codeForOriginalContent);
    }
  }

  public RDF3XIndexScan.CollationOrder getCollationOrder(){
    return this.order;
  }
}
TOP

Related Classes of lupos.datastructures.paged_dbbptree.node.nodedeserializer.LazyLiteralNodeDeSerializer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.