Package com.slytechs.capture.file.editor

Source Code of com.slytechs.capture.file.editor.MemoryCacheLoader

/**
* Copyright (C) 2007 Sly Technologies, Inc. This library is free software; you
* can redistribute it and/or modify it under the terms of the GNU Lesser
* General Public License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. This
* library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details. You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package com.slytechs.capture.file.editor;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;

import org.jnetstream.capture.file.HeaderReader;
import org.jnetstream.capture.file.RecordFilterTarget;
import org.jnetstream.capture.file.RecordType;
import org.jnetstream.filter.Filter;
import org.jnetstream.packet.ProtocolFilterTarget;

import com.slytechs.utils.memory.BitBuffer;
import com.slytechs.utils.memory.BufferBlock;
import com.slytechs.utils.memory.BufferUtils;
import com.slytechs.utils.memory.MemoryModel;
import com.slytechs.utils.memory.PartialBuffer;

/**
* @author Mark Bednarczyk
* @author Sly Technologies, Inc.
*/
public class MemoryCacheLoader implements PartialLoader {

  private ByteBuffer buffer;

  private final int length;

  private final PartialBuffer partial;

  private boolean readonly = false;

  private final HeaderReader lengthGetter;

  public MemoryCacheLoader(HeaderReader lengthGetter,
      final ByteBuffer... buffers) {
    this.lengthGetter = overrideOffset(lengthGetter);
    // Calculate total number of bytes in all the elements buffers
    int total = 0;
    for (final ByteBuffer b : buffers) {
      total += (b.limit() - b.position());
    }

    this.length = total;

    this.buffer = this.allocate(this.length);
    this.partial =
        new BufferBlock(this.buffer, BitBuffer.wrap(this.buffer), 0,
            this.length);

    // Copy contents from all the elements buffer into our large buffer
    for (final ByteBuffer b : buffers) {
      this.buffer.put(b);
    }
  }

  /**
   * Allocates a memory based buffer and if the copy flag is true, copies the
   * content of the supplied buffer into the newly allocated one. The content is
   * copied from buffer position upto the limit properties. The length is also
   * calculated by the difference between the limit and position properties.
   *
   * @param buffer
   *          buffer to copy contents into our internally allocated buffer
   * @param copy
   *          if true, the contents of the buffer are copied into a new buffer,
   *          otherwise the supplied buffer is used
   * @param headerReader
   *          TODO
   */
  public MemoryCacheLoader(final ByteBuffer buffer, final boolean copy,
      HeaderReader lengthGetter) {
    this.lengthGetter = overrideOffset(lengthGetter);
    this.length = buffer.limit() - buffer.position();

    if (copy) {
      this.buffer = this.allocate(this.length);
      this.buffer.order(buffer.order());
      this.buffer.put(buffer);
    } else {
      if ((buffer.position() != 0) || (buffer.limit() != buffer.capacity())) {
        this.buffer = BufferUtils.slice(buffer);
      } else {
        this.buffer = buffer;
      }
    }

    this.partial =
        new BufferBlock(this.buffer, BitBuffer.wrap(this.buffer), 0,
            this.length);
  }

  /**
   * <p>
   * Allocates a memory based on two buffers copies their into a newly allocated
   * one. The content is copied from buffers position upto the limit properties.
   * The length is also calculated by the difference between the limit and
   * position properties of the combined two buffers.
   * </p>
   * <p>
   * This version of the constructor is primarily used when you have the records
   * header and content in two separate buffers and they need to be merged
   * together.
   * </p>
   *
   * @param buffer1
   *          buffer to copy contents into our internally allocated buffer
   * @param buffer1
   * @param buffer2
   *          second buffer to copy contents into our internally allocated
   *          buffer
   * @param buffer2
   * @param headerReader
   *          TODO
   */
  public MemoryCacheLoader(final ByteBuffer buffer1, final ByteBuffer buffer2,
      HeaderReader lengthGetter) {
    this.lengthGetter = overrideOffset(lengthGetter);
    this.length =
        (buffer1.limit() - buffer1.position())
            + (buffer2.limit() - buffer2.position());

    this.buffer = this.allocate(this.length);
    this.buffer.put(buffer1);
    this.buffer.put(buffer2);

    this.partial =
        new BufferBlock(this.buffer, BitBuffer.wrap(this.buffer), 0,
            this.length);
  }

  /**
   * Allocates a memory based and cached loader with the specified buffer
   * length. The buffer is uninitialized and needs to be initialized externally.
   *
   * @param length
   *          number of bytes to allocate for the buffer
   * @param headerReader
   *          TODO
   */
  public MemoryCacheLoader(final int length, HeaderReader lengthGetter) {
    this.length = length;
    this.lengthGetter = overrideOffset(lengthGetter);
    this.buffer = this.allocate(length);

    this.partial =
        new BufferBlock(this.buffer, BitBuffer.wrap(this.buffer), 0, length);
  }

  private static HeaderReader overrideOffset(final HeaderReader lengthGetter) {

    if (true) {
      return lengthGetter;
    }

    final HeaderReader newGetter = new HeaderReader() {
      final HeaderReader delagate = lengthGetter;

      /**
       * @return
       * @see org.jnetstream.capture.file.HeaderReader#getOffset()
       */
      public int getOffset() {
        return 0;
      }

      /**
       * @return
       * @see org.jnetstream.capture.file.HeaderReader#getMinLength()
       */
      public int getMinLength() {
        return this.delagate.getMinLength();
      }

      /**
       * @param b
       * @return
       * @see org.jnetstream.capture.file.HeaderReader#readLength(java.nio.ByteBuffer)
       */
      public long readLength(ByteBuffer b) {
        return this.delagate.readLength(b);
      }

      public RecordType readType(ByteBuffer buffer) {
        return this.delagate.readType(buffer);
      }

      public int getHeaderLength(ByteBuffer buffer) {
        return this.delagate.getHeaderLength(buffer);
      }

      public RecordFilterTarget readRecordFilterTarget(ByteBuffer buffer) {
        return this.delagate.readRecordFilterTarget(buffer);
      }

      public Filter<RecordFilterTarget> asRecordFilter(
          Filter<ProtocolFilterTarget> filter, ProtocolFilterTarget protocol) {
        return this.delagate.asRecordFilter(filter, protocol);
      }
    };

    return newGetter;
  }

  private final ByteBuffer allocate(final int length) {
    // return Malloc.getDefault().allocateBuffer(length);

    return ByteBuffer.allocate(length);
  }

  /*
   * (non-Javadoc)
   *
   * @see com.slytechs.capture.file.editor.PartialLoader#checkBoundary(long)
   */
  public void checkBoundaryRegional(final long regional)
      throws IndexOutOfBoundsException {
    final int local = (int) this.partial.mapRegionalToLocal(regional);

    if ((local < 0) || (local > this.buffer.capacity())) {
      throw new IndexOutOfBoundsException("Index out of bounds [0 - "
          + this.buffer.capacity() + "]");
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see com.slytechs.capture.file.editor.PartialLoader#checkBoundary(long,
   *      long)
   */
  public void checkBoundaryRegional(final long regional, final long length)
      throws IndexOutOfBoundsException {
    if (length == 0) {
      this.checkBoundaryRegional(regional);
    } else {
      this.checkBoundaryRegional(regional + length - 1);
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see java.io.Closeable#close()
   */
  public void close() throws IOException {
    // Empty, nothing to do
  }

  /*
   * (non-Javadoc)
   *
   * @see com.slytechs.capture.file.editor.PartialLoader#fetchBlock(long, int)
   */
  public PartialBuffer fetchBlock(final long regional, final int length)
      throws IOException {
    this.checkBoundaryRegional(regional, length);

    this.partial.reposition(regional, length);

    return this.partial;
  }

  /*
   * (non-Javadoc)
   *
   * @see com.slytechs.capture.file.editor.PartialLoader#fetchBlock(long, int,
   *      com.slytechs.utils.memory.MemoryModel)
   */
  public PartialBuffer fetchBlock(final long regional, final int length,
      final MemoryModel model) throws IOException {
    return this.fetchBlock(regional, length);
  }

  /*
   * (non-Javadoc)
   *
   * @see com.slytechs.capture.file.editor.PartialLoader#fetchMinimum(long, int)
   */
  public PartialBuffer fetchMinimum(final long regional, final int length)
      throws IOException {

    final int minimum = pickMinimum(regional, length);

    partial.reposition(regional, minimum);

    return partial;
  }

  /*
   * (non-Javadoc)
   *
   * @see com.slytechs.capture.file.editor.PartialLoader#fetchMinimum(long, int,
   *      com.slytechs.utils.memory.MemoryModel)
   */
  public PartialBuffer fetchMinimum(final long regional, final int length,
      final MemoryModel model) throws IOException {

    return fetchMinimum(regional, length);
  }

  private int pickMinimum(final long regional, final int length) {
    final int remaining = this.length - (int) regional;

    return ((remaining < length) ? remaining : length);
  }

  /*
   * (non-Javadoc)
   *
   * @see com.slytechs.capture.file.editor.PartialLoader#getBufferAllocation()
   */
  public int getBufferAllocation(long length) {
    return this.length;
  }

  /*
   * (non-Javadoc)
   *
   * @see com.slytechs.capture.file.editor.PartialLoader#getByteOrder()
   */
  public ByteOrder getByteOrder() {
    return this.buffer.order();
  }

  /*
   * (non-Javadoc)
   *
   * @see com.slytechs.capture.file.editor.PartialLoader#getLength()
   */
  public long getLength() {
    return this.length;
  }

  /*
   * (non-Javadoc)
   *
   * @see com.slytechs.capture.file.editor.PartialLoader#getMemoryModel()
   */
  public MemoryModel getMemoryModel() {
    return MemoryModel.DirectBuffer;
  }

  /*
   * (non-Javadoc)
   *
   * @see com.slytechs.capture.file.editor.PartialLoader#isInMemory(long)
   */
  public boolean isInMemory(final long position) {
    return true;
  }

  /*
   * (non-Javadoc)
   *
   * @see com.slytechs.utils.collection.Readonly#isReadonly()
   */
  public boolean isReadonly() {
    return this.readonly;
  }

  /*
   * (non-Javadoc)
   *
   * @see com.slytechs.capture.file.editor.PartialLoader#isWithinBoundary(long)
   */
  public boolean isWithinBoundary(final long index) {
    if ((index >= 0) && (index < this.length)) {
      return true;
    } else {
      return false;
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see com.slytechs.capture.file.editor.PartialLoader#setBufferPrefetchSize(int)
   */
  public void setBufferPrefetchSize(final int bufferAllocation) {
    // Empty, does nothing
  }

  /*
   * (non-Javadoc)
   *
   * @see com.slytechs.capture.file.editor.PartialLoader#setByteOrder(java.nio.ByteOrder)
   */
  public void order(final ByteOrder order) {
    this.buffer.order(order);
  }

  /*
   * (non-Javadoc)
   *
   * @see com.slytechs.utils.collection.Readonly#setReadonly(boolean)
   */
  public boolean setReadonly(final boolean state) {

    if (state != this.readonly) {

      if (state == true) {
        this.buffer = BufferUtils.asReadonly(this.buffer);
        this.partial.setBuffer(this.buffer);
      }

    }

    this.readonly = state;

    return true;
  }

  @Override
  public String toString() {
    return "Heap";
  }

  /*
   * (non-Javadoc)
   *
   * @see com.slytechs.capture.file.editor.PartialLoader#transferTo(java.nio.channels.FileChannel)
   */
  public long transferTo(final FileChannel out) throws IOException {
    return this.transferTo(0, this.length, out);
  }

  /*
   * (non-Javadoc)
   *
   * @see com.slytechs.capture.file.editor.PartialLoader#transferTo(long, long,
   *      java.nio.channels.FileChannel)
   */
  public long transferTo(final long position, final long length,
      final FileChannel out) throws IOException {

    this.buffer.position((int) position);
    this.buffer.limit((int) (position + length));

    return out.write(this.buffer);
  }

  /*
   * (non-Javadoc)
   *
   * @see com.slytechs.capture.file.editor.PartialLoader#getLengthGetter()
   */
  public HeaderReader getLengthGetter() {
    return lengthGetter;
  }

}
TOP

Related Classes of com.slytechs.capture.file.editor.MemoryCacheLoader

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.