com.sleepycat.je.rep.vlsn
Class GhostBucket

java.lang.Object
  extended by com.sleepycat.je.rep.vlsn.VLSNBucket
      extended by com.sleepycat.je.rep.vlsn.GhostBucket

 class GhostBucket
extends VLSNBucket

A ghost bucket stands in as a placeholder for a set of vlsns that are unknown. This kind of bucket can only be present at the very beginning of the vlsn range. This fulfills an edge case that can arise when vlsns are inserted out of order, and log cleaner truncation lops off the leading edge of the index. For example, suppose vlsns were inserted in this order: vlsnIndex.put(vlsn=2, lsn=1/2) vlsnIndex.put(vlsn=1, lsn=1/0) vlsnIndex.put(vlsn=3, lsn=1/3) ... vlsnIndex.put(vlsn=5, lsn=2/9) vlsnIndex.put(vlsn=4, lsn=2/0) vlsnIndex.put(vlsn=6, lsn=2/10) .. This results in an index that has two buckets. Bucket 1 = {vlsn 2,3} and bucket 2 = {vlsn 5,6}. If we log clean file 1, we will truncate log at vlsn 3, and the new range will be vlsn 4-> vlsn 6. But the beginning and end of each range needs to have a valid bucket, and there is no bucket to represent vlsn 4. A GhostBucket is added to the head of the bucket set.


Field Summary
 
Fields inherited from class com.sleepycat.je.rep.vlsn.VLSNBucket
dirty, firstVLSN, lastVLSN
 
Constructor Summary
GhostBucket(VLSN ghostVLSN, long firstPossibleLsn, long lastPossibleLsn)
           
 
Method Summary
(package private)  long getGTELsn(VLSN vlsn)
          Return a lsn as a starting point for a backward scan.
 long getLsn(VLSN vlsn)
          There is no mapping for this VLSN, so always return NULL_LSN.
(package private)  long getLTEFileNumber()
          Return a file number that is less or equal to the first mapped vlsn, for use in determining the CBVLSN.
(package private)  long getLTELsn(VLSN vlsn)
          Return a lsn as a starting point for a forward scan.
(package private)  int getNumOffsets()
           
(package private)  boolean isGhost()
           
(package private) static GhostBucket makeNewInstance(TupleInput ti)
          Ideally, this would be a constructor, but we have to read several items off the tuple input first before calling super();
(package private)  boolean put(VLSN vlsn, long lsn)
          Record the LSN location for this VLSN.
(package private)  VLSNBucket removeFromHead(EnvironmentImpl envImpl, VLSN lastDuplicate)
          Remove the mappings from this bucket that are for VLSNs <= lastDuplicate.
(package private)  void removeFromTail(VLSN startOfDelete, long prevLsn)
          Remove the mappings from this bucket that are for VLSNs >= startOfDelete.
 String toString()
           
(package private)  void writeToTupleOutput(TupleOutput to)
           
 
Methods inherited from class com.sleepycat.je.rep.vlsn.VLSNBucket
close, dump, empty, fillDataEntry, follows, getFirst, getLast, getLastLsn, owns, precedes, readFromDatabase, writeToDatabase, writeToDatabase
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

GhostBucket

GhostBucket(VLSN ghostVLSN,
            long firstPossibleLsn,
            long lastPossibleLsn)
Method Detail

makeNewInstance

static GhostBucket makeNewInstance(TupleInput ti)
Ideally, this would be a constructor, but we have to read several items off the tuple input first before calling super();


isGhost

boolean isGhost()
Overrides:
isGhost in class VLSNBucket

writeToTupleOutput

void writeToTupleOutput(TupleOutput to)
Overrides:
writeToTupleOutput in class VLSNBucket

getGTELsn

long getGTELsn(VLSN vlsn)
Return a lsn as a starting point for a backward scan.

Overrides:
getGTELsn in class VLSNBucket
Returns:
the mapping whose VLSN is >= the VLSN parameter. Will never return NULL_LSN, because the VLSNRange begin and end point are always mapped.

getLTELsn

long getLTELsn(VLSN vlsn)
Return a lsn as a starting point for a forward scan.

Overrides:
getLTELsn in class VLSNBucket
Returns:
the lsn whose VLSN is <= the VLSN parameter. Will never return NULL_LSN, because the VLSNRange begin and end points are always mapped.

getLsn

public long getLsn(VLSN vlsn)
There is no mapping for this VLSN, so always return NULL_LSN.

Overrides:
getLsn in class VLSNBucket
Returns:
the lsn whose VLSN is == the VLSN parameter or DbLsn.NULL_LSN if there is no mapping. Note that because of out of order puts, there may be missing mappings that appear later on.

getLTEFileNumber

long getLTEFileNumber()
Return a file number that is less or equal to the first mapped vlsn, for use in determining the CBVLSN.

Overrides:
getLTEFileNumber in class VLSNBucket
Returns:

put

boolean put(VLSN vlsn,
            long lsn)
Description copied from class: VLSNBucket
Record the LSN location for this VLSN. One key issue is that puts() are not synchronized, and the VLSNs may arrive out of order. If an out of order VLSN does arrive, we can still assume that the earlier VLSNs have been successfully logged. If a VLSN arrives that is divisible by the stride, and should be recorded in the fileOffsets, but is not the next VLSN that should be recorded, we'll pad out the fileOffsets list with placeholders. For example, suppose the stride is 3, and the first VLSN is 2. Then this bucket should record VLSN 2, 5, 8, ... etc. If VLSN 8 arrives before VLSN 5, VLSN 8 will be recorded, and VLSN 5 will have an offset placeholder of NO_OFFSET. It is a non-issue if VLSNs 3, 4, 6, 7 arrive out of order, because they would not have been recorded anyway. This should not happen often, because the stride should be fairly large, and the calls to put() should be close together. If the insertion order is vlsn 2, 5, 9, then the file offsets array will be a little short, and will only have 2 elements, instead of 3. We follow this policy because we must always have a valid begin and end point for the range. We must handle placeholders in all cases, and can't count of later vlsn inserts, because a bucket can become immutable at any time if it is flushed to disk.

Overrides:
put in class VLSNBucket
Returns:
false if this bucket will not accept this VLSN. Generally, a refusal might happen because the bucket was full or the mapping is too large a distance away from the previous mapping. In that case, the tracker will start another bucket.

removeFromHead

VLSNBucket removeFromHead(EnvironmentImpl envImpl,
                          VLSN lastDuplicate)
Description copied from class: VLSNBucket
Remove the mappings from this bucket that are for VLSNs <= lastDuplicate. If this results in a broken stride interval, package all those mappings into their own bucket and return it as a remainder bucket. For example, suppose this bucket has a stride of 5 and maps VLSN 10-23. Then it has mappings for 10, 15, 20, 23. If we need to remove mappings <= 16, we'll end up without a bucket that serves as a home base for vlsns 17,18,19. Those will be spun out into their own bucket, and this bucket will be adjusted to start at VLSN 20. This bucket should end up with - firstVLSN = 20 - fileOffset is an array of size 1, for the LSN for VLSN 20 - lastVLSN = 23 - lastLsn = the same as before The spun-off bucket should be: - firstVLSN = 17 - fileOffset is an array of size 1, for the LSN for VLSN 17 - lastVLSN = 19 - lastLsn = lsn for 19

Overrides:
removeFromHead in class VLSNBucket
Returns:
the newly created bucket that holds mappings from a broken stride interval, or null if there was no need to create such a bucket.

removeFromTail

void removeFromTail(VLSN startOfDelete,
                    long prevLsn)
Description copied from class: VLSNBucket
Remove the mappings from this bucket that are for VLSNs >= startOfDelete. Unlike removing from the head, we need not worry about breaking a bucket stride interval. If prevLsn is NULL_VLSN, we don't have a good value to cap the bucket. Instead, we'll have to delete the bucket back to whatever was the next available lsn. For example, suppose the bucket has these mappings. This strange bucket (stride 25 is missing) is possible if vlsn 26 arrived early, out of order. in fileOffset: 10 -> 101 in fileOffset: 15 -> no offset in fileOffset: 20 -> 201 lastVLSN->lastnLsn mapping 26 -> 250 If we have a prevLsn and the startOfDelete is 17, then we can create a new mapping in fileOffset: 10 -> 101 in fileOffset: 15 -> no offset lastVLSN->lastnLsn mapping 17 -> 190 If we don't have a prevLsn, then we know that we have to cut the bucket back to the largest known mapping, losing many mappings along the way. in fileOffset: 10 -> 101 lastVLSN->lastnLsn mapping 10 -> 101 If we are deleting in the vlsn area between the last stride and the last offset, (i.e. vlsn 23 is the startOfDelete) the with and without prevLSn cases would look like this: (there is a prevLsn, and 23 is startDelete. No need to truncate anything) in fileOffset: 10 -> 101 in fileOffset: 15 -> no offset in fileOffset: 20 -> 201 lastVLSN->lastnLsn mapping 23 -> prevLsn (there is no prevLsn, and 23 is startDelete) in fileOffset: 10 -> 101 in fileOffset: 15 -> no offset in fileOffset: 20 -> 201 lastVLSN->lastnLsn mapping 20 -> 201

Overrides:
removeFromTail in class VLSNBucket
Parameters:
startOfDelete - is the VLSN that begins the range to delete, inclusive
prevLsn - is the lsn of startOfDelete.getPrev(). We'll be using it to cap off the end of the bucket, by assigning it to the lastLsn field.

getNumOffsets

int getNumOffsets()
Overrides:
getNumOffsets in class VLSNBucket

toString

public String toString()
Overrides:
toString in class VLSNBucket
See Also:
Object.toString()


Copyright (c) 2004-2010 Oracle. All rights reserved.