Ejemplo n.º 1
0
            public void seek(long desired)
            {
                if (desired == 0 && bytes.Count == 0)
                {
                    logEmptySeek(name);
                    return;
                }
                int i = 0;

                foreach (DiskRange curRange in bytes)
                {
                    if (desired == 0 && curRange.getData().remaining() == 0)
                    {
                        logEmptySeek(name);
                        return;
                    }
                    if (curRange.getOffset() <= desired &&
                        (desired - curRange.getOffset()) < curRange.getLength())
                    {
                        currentOffset = desired;
                        currentRange  = i;
                        this.range    = curRange.getData().duplicate();
                        int pos = range.position();
                        pos += (int)(desired - curRange.getOffset()); // this is why we duplicate
                        this.range.position(pos);
                        return;
                    }
                    ++i;
                }
                // if they are seeking to the precise end, go ahead and let them go there
                int segments = bytes.Count;

                if (segments != 0 && desired == bytes[segments - 1].getEnd())
                {
                    currentOffset = desired;
                    currentRange  = segments - 1;
                    DiskRange curRange = bytes[currentRange];
                    this.range = curRange.getData().duplicate();
                    int pos = range.position();
                    pos += (int)(desired - curRange.getOffset()); // this is why we duplicate
                    this.range.position(pos);
                    return;
                }
                throw new ArgumentException("Seek in " + name + " to " +
                                            desired + " is outside of the data");
            }
Ejemplo n.º 2
0
            private void seek(long desired)
            {
                if (desired == 0 && bytes.Count == 0)
                {
                    logEmptySeek(name);
                    return;
                }
                int i = 0;

                foreach (DiskRange range in bytes)
                {
                    if (range.getOffset() <= desired && desired < range.getEnd())
                    {
                        currentRange = i;
                        compressed   = range.getData().duplicate();
                        int pos = compressed.position();
                        pos += (int)(desired - range.getOffset());
                        compressed.position(pos);
                        currentOffset = desired;
                        return;
                    }
                    ++i;
                }
                // if they are seeking to the precise end, go ahead and let them go there
                int segments = bytes.Count;

                if (segments != 0 && desired == bytes[segments - 1].getEnd())
                {
                    DiskRange range = bytes[segments - 1];
                    currentRange = segments - 1;
                    compressed   = range.getData().duplicate();
                    compressed.position(compressed.limit());
                    currentOffset = desired;
                    return;
                }
                throw new IOException("Seek outside of data in " + this + " to " + desired);
            }
Ejemplo n.º 3
0
            /* slices a read only contiguous buffer of chunkLength */
            private ByteBuffer slice(int chunkLength)
            {
                int        len       = chunkLength;
                long       oldOffset = currentOffset;
                ByteBuffer slice;

                if (compressed.remaining() >= len)
                {
                    slice = compressed.slice();
                    // simple case
                    slice.limit(len);
                    currentOffset += len;
                    compressed.position(compressed.position() + len);
                    return(slice);
                }
                else if (currentRange >= (bytes.Count - 1))
                {
                    // nothing has been modified yet
                    throw new IOException("EOF in " + this + " while trying to read " +
                                          chunkLength + " bytes");
                }

                if (LOG.isDebugEnabled())
                {
                    LOG.debug(String.Format(
                                  "Crossing into next BufferChunk because compressed only has %d bytes (needs %d)",
                                  compressed.remaining(), len));
                }

                // we need to consolidate 2 or more buffers into 1
                // first copy out compressed buffers
                ByteBuffer copy = allocateBuffer(chunkLength, compressed.isDirect());

                currentOffset += compressed.remaining();
                len           -= compressed.remaining();
                copy.put(compressed);

                for (int i = currentRange; i < bytes.Count && len > 0; i++)
                {
                    ++currentRange;
                    if (LOG.isDebugEnabled())
                    {
                        LOG.debug(String.Format("Read slow-path, >1 cross block reads with {0}", this.ToString()));
                    }
                    DiskRange range = bytes[i];
                    compressed = range.getData().duplicate();
                    if (compressed.remaining() >= len)
                    {
                        slice = compressed.slice();
                        slice.limit(len);
                        copy.put(slice);
                        currentOffset += len;
                        compressed.position(compressed.position() + len);
                        return(copy);
                    }
                    currentOffset += compressed.remaining();
                    len           -= compressed.remaining();
                    copy.put(compressed);
                }

                // restore offsets for exception clarity
                seek(oldOffset);
                throw new IOException("EOF in " + this + " while trying to read " +
                                      chunkLength + " bytes");
            }