Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (C) 2011 the original author or authors. See the notice.md file distributed with this work for additional information regarding copyright ownership. Licensed 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.iq80.leveldb.table;
 
 
 
 import static org.iq80.leveldb.util.SizeOf.SIZE_OF_INT;
 
 public class BlockIterator implements SeekingIterator<SliceSlice>
 {
     private final SliceInput data;
     private final Slice restartPositions;
     private final int restartCount;
     private final Comparator<Slicecomparator;
 
     private BlockEntry nextEntry;
 
     public BlockIterator(Slice dataSlice restartPositionsComparator<Slicecomparator)
     {
         Preconditions.checkNotNull(data"data is null");
         Preconditions.checkNotNull(restartPositions"restartPositions is null");
         Preconditions.checkArgument(restartPositions.length() %  == 0, "restartPositions.readableBytes() must be a multiple of %s");
         Preconditions.checkNotNull(comparator"comparator is null");
 
         this. = data.input();
 
         this. = restartPositions.slice();
          = this..length() / ;
 
         this. = comparator;
 
         seekToFirst();
     }
 
     @Override
     public boolean hasNext()
     {
         return  != null;
     }
 
     @Override
     public BlockEntry peek()
     {
         if (!hasNext()) {
             throw new NoSuchElementException();
         }
         return ;
     }
 
     @Override
     public BlockEntry next()
     {
         if (!hasNext()) {
             throw new NoSuchElementException();
         }
 
         BlockEntry entry = ;
 
         if (!.isReadable()) {
              = null;
         }
         else {
             // read entry at current data position
              = readEntry();
         }
 
         return entry;
     }
 
     @Override
     public void remove()
     {
         throw new UnsupportedOperationException();
     }

    
Repositions the iterator so the beginning of this block.
    @Override
    public void seekToFirst()
    {
        if ( > 0) {
            seekToRestartPosition(0);
        }
    }

    
Repositions the iterator so the key of the next BlockElement returned greater than or equal to the specified targetKey.
    @Override
    public void seek(Slice targetKey)
    {
        if ( == 0) {
            return;
        }
        int left = 0;
        int right =  - 1;
        // binary search restart positions to find the restart position immediately before the targetKey
        while (left < right) {
            int mid = (left + right + 1) / 2;
            seekToRestartPosition(mid);
            if (.compare(.getKey(), targetKey) < 0) {
                // key at mid is smaller than targetKey.  Therefore all restart
                // blocks before mid are uninteresting.
                left = mid;
            }
            else {
                // key at mid is greater than or equal to targetKey.  Therefore
                // all restart blocks at or after mid are uninteresting.
                right = mid - 1;
            }
        }
        // linear search (within restart block) for first key greater than or equal to targetKey
        for (seekToRestartPosition(left);  != nullnext()) {
            if (.compare(peek().getKey(), targetKey) >= 0) {
                break;
            }
        }
    }

    
Seeks to and reads the entry at the specified restart position.

After this method, nextEntry will contain the next entry to return, and the previousEntry will be null.

    private void seekToRestartPosition(int restartPosition)
    {
        Preconditions.checkPositionIndex(restartPosition"restartPosition");
        // seek data readIndex to the beginning of the restart block
        int offset = .getInt(restartPosition * );
        .setPosition(offset);
        // clear the entries to assure key is not prefixed
         = null;
        // read the entry
         = readEntry(null);
    }

    
Reads the entry at the current data readIndex. After this method, data readIndex is positioned at the beginning of the next entry or at the end of data if there was not a next entry.

Returns:
true if an entry was read
    private static BlockEntry readEntry(SliceInput dataBlockEntry previousEntry)
    {
        Preconditions.checkNotNull(data"data is null");
        // read entry header
        int sharedKeyLength = VariableLengthQuantity.readVariableLengthInt(data);
        int nonSharedKeyLength = VariableLengthQuantity.readVariableLengthInt(data);
        int valueLength = VariableLengthQuantity.readVariableLengthInt(data);
        // read key
        Slice key = Slices.allocate(sharedKeyLength + nonSharedKeyLength);
        SliceOutput sliceOutput = key.output();
        if (sharedKeyLength > 0) {
            Preconditions.checkState(previousEntry != null"Entry has a shared key but no previous entry was provided");
            sliceOutput.writeBytes(previousEntry.getKey(), 0, sharedKeyLength);
        }
        sliceOutput.writeBytes(datanonSharedKeyLength);
        // read value
        Slice value = data.readSlice(valueLength);
        return new BlockEntry(keyvalue);
    }
New to GrepCode? Check out our FAQ X