00001 /*00002 * The Software License00003 * =================================================================================00004 * Copyright (c) 2003-.The Terimber Corporation. All rights reserved.00005 * =================================================================================00006 * Redistributions of source code must retain the above copyright notice, 00007 * this list of conditions and the following disclaimer.00008 * Redistributions in binary form must reproduce the above copyright notice, 00009 * this list of conditions and the following disclaimer in the documentation 00010 * and/or other materials provided with the distribution.00011 * The end-user documentation included with the redistribution, if any, 00012 * must include the following acknowledgment:00013 * "This product includes software developed by the Terimber Corporation."00014 * =================================================================================00015 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, 00016 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 00017 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00018 * IN NO EVENT SHALL THE TERIMBER CORPORATION OR ITS CONTRIBUTORS BE LIABLE FOR 00019 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00020 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00021 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00022 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT00023 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE00024 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.00025 * ================================================================================00026 */00027
00028 #include "memdb/memdb.hpp"00029 #include "base/list.hpp"00030 #include "base/map.hpp"00031 #include "base/vector.hpp"00032 #include "base/memory.hpp"00033
00034 BEGIN_TERIMBER_NAMESPACE00035 #pragma pack(4)00036
00038memindex::memindex(memtable& parent, constmemdb_rowset_less& pred) :
00039 _parent(parent),
00040 _index(pred)
00041 {
00042 }
00043
00044memindex::~memindex()
00045 {
00046 mutex_keeper guard(_mtx);
00047 for (list_lookups_t::iterator iter = _lookups.begin(); iter != _lookups.end(); ++iter)
00048 delete *iter;
00049
00050 _lookups.clear();
00051 }
00052
00053 bool00054memindex::construct()
00055 {
00056 // looks up thought the rowset and constructs index00057 for (memdb_rowset_citerator_t iter = _parent.get_rowset().begin(); iter != _parent.get_rowset().end(); ++iter)
00058 _index.insert(iter, iter);
00059
00060 returntrue;
00061 }
00062
00063 terimber_memlookup*
00064memindex::add_lookup(constterimber_db_value_vector* info)
00065 {
00066 memlookup* obj = newmemlookup(*this);
00067
00068 if (obj)
00069 {
00070 if (!obj->construct(static_cast< const terimber_db_value_vector_impl* >(info)))
00071 {
00072 delete obj;
00073 return 0;
00074 }
00075
00076 // adds to the list of indexes00077 mutex_keeper guard(_mtx);
00078 _lookups.push_back(obj);
00079 }
00080
00081 obj->log_on(this);
00082 return obj;
00083 }
00084
00085 //00086 // destroys lookup after using00087 //00088 bool00089memindex::remove_lookup(terimber_memlookup* obj)
00090 {
00091 mutex_keeper guard(_mtx);
00092 for (list_lookups_t::iterator iter = _lookups.begin(); iter != _lookups.end(); ++iter)
00093 if (*iter == obj)
00094 {
00095 (*iter)->log_on(0);
00096 delete *iter;
00097 _lookups.erase(iter);
00098 returntrue;
00099 }
00100
00101 returnfalse;
00102 }
00103
00104 //00105 // parent table send notification00106 //00107 void00108memindex::notify(memdb_rowset_citerator_t iter, bool insert_or_delete)
00109 {
00110 if (insert_or_delete)
00111 {
00112 // notifies all lookups00113 memdb_index_citer_t index_iter = _index.insert(iter, iter).first;
00114 mutex_keeper guard(_mtx);
00115 for (list_lookups_t::iterator liter = _lookups.begin(); liter != _lookups.end(); ++liter)
00116 (*liter)->notify(index_iter, true);
00117 }
00118 else00119 {
00120 // notify all lookups00121 memdb_index_t::pairii_t range = _index.equal_range(iter);
00122 if (range.first != _index.end())
00123 {
00124 while (range.first != range.second)
00125 {
00126 if (range.first.key() == iter)
00127 {
00128 mutex_keeper guard(_mtx);
00129 for (list_lookups_t::iterator liter = _lookups.begin(); liter != _lookups.end(); ++liter)
00130 (*liter)->notify(range.first, false);
00131
00132 // erases00133 _index.erase(range.first);
00134 break;
00135 }
00136 else00137 ++range.first;
00138 }
00139 }
00140 }
00141 }
00142
00143 #pragma pack()00144 END_TERIMBER_NAMESPACE