com.sleepycat.je.rep.vlsn
Class GhostBucket
java.lang.Object
com.sleepycat.je.rep.vlsn.VLSNBucket
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.
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 |
GhostBucket
GhostBucket(VLSN ghostVLSN,
long firstPossibleLsn,
long lastPossibleLsn)
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,
inclusiveprevLsn
- 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-2012 Oracle. All rights reserved.