/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package com.github.geophile.erdo.map.emptymap;
import com.github.geophile.erdo.AbstractKey;
import com.github.geophile.erdo.map.Factory;
import com.github.geophile.erdo.map.MapCursor;
import com.github.geophile.erdo.map.SealedMap;
import com.github.geophile.erdo.map.SealedMapBase;
import com.github.geophile.erdo.transaction.TimestampSet;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
// Used to eagerly consolidate empty maps in ConsolidationElementTracker, following read transactions.
// CET owns one EmptyMap, and as empty maps (resulting from read transactions) are added, the TimestampSet is
// updated. This greatly reduces the time needed to consolidate empty maps.
public class EmptyMap extends SealedMapBase
{
// Consolidation.Element interface
@Override
public boolean durable()
{
return false;
}
// OpenOrSealedMapBase interface
@Override
public MapCursor cursor(AbstractKey startKey, boolean singleKey)
throws IOException, InterruptedException
{
return new EmptyMapCursor();
}
@Override
public MapCursor keyScan(AbstractKey startKey, boolean singleKey)
throws IOException, InterruptedException
{
return new EmptyMapCursor();
}
@Override
public long recordCount()
{
return 0;
}
@Override
public long estimatedSizeBytes()
{
return 0;
}
@Override
public void loadForConsolidation(MapCursor recordScan, MapCursor keyScan)
throws UnsupportedOperationException, IOException, InterruptedException
{
assert false;
}
@Override
public boolean keysInMemory()
{
return true;
}
@Override
public TimestampSet timestamps()
{
if (timestamps != null) {
timestampSets.add(timestamps);
}
timestamps = TimestampSet.consolidate(timestampSets);
timestampSets.clear();
return timestamps;
}
// EmptyMap interface
public void addEmpty(SealedMap map)
{
assert map.recordCount() == 0;
timestampSets.add(map.timestamps());
}
public void removeEmpty(SealedMap map)
{
assert map.recordCount() == 0;
// timestamps() consolidates timestamps and timestampSets.
timestamps = timestamps().minus(map.timestamps());
}
// ConsolidationElementTracker owns an EmptyMap whose timestamps are updated (via addEmpty and removeEmpty).
// When that EmptyMap is handed out (outside of the ConsolidationSet), the recipient must have a static view
// of the EmptyMap. (Everything else handed out is already completely unchanging.) So a copy of the EmptyMap
// is created. The copy must have its own TimestampSet.
public EmptyMap copy()
{
EmptyMap copy = new EmptyMap(factory);
copy.timestamps = timestamps().copy(); // Not timestamps.copy(). Need to consolidate before copying.
return copy;
}
public EmptyMap(Factory factory)
{
super(factory);
}
// Object state
private final List<TimestampSet> timestampSets = new ArrayList<TimestampSet>();
}