db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From krist...@apache.org
Subject svn commit: r718936 - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/jdbc/ testing/org/apache/derbyTesting/unitTests/junit/
Date Wed, 19 Nov 2008 11:46:26 GMT
Author: kristwaa
Date: Wed Nov 19 03:46:26 2008
New Revision: 718936

URL: http://svn.apache.org/viewvc?rev=718936&view=rev
Log:
DERBY-3936: Add CharacterStreamDescriptor.
Added a descriptor object for streams representing characters.
The following information is tracked by the descriptor:
 - if the stream can/should be buffered
 - if the stream is position aware (and can reposition itself)
 - the current byte position
 - the current character position (starting at 1, and special value BEFORE_FIRST)
 - byte length
 - character length
 - maximum allowed length (an imposed limit)
 - data offset (in case of headers/metadata in the stream)

Note that the descriptor don't handle encoding. Currently all streams are assumed to use the
modified UTF-8 encoding (which is Derby's on disk format).

This is the first revision, more pieces of information may be added later.
The intended use of the descriptor is to pass enough information to allow readers/decoders
to configure themselves properly at initialization time. The descriptor object is immutable,
and it does not keep it's state in synch with the stream.
Patch file: derby-3936-1b-CharacterStreamDescriptor.diff

Added:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/CharacterStreamDescriptor.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/CharacterStreamDescriptorTest.java
Modified:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/_Suite.java

Added: db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/CharacterStreamDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/CharacterStreamDescriptor.java?rev=718936&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/CharacterStreamDescriptor.java
(added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/CharacterStreamDescriptor.java
Wed Nov 19 03:46:26 2008
@@ -0,0 +1,293 @@
+/*
+
+   Derby - Class org.apache.derby.iapi.jdbc.CharacterStreamDescriptor
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.derby.iapi.jdbc;
+
+import org.apache.derby.iapi.services.sanity.SanityManager;
+
+/**
+ * A description of a byte stream representing characters. The description is
+ * used by decoders to properly configure themselves. Note that encoding is not
+ * included in the description, because all internal byte streams are expected
+ * to be using the modified UTF-8 encoding (see DataInput).
+ * <p>
+ * The information in the description is only guranteed to be valid at the
+ * moment it is passed to the decoder object. As the decoder works on the
+ * stream, the information in the descriptor will be outdated.
+ * <p>
+ * To create a stream descriptor, obtain a {@code Builder} instance and set the
+ * required parameters.
+ *
+ * @see Builder
+ */
+//@Immutable
+public class CharacterStreamDescriptor {
+
+    /**
+     * Constant for the character position, when it is positioned before the
+     * first character in the stream (i.e. at the very beginning of the stream
+     * or in the header).
+     */
+    public static final long BEFORE_FIRST = 0;
+
+    /** First data byte in the byte stream. */
+    private final long dataOffset;
+    /** The current byte position. */
+    private final long curBytePos;
+    /** The current character position. */
+    private final long curCharPos;
+    /** The byte length of the stream, {@code 0} if unknown. */
+    private final long byteLength;
+    /** The character length of the stream, {@code 0} if unknown. */
+    private final long charLength;
+    /** The maximum allowed character length. */
+    private final long maxCharLength;
+    /** Tells if the stream can be buffered or not. */
+    private final boolean bufferable;
+    /** Tells if the stream is aware of its own position. */
+    private final boolean positionAware;
+    /** A (mostly) unique id for the associated stream. */
+    private final int id;
+
+    /**
+     * Creates a character stream descriptor, using the supplied builder.
+     * <p>
+     * Use the builder to create instances of this class.
+     *
+     * @param b object builder
+     * @see Builder
+     */
+    private CharacterStreamDescriptor(Builder b) {
+        bufferable = b.bufferable;
+        positionAware = b.positionAware;
+        dataOffset = b.dataOffset;
+        curBytePos = b.curBytePos;
+        curCharPos = b.curCharPos;
+        byteLength = b.byteLength;
+        charLength = b.charLength;
+        maxCharLength = b.maxCharLength;
+        id = b.id;
+    }
+
+    /**
+     * Tells if the described stream should be buffered or not.
+     * <p>
+     * Some of the reasons a stream should not be buffered at this level, are
+     * the stream is already buffered, or it serves bytes directly from a byte
+     * array in memory.
+     *
+     * @return {@code true} if the stream should be buffered for improved
+     *      performance, {@code false} if it should not be buffered.
+     */
+    public boolean isBufferable() {
+        return bufferable;
+    }
+
+    /**
+     * Tells if the described stream is aware of its own position, and that it
+     * can reposition itself on requrest.
+     *
+     * @return {@code true} if the stream is position aware, @{code false}
+     *      otherwise.
+     */
+    public boolean isPositionAware() {
+        return positionAware;
+    }
+
+    public long getByteLength() {
+        return byteLength;
+    }
+
+    public long getCharLength() {
+        return charLength;
+    }
+
+    public long getCurBytePos() {
+        return curBytePos;
+    }
+
+    /**
+     * Returns the current character position.
+     *
+     * @return The current character position, where the first character is at
+     *      position {@code 1}, or {@code BEFORE_FIRST} if the stream is
+     *      positioned before the first character.
+     */
+    public long getCurCharPos() {
+        return curCharPos;
+    }
+
+    /**
+     * Returns the first index of the described stream that contains real data.
+     * <p>
+     * The information is typically used to filter out meta data at the head of
+     * the stream, and to correctly reset the stream.
+     *
+     * @return The first position in the stream containing real data.
+     */
+    public long getDataOffset() {
+        return dataOffset;
+    }
+
+    /**
+     * Returns the imposed maximum character length on the described stream.
+     * <p>
+     * The default value is {@code Long.MAX_VALUE}.
+     *
+     * @return The max allowed character length of the stream, or {@code 0} if
+     *      no limit has been set.
+     */
+    public long getMaxCharLength() {
+        return maxCharLength;
+    }
+    
+    /**
+     * Returns an id that can be used to identify the associated stream.
+     * <p>
+     * Mostly used for debugging and verification purposes.
+     *
+     * @return An integer id.
+     */
+    public int getStreamId() {
+        return id;
+    }
+
+    public String toString() {
+        return ("CharacterStreamDescriptor-" + hashCode() +"#bufferable=" +
+                bufferable + ":positionAware=" +
+                positionAware + ":byteLength=" + byteLength + ":charLength=" +
+                charLength + ":curBytePos=" + curBytePos + ":curCharPos=" +
+                curCharPos + ":dataOffset=" + dataOffset + ":id=" + id);
+    }
+
+    /**
+     * The builder for the {@code CharacterStreamDescriptor} class. The builder
+     * is used to avoid having a large set of constructors. See the
+     * {@linkplain #build} method for pre-build field validation. Note that the
+     * validation is only performed in sane builds.
+     */
+    public static class Builder {
+ 
+        /** Default max character length is unlimited. */
+        private static final long DEFAULT_MAX_CHAR_LENGTH = Long.MAX_VALUE;
+
+        // See documentation for the fields in the CharacterStreamDescriptor
+        // class. The values below are the field defaults.
+        private boolean bufferable = false;
+        private boolean positionAware = false;
+        private long curBytePos = 0;
+        private long curCharPos = 1;
+        private long byteLength = 0;
+        private long charLength = 0;
+        private long dataOffset = 0;
+        private long maxCharLength = DEFAULT_MAX_CHAR_LENGTH;
+        private int id = -1;
+
+        /**
+         * Creates a builder object.
+         */
+        public Builder() {}
+
+        public Builder bufferable(boolean bufferable) {
+            this.bufferable = bufferable;
+            return this;
+        }
+
+        public Builder positionAware(boolean positionAware) {
+            this.positionAware = positionAware;
+            return this;
+        }
+
+        public Builder curBytePos(long pos) {
+            this.curBytePos = pos;
+            return this;
+        }
+
+        public Builder curCharPos(long pos) {
+            this.curCharPos = pos;
+            return this;
+        }
+
+        public Builder byteLength(long length) {
+            this.byteLength = length;
+            return this;
+        }
+
+        public Builder charLength(long length) {
+            this.charLength = length;
+            return this;
+        }
+
+        public Builder dataOffset(long offset) {
+            this.dataOffset = offset;
+            return this;
+        }
+
+        public Builder maxCharLength(long length) {
+            this.maxCharLength = length;
+            return this;
+        }
+
+        public Builder id(int id) {
+            this.id = id;
+            return this;
+        }
+
+        /**
+         * Creates a descriptor object based on the parameters kept in the
+         * builder instance.
+         * <p>
+         * Default values will be used for parameters for which a value hasn't
+         * been set.
+         * <p>
+         * <b>NOTE</b>: Parameter validation is only performed in sane builds.
+         *
+         * @return A character stream descriptor instance.
+         */
+        public CharacterStreamDescriptor build() {
+            // Do validation only in sane builds.
+            if (SanityManager.DEBUG) {
+                SanityManager.ASSERT(curBytePos >= 0);
+                SanityManager.ASSERT(curCharPos >= 1 ||
+                        curCharPos == BEFORE_FIRST);
+                SanityManager.ASSERT(byteLength >= 0);
+                SanityManager.ASSERT(charLength >= 0);
+                SanityManager.ASSERT(dataOffset >= 0);
+                SanityManager.ASSERT(maxCharLength >= 0);
+
+                // If current byte pos is set, require char pos to be set too.
+                if ((curBytePos != 0 && curCharPos == 0) || 
+                        (curBytePos == 0 && curCharPos > 1)) {
+                    SanityManager.THROWASSERT("Invalid byte/char pos: " +
+                            curBytePos + "/" + curCharPos);
+                }
+                // The byte position cannot be smaller than the character
+                // position minues one (at least one byte per char).
+                SanityManager.ASSERT(curBytePos >= curCharPos -1);
+                // If we're in the header section, the character position must
+                // be before the first character.
+                if (curBytePos < dataOffset) {
+                    SanityManager.ASSERT(curCharPos == BEFORE_FIRST);
+                }
+            }
+            return new CharacterStreamDescriptor(this);
+        }
+    }
+}

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/CharacterStreamDescriptorTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/CharacterStreamDescriptorTest.java?rev=718936&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/CharacterStreamDescriptorTest.java
(added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/CharacterStreamDescriptorTest.java
Wed Nov 19 03:46:26 2008
@@ -0,0 +1,108 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.unitTests.junit.CharacterStreamDescriptorTest
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.derbyTesting.unitTests.junit;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.derby.iapi.jdbc.CharacterStreamDescriptor;
+import org.apache.derbyTesting.junit.BaseTestCase;
+
+/**
+ * Simple tests of the character stream descriptor class.
+ */
+public class CharacterStreamDescriptorTest
+    extends BaseTestCase {
+
+    public CharacterStreamDescriptorTest(String name) {
+        super(name);
+    }
+
+    /**
+     * Tests the default values set by the builder.
+     */
+    public void testDefaultValues() {
+        CharacterStreamDescriptor.Builder b =
+                new CharacterStreamDescriptor.Builder();
+        CharacterStreamDescriptor csd = b.build();
+
+        // Test the default values.
+        assertEquals(false, csd.isBufferable());
+        assertEquals(false, csd.isPositionAware());
+        assertEquals(0, csd.getDataOffset());
+        assertEquals(0, csd.getCurBytePos());
+        assertEquals(1, csd.getCurCharPos());
+        assertEquals(0, csd.getByteLength());
+        assertEquals(0, csd.getCharLength());
+        assertEquals(Long.MAX_VALUE, csd.getMaxCharLength());
+        assertEquals(-1, csd.getStreamId());
+    }
+
+    public void testSetValues() {
+        final long byteLength = 1023;
+        final long charLength = 1023*2;
+        final long curBytePos = 4;
+        final long curCharPos = 2;
+        final long dataOffset = 2;
+        final long maxCharLen = 768;
+        final int streamId = this.hashCode();
+
+        CharacterStreamDescriptor.Builder b =
+                new CharacterStreamDescriptor.Builder().bufferable(true).
+                byteLength(byteLength).charLength(charLength).
+                curBytePos(curBytePos).curCharPos(curCharPos).
+                dataOffset(dataOffset).maxCharLength(maxCharLen).id(streamId);
+        CharacterStreamDescriptor csd = b.build();
+
+        // Test the values.
+        assertEquals(true, csd.isBufferable());
+        assertEquals(false, csd.isPositionAware());
+        assertEquals(dataOffset, csd.getDataOffset());
+        assertEquals(curBytePos, csd.getCurBytePos());
+        assertEquals(curCharPos, csd.getCurCharPos());
+        assertEquals(byteLength, csd.getByteLength());
+        assertEquals(charLength, csd.getCharLength());
+        assertEquals(maxCharLen, csd.getMaxCharLength());
+        assertEquals(streamId, csd.getStreamId());
+
+        // Set only a few values.
+        csd = new CharacterStreamDescriptor.Builder().bufferable(true).
+                positionAware(true). maxCharLength(maxCharLen).build();
+        assertEquals(true, csd.isBufferable());
+        assertEquals(true, csd.isPositionAware());
+        assertEquals(maxCharLen, csd.getMaxCharLength());
+
+        // Set data offset and update the character position accordingly.
+        csd = new CharacterStreamDescriptor.Builder().bufferable(true).
+                positionAware(true).dataOffset(dataOffset).
+                curCharPos(CharacterStreamDescriptor.BEFORE_FIRST).build();
+        assertEquals(true, csd.isBufferable());
+        assertEquals(true, csd.isPositionAware());
+        assertEquals(dataOffset, csd.getDataOffset());
+        assertEquals(CharacterStreamDescriptor.BEFORE_FIRST,
+                csd.getCurCharPos());
+
+    }
+
+    public static Test suite() {
+        return new TestSuite(CharacterStreamDescriptorTest.class,
+                "CharacterStreamDescriptorTest suite");
+    }
+}

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/_Suite.java?rev=718936&r1=718935&r2=718936&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/_Suite.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/junit/_Suite.java Wed
Nov 19 03:46:26 2008
@@ -53,6 +53,7 @@
         suite.addTestSuite(CompressedNumberTest.class);
         suite.addTest(AssertFailureTest.suite());
         suite.addTest(InputStreamUtilTest.suite());
+        suite.addTest(CharacterStreamDescriptorTest.suite());
 
         return suite;
     }



Mime
View raw message