summaryrefslogtreecommitdiff
path: root/cpp/src/Freeze/EvictorIteratorI.cpp
diff options
context:
space:
mode:
authorBernard Normier <bernard@zeroc.com>2003-10-21 20:40:01 +0000
committerBernard Normier <bernard@zeroc.com>2003-10-21 20:40:01 +0000
commit2cb10f33a1cc8d3d94450fa45cc8f63ba32c137f (patch)
treeee83ca7fa800f497d1e7f340c5d1737545235870 /cpp/src/Freeze/EvictorIteratorI.cpp
parentFixed code generation bug. (diff)
downloadice-2cb10f33a1cc8d3d94450fa45cc8f63ba32c137f.tar.bz2
ice-2cb10f33a1cc8d3d94450fa45cc8f63ba32c137f.tar.xz
ice-2cb10f33a1cc8d3d94450fa45cc8f63ba32c137f.zip
Added Freeze evictor indices
Diffstat (limited to 'cpp/src/Freeze/EvictorIteratorI.cpp')
-rw-r--r--cpp/src/Freeze/EvictorIteratorI.cpp231
1 files changed, 231 insertions, 0 deletions
diff --git a/cpp/src/Freeze/EvictorIteratorI.cpp b/cpp/src/Freeze/EvictorIteratorI.cpp
new file mode 100644
index 00000000000..2d348e63b86
--- /dev/null
+++ b/cpp/src/Freeze/EvictorIteratorI.cpp
@@ -0,0 +1,231 @@
+// **********************************************************************
+//
+// Copyright (c) 2003
+// ZeroC, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved.
+//
+// Ice is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation.
+//
+// **********************************************************************
+
+#include <Freeze/EvictorIteratorI.h>
+#include <Freeze/EvictorI.h>
+#include <Freeze/Util.h>
+
+using namespace std;
+using namespace Freeze;
+using namespace Ice;
+
+
+Freeze::EvictorIteratorI::EvictorIteratorI(EvictorI& evictor, Int batchSize, bool loadServants) :
+ _evictor(evictor),
+ _batchSize(static_cast<size_t>(batchSize)),
+ _loadServants(loadServants),
+ _key(1024),
+ _more(true)
+{
+ if(loadServants)
+ {
+ _value.resize(1024);
+ }
+ _batchIterator = _batch.end();
+}
+
+
+bool
+Freeze::EvictorIteratorI::hasNext()
+{
+ if(_batchIterator != _batch.end())
+ {
+ return true;
+ }
+ else
+ {
+ _batchIterator = nextBatch();
+ return (_batchIterator != _batch.end());
+ }
+}
+
+Identity
+Freeze::EvictorIteratorI::next()
+{
+ if(hasNext())
+ {
+ return *_batchIterator++;
+ }
+ else
+ {
+ throw Freeze::NoSuchElementException(__FILE__, __LINE__);
+ }
+}
+
+
+vector<Identity>::const_iterator
+Freeze::EvictorIteratorI::nextBatch()
+{
+ _batch.clear();
+
+ if(!_more)
+ {
+ return _batch.end();
+ }
+
+ vector<EvictorI::EvictorElementPtr> evictorElements;
+ evictorElements.reserve(_batchSize);
+
+ Key firstKey;
+ firstKey = _key;
+
+ int loadedGeneration = 0;
+
+ try
+ {
+ for(;;)
+ {
+ _batch.clear();
+ evictorElements.clear();
+
+ Dbt dbKey;
+ initializeOutDbt(_key, dbKey);
+
+ Dbt dbValue;
+ if(_loadServants)
+ {
+ initializeOutDbt(_value, dbValue);
+ }
+ else
+ {
+ dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);
+ }
+
+ Dbc* dbc = 0;
+ try
+ {
+ //
+ // Move to the first record
+ //
+ u_int32_t flags = DB_NEXT;
+ if(_key.size() > 0)
+ {
+ //
+ // _key represents the next element not yet returned
+ // if it has been deleted, we want the one after
+ //
+ flags = DB_SET_RANGE;
+
+ //
+ // Will be used as input as well
+ //
+ dbKey.set_size(firstKey.size());
+ }
+
+ if(_loadServants)
+ {
+ loadedGeneration = _evictor.currentGeneration();
+ }
+
+ _evictor.db()->cursor(0, &dbc, 0);
+
+ for(;;)
+ {
+ try
+ {
+ _more = (dbc->get(&dbKey, &dbValue, flags) == 0);
+ if(_more)
+ {
+ _key.resize(dbKey.get_size());
+ //
+ // No need to resize data as we never use it as input
+ //
+ }
+ break;
+ }
+ catch(const DbMemoryException& dx)
+ {
+ handleMemoryException(dx, _key, dbKey, _value, dbValue);
+ }
+ }
+
+ while(_batch.size() < _batchSize && _more)
+ {
+ //
+ // Even when count is 0, we read one more record (unless we reach the end)
+ //
+ if(_loadServants)
+ {
+ _more = _evictor.load(dbc, _key, _value, _batch, evictorElements);
+ }
+ else
+ {
+ _more = _evictor.load(dbc, _key, _batch);
+ }
+ }
+
+ Dbc* toClose = dbc;
+ dbc = 0;
+ toClose->close();
+ break; // for (;;)
+ }
+ catch(const DbDeadlockException&)
+ {
+ if(dbc != 0)
+ {
+ try
+ {
+ dbc->close();
+ }
+ catch(const DbDeadlockException&)
+ {
+ //
+ // Ignored
+ //
+ }
+ }
+ _key = firstKey;
+ //
+ // Retry
+ //
+ }
+ catch(...)
+ {
+ if(dbc != 0)
+ {
+ try
+ {
+ dbc->close();
+ }
+ catch(const DbDeadlockException&)
+ {
+ //
+ // Ignored
+ //
+ }
+ }
+ throw;
+ }
+ }
+ }
+ catch(const DbException& dx)
+ {
+ DatabaseException ex(__FILE__, __LINE__);
+ ex.message = dx.what();
+ throw ex;
+ }
+
+ if(_batch.size() == 0)
+ {
+ return _batch.end();
+ }
+ else
+ {
+ if(_loadServants)
+ {
+ _evictor.insert(_batch, evictorElements, loadedGeneration);
+ }
+ return _batch.begin();
+ }
+}