Package ej.sp

Class ShieldedPlug


  • public class ShieldedPlug
    extends Object

    A shielded plug is a database that contains several memory blocks.

    A shielded plug can be created at runtime using createDatabase(int) or be created at startup and retrieved by getDatabase(int).

    The list of memory blocks IDs can be retrieve using getIDs().
    There are two sorts of shielded plugs:

    1. The immutable ones (isImmutable()) that cannot be modified.
    2. The mutable ones (!isImmutable()) can be modified by adding or removing blocks using create(int, int) or create(int, int, int) or delete(int).

    Each block has fixed length (getLength(int) passing the block ID).
    All access to a database is serialized by the implementation: there will be only one access (either read or write) at a time. Each access to a block is atomic, this avoids inconsistency:

    • It can be read using one of the read methods that match its length.
    • It can be written using one the write methods that match its length.

    Each memory block has a flag that indicates that an update has occurred since the last read. It is possible to test this state: isPending(int). This flag is set to false when reading, and to true when writing.

    A task can wait for the modification of a memory block by using waitFor(int). This method suspends the current task if and only if the method pending returns false on the specified memory block. A task can also wait on several memory blocks, the task is released when one of the blocks is modified waitFor(int[])).

    Each memory block has a flag indicating if its data are available or not. It is possible to test this flag using isDataAvailable(int). This flag is initially false and is set to true when writing data. It can be set to false using the method reset(int).

    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void create​(int blockID, int length)
      Creates a block with the given ID.
      void create​(int blockID, int length, int maxTasks)
      Creates a block with the given ID.
      static ShieldedPlug createDatabase​(int ID)
      Creates a new empty database with the given ID.
      void delete​(int blockID)
      Deletes the block with the given ID.
      static ShieldedPlug getDatabase​(int ID)
      Returns the database defined at the given ID.
      int getID()
      Gets the ID of this database.
      int[] getIDs()
      Gets the list of IDs of the blocks available in this database.
      int getLength​(int blockID)
      Returns the length of the block with the given ID.
      int getMaxTasks​(int blockID)
      Gets the maximum number of tasks that can wait at the same time on the block defined with the given ID.
      SPReader getReader​(int blockID)
      Gets the SPReader used to de-serialize objects from the block with the given ID.
      If no SPReader is defined for the block, null is returned.
      int getSize()
      Gets the number of blocks of this database.
      SPWriter getWriter​(int blockID)
      Gets the SPWriter used to serialize objects into the block with the given ID.
      If no SPWriter is defined for the block, null is returned.
      boolean isDataAvailable​(int blockID)
      Determines whether data in the block with the given ID are available or not.
      By default no data is available in a block.
      boolean isImmutable()
      Gets if this database is immutable or not.
      boolean isPending​(int blockID)
      Gets if data has been written into the block since last read.
      void read​(int blockID, byte[] data)
      Fills the given array with data from the block with the given ID.
      void read​(int blockID, byte[] data, int destOffset)
      Fills the given array with block.length bytes from the block with the given ID.
      double readDouble​(int blockID)
      Reads eight input bytes from the block with the given ID and returns a double value.
      The way the double is built from the eight bytes is platform dependent.
      float readFloat​(int blockID)
      Reads four input bytes from the block with the given ID and returns a float value.
      The way the float is built from the four bytes is platform dependent.
      int readInt​(int blockID)
      Reads four input bytes from the block with the given ID and returns an int value.
      The way the int is built from the four bytes is platform dependent.
      long readLong​(int blockID)
      Reads eight input bytes from the block with the given ID and returns a long value.
      The way the long is built from the eight bytes is platform dependent.
      Object readObject​(int blockID)
      Invokes the readObject method of the SPReader registered for the block with the given ID.
      void reset​(int blockID)
      Resets data of the block with the given ID.
      After execution of this method, isDataAvailable(int) method would return false (unless data were written after calling reset(int) and before calling isDataAvailable(int)).
      void setReader​(int blockID, SPReader reader)
      Registers the given SPReader to de-serialize objects from the block with the given ID.
      If an SPReader is already defined for the block, it is replaced by the given SPReader.
      void setWriter​(int blockID, SPWriter writer)
      Registers the given SPWriter to serialize objects into the block with the given ID.
      If an SPWriter is already defined for the block, it is replaced by the given SPWriter.
      void waitFor​(int blockID)
      Causes current thread to wait until another thread write data into the block with the given ID.
      If data has been written in the block since last read, this method returns immediately.
      int[] waitFor​(int[] blockIDs)
      Causes current thread to wait until another thread write data into at least one block from the blocks with the given IDs.
      If data has been written in one block since last read from it, this method returns immediately.
      void write​(int blockID, byte[] data)
      Writes block length bytes from the specified byte array to the block with the given ID.
      The write(blockID, data) method has the same effect as:
      void write​(int blockID, byte[] data, int srcOffset)
      Writes block length bytes from the specified byte array to the block with the given ID.
      Element data[destOffset] is the first byte written to the block.
      void writeDouble​(int blockID, double value)
      Writes a double value, which is comprised of eight bytes, to the block with the given ID.
      The way the double is written from the eight bytes is platform dependent.
      void writeFloat​(int blockID, float value)
      Writes a float value, which is comprised of four bytes, to the block with the given ID.
      The way the float is written from the four bytes is platform dependent.
      void writeInt​(int blockID, int value)
      Writes an int value, which is comprised of four bytes, to the block with the given ID.
      The way the int is written from the four bytes is platform dependent.
      void writeLong​(int blockID, long value)
      Writes a long value, which is comprised of eight bytes, to the block with the given ID.
      The way the long is written from the eight bytes is platform dependent.
      void writeObject​(int blockID, Object o)
      Invokes the writeObject method of the SPWriter registered for the block with the given ID.
    • Method Detail

      • getDatabase

        public static ShieldedPlug getDatabase​(int ID)
        Returns the database defined at the given ID.
        Parameters:
        ID - the identification number of the requested database
        Returns:
        the database with the given ID
        Throws:
        IllegalArgumentException - if no database is defined with the given ID
      • createDatabase

        public static ShieldedPlug createDatabase​(int ID)
        Creates a new empty database with the given ID.
        Parameters:
        ID - the identification number of the created database
        Returns:
        the created database
        Throws:
        IllegalArgumentException - if a database with the given ID already exists
        SecurityException - if the platform cannot create dynamically databases
      • isImmutable

        public boolean isImmutable()
        Gets if this database is immutable or not.
        Returns:
        true if no block can be added or remove to this database, false otherwise
      • delete

        public void delete​(int blockID)
        Deletes the block with the given ID.
        Parameters:
        blockID - the ID of the block to delete
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
        SecurityException - if this database is immutable
      • create

        public void create​(int blockID,
                           int length,
                           int maxTasks)
        Creates a block with the given ID.
        Parameters:
        blockID - the ID of the block to create
        length - the length in bytes of the block to create
        maxTasks - maximum number of tasks that can wait at the same time for a modification of the block
        Throws:
        IllegalArgumentException - if a block is already defined with the given ID
        SecurityException - if this database is immutable
      • create

        public void create​(int blockID,
                           int length)
        Creates a block with the given ID. An unlimited number of tasks will be able to wait at the same time for a modification of the block.
        Parameters:
        blockID - the ID of the block to create
        length - the length in bytes of the block to create
        Throws:
        IllegalArgumentException - if a block is already defined with the given ID
        SecurityException - if this database is immutable
      • getID

        public int getID()
        Gets the ID of this database.
        Returns:
        the ID of this database
      • getSize

        public int getSize()
        Gets the number of blocks of this database.
        Returns:
        the number of blocks in this database
      • getIDs

        public int[] getIDs()
        Gets the list of IDs of the blocks available in this database.
        Returns:
        the list of the IDs of the blocks available in this database
      • getLength

        public int getLength​(int blockID)
        Returns the length of the block with the given ID.
        Parameters:
        blockID - the ID of the block
        Returns:
        the length in bytes
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
      • getMaxTasks

        public int getMaxTasks​(int blockID)
        Gets the maximum number of tasks that can wait at the same time on the block defined with the given ID.
        Parameters:
        blockID - the ID of the block
        Returns:
        the maximum number of tasks that can wait at the same time on the block defined with the given ID, or -1 if infinite
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
      • read

        public void read​(int blockID,
                         byte[] data)
                  throws EmptyBlockException
        Fills the given array with data from the block with the given ID. The number of bytes read is equal to the length of the block.
        The read(blockID, data) method has the same effect as:
          read(blockID, data, 0) 
         
        Parameters:
        blockID - the ID of the block
        data - the buffer into which the data is read
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
        EmptyBlockException - if no data is available in the block
        IndexOutOfBoundsException - if data.length is lower than block length
      • read

        public void read​(int blockID,
                         byte[] data,
                         int destOffset)
                  throws EmptyBlockException
        Fills the given array with block.length bytes from the block with the given ID. The first byte read is stored into element data[destOffset].

        If destOffset is negative or destOffset + block length is greater than the length of the array data, then an IndexOutOfBoundsException is thrown.

        Parameters:
        blockID - the ID of the block
        data - the buffer into which the data is read
        destOffset - the start offset in array data at which the data is written
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
        EmptyBlockException - if no data is available in the block
        IndexOutOfBoundsException - if destOffset is negative or if data.length is lower than destOffset + block length
      • readInt

        public int readInt​(int blockID)
                    throws EmptyBlockException
        Reads four input bytes from the block with the given ID and returns an int value.
        The way the int is built from the four bytes is platform dependent.

        This method is suitable for reading bytes written by the writeInt method.

        Parameters:
        blockID - the ID of the block
        Returns:
        the int value read
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
        EmptyBlockException - if no data is available in the block
        IndexOutOfBoundsException - if block length is not four bytes
      • readLong

        public long readLong​(int blockID)
                      throws EmptyBlockException
        Reads eight input bytes from the block with the given ID and returns a long value.
        The way the long is built from the eight bytes is platform dependent.

        This method is suitable for reading bytes written by the writeLong method.

        Parameters:
        blockID - the ID of the block
        Returns:
        the long value read
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
        EmptyBlockException - if no data is available in the block
        IndexOutOfBoundsException - if block length is not height bytes
      • readFloat

        public float readFloat​(int blockID)
                        throws EmptyBlockException
        Reads four input bytes from the block with the given ID and returns a float value.
        The way the float is built from the four bytes is platform dependent.

        This method is suitable for reading bytes written by the writeFloat method.

        Parameters:
        blockID - the ID of the block
        Returns:
        the float value read
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
        EmptyBlockException - if no data is available in the block
        IndexOutOfBoundsException - if block length is not four bytes
      • readDouble

        public double readDouble​(int blockID)
                          throws EmptyBlockException
        Reads eight input bytes from the block with the given ID and returns a double value.
        The way the double is built from the eight bytes is platform dependent.

        This method is suitable for reading bytes written by the writeDouble method.

        Parameters:
        blockID - the ID of the block
        Returns:
        the double value read
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
        EmptyBlockException - if no data is available in the block
        IndexOutOfBoundsException - if block length is not height bytes
      • setReader

        public void setReader​(int blockID,
                              SPReader reader)
        Registers the given SPReader to de-serialize objects from the block with the given ID.
        If an SPReader is already defined for the block, it is replaced by the given SPReader.
        Parameters:
        blockID - the ID of the block
        reader - the SPReader
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
      • getReader

        @Nullable
        public SPReader getReader​(int blockID)
        Gets the SPReader used to de-serialize objects from the block with the given ID.
        If no SPReader is defined for the block, null is returned.
        Parameters:
        blockID - the ID of the block
        Returns:
        the SPReader set or null if none
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
      • write

        public void write​(int blockID,
                          byte[] data)
        Writes block length bytes from the specified byte array to the block with the given ID.
        The write(blockID, data) method has the same effect as:
          write(blockID, data, 0) 
         
        Parameters:
        blockID - the ID of the block
        data - the data to write
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
        IndexOutOfBoundsException - if data.length value is lower than block length
      • write

        public void write​(int blockID,
                          byte[] data,
                          int srcOffset)
        Writes block length bytes from the specified byte array to the block with the given ID.
        Element data[destOffset] is the first byte written to the block.

        If destOffset is negative, or destOffset + block length is greater than the length of the array data, then an IndexOutOfBoundsException is thrown.

        Parameters:
        blockID - the ID of the block
        data - the data to write
        srcOffset - the start offset in the data
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
        IndexOutOfBoundsException - if destOffset is negative or if data.length is lower than offset + block length
      • writeInt

        public void writeInt​(int blockID,
                             int value)
        Writes an int value, which is comprised of four bytes, to the block with the given ID.
        The way the int is written from the four bytes is platform dependent.

        The bytes written by this method may be read by the readInt method, which will then return an int equal to value.

        Parameters:
        blockID - the ID of the block
        value - the int value to be written
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
        IndexOutOfBoundsException - if block length is not four bytes
      • writeLong

        public void writeLong​(int blockID,
                              long value)
        Writes a long value, which is comprised of eight bytes, to the block with the given ID.
        The way the long is written from the eight bytes is platform dependent.

        The bytes written by this method may be read by the readLong method, which will then return a long equal to value.

        Parameters:
        blockID - the ID of the block
        value - the long value to be written
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
        IndexOutOfBoundsException - if block length is not eight bytes
      • writeFloat

        public void writeFloat​(int blockID,
                               float value)
        Writes a float value, which is comprised of four bytes, to the block with the given ID.
        The way the float is written from the four bytes is platform dependent.

        The bytes written by this method may be read by the readFloat method, which will then return a float equal to value.

        Parameters:
        blockID - the ID of the block
        value - the float value to be written
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
        IndexOutOfBoundsException - if block length is not four bytes
      • writeDouble

        public void writeDouble​(int blockID,
                                double value)
        Writes a double value, which is comprised of eight bytes, to the block with the given ID.
        The way the double is written from the eight bytes is platform dependent.

        The bytes written by this method may be read by the readDouble method, which will then return a double equal to value.

        Parameters:
        blockID - ID of the block
        value - the double value to be written
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
        IndexOutOfBoundsException - if block length is not eight bytes
      • writeObject

        public void writeObject​(int blockID,
                                Object o)
        Invokes the writeObject method of the SPWriter registered for the block with the given ID.
        The SPWriter is responsible for the serialization of the object into the block.
        Parameters:
        blockID - the ID of the block
        o - the object to be written
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
        NullPointerException - if no SPWriter has been registered for the block
        IndexOutOfBoundsException - if block length is lower than the size needed for object serialization
      • setWriter

        public void setWriter​(int blockID,
                              SPWriter writer)
        Registers the given SPWriter to serialize objects into the block with the given ID.
        If an SPWriter is already defined for the block, it is replaced by the given SPWriter.
        Parameters:
        blockID - the ID of the block
        writer - the SPWriter
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
      • getWriter

        @Nullable
        public SPWriter getWriter​(int blockID)
        Gets the SPWriter used to serialize objects into the block with the given ID.
        If no SPWriter is defined for the block, null is returned.
        Parameters:
        blockID - the ID of the block
        Returns:
        the SPWriter set or null if none
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
      • waitFor

        public void waitFor​(int blockID)
                     throws InterruptedException
        Causes current thread to wait until another thread write data into the block with the given ID.
        If data has been written in the block since last read, this method returns immediately.
        Parameters:
        blockID - the ID of the block
        Throws:
        InterruptedException - if another thread has interrupted the current thread The interrupted status of the current thread is cleared when this exception is thrown
        IllegalArgumentException - if no block is defined with the given ID
        TooManyWaitingThreadsException - if too many threads are waiting for new data
      • waitFor

        public int[] waitFor​(int[] blockIDs)
                      throws InterruptedException
        Causes current thread to wait until another thread write data into at least one block from the blocks with the given IDs.
        If data has been written in one block since last read from it, this method returns immediately.
        Parameters:
        blockIDs - the list of block IDs
        Returns:
        the list of IDs of the blocks that has been written
        Throws:
        InterruptedException - if another thread has interrupted the current thread The interrupted status of the current thread is cleared when this exception is thrown
        IllegalArgumentException - if one of the ID does not correspond to an existing block
        TooManyWaitingThreadsException - if too many threads are waiting for new data
      • isPending

        public boolean isPending​(int blockID)
        Gets if data has been written into the block since last read.
        Parameters:
        blockID - the ID of the block
        Returns:
        true if data has been written into the block since last read, false otherwise
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
      • isDataAvailable

        public boolean isDataAvailable​(int blockID)
        Determines whether data in the block with the given ID are available or not.
        By default no data is available in a block. When data are written in a block, they remain available until method reset(int) is called.
        Parameters:
        blockID - the ID of the block
        Returns:
        true if data is available in the block false otherwise
        Throws:
        IllegalArgumentException - if no block is defined with the given ID
      • reset

        public void reset​(int blockID)
        Resets data of the block with the given ID.
        After execution of this method, isDataAvailable(int) method would return false (unless data were written after calling reset(int) and before calling isDataAvailable(int)).
        Parameters:
        blockID - the ID of the block
        Throws:
        IllegalArgumentException - if no block is defined with the given ID