001package com.hfg.sql.table; 002 003import java.sql.ResultSet; 004import java.sql.SQLException; 005import java.util.List; 006 007import com.hfg.xml.XMLTag; 008 009//------------------------------------------------------------------------------ 010/** 011 Database row object which has an Integer as the primary key. 012 <div> 013 @author J. Alex Taylor, hairyfatguy.com 014 </div> 015 */ 016//------------------------------------------------------------------------------ 017// com.hfg XML/HTML Coding Library 018// 019// This library is free software; you can redistribute it and/or 020// modify it under the terms of the GNU Lesser General Public 021// License as published by the Free Software Foundation; either 022// version 2.1 of the License, or (at your option) any later version. 023// 024// This library is distributed in the hope that it will be useful, 025// but WITHOUT ANY WARRANTY; without even the implied warranty of 026// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 027// Lesser General Public License for more details. 028// 029// You should have received a copy of the GNU Lesser General Public 030// License along with this library; if not, write to the Free Software 031// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 032// 033// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 034// jataylor@hairyfatguy.com 035//------------------------------------------------------------------------------ 036 037public abstract class DatabaseRowWithIntPrimaryKey extends DatabaseRow 038{ 039 040 // Cached value 041 private Integer mRowId; 042 043 //########################################################################### 044 // CONSTRUCTORS 045 //########################################################################### 046 047 //--------------------------------------------------------------------------- 048 public DatabaseRowWithIntPrimaryKey(DatabaseTable<? extends DatabaseRow> inTable) 049 { 050 super(inTable); 051 } 052 053 //--------------------------------------------------------------------------- 054 public DatabaseRowWithIntPrimaryKey(DatabaseTable<? extends DatabaseRow> inTable, ResultSet inResultSet) 055 { 056 super(inTable, inResultSet); 057 } 058 059 //--------------------------------------------------------------------------- 060 public DatabaseRowWithIntPrimaryKey(XMLTag inXMLTag) 061 { 062 super(inXMLTag); 063 } 064 065 066 //########################################################################### 067 // PUBLIC METHODS 068 //########################################################################### 069 070 //--------------------------------------------------------------------------- 071 public Integer getId() 072 { 073 if (null == mRowId) 074 { 075 mRowId = (Integer) getField(getIdCol()).getValue(); 076 } 077 078 return mRowId; 079 } 080 081 //--------------------------------------------------------------------------- 082 @SuppressWarnings("unchecked") 083 public void clearId() 084 { 085 getField(getIdCol()).setValue(null); 086 mRowId = null; 087 } 088 089 //--------------------------------------------------------------------------- 090 /** 091 Searches a List of DatabaseRowWithLongPrimaryKey objects sorted in ascending order 092 to find the matching row with the specified id. Slower than a HashMap approach 093 but more memory efficient. More performant when used with ArrayLists than with LinkedLists. 094 * @param inList the sorted List to be searched 095 * @param inTargetRowId the row id to be searched for 096 * @return the index of the row with the matching rowId or -1 if it is not present in the list 097 */ 098 public static int interpolationSearch(List<? extends DatabaseRowWithIntPrimaryKey> inList, 099 Integer inTargetRowId) 100 { 101 int listSize = inList.size(); 102 int leftIdx = 0; 103 int rightIdx = inList.size() - 1; 104 105 DatabaseRowWithIntPrimaryKey leftRow = inList.get(leftIdx); 106 DatabaseRowWithIntPrimaryKey rightRow = inList.get(rightIdx); 107 108 while (leftIdx < rightIdx) 109 { 110 // Guess where to check next 111 int nextIdx = leftIdx + ((inTargetRowId - leftRow.getId()) * (rightIdx - leftIdx) / 112 (rightRow.getId() - leftRow.getId())); 113 114 if (nextIdx < 0) 115 { 116 nextIdx = 0; 117 } 118 else if (nextIdx >= listSize) 119 { 120 nextIdx = listSize - 1; 121 } 122 123 int comparison = inTargetRowId - inList.get(nextIdx).getId(); 124 if (0 == comparison) 125 { 126 return nextIdx; 127 } 128 else if (comparison < 0) 129 { 130 if (nextIdx <= 0 131 || rightIdx <= nextIdx - 1) 132 { 133 break; // Or we'll end up in an infinite loop 134 } 135 136 rightIdx = nextIdx - 1; 137 rightRow = inList.get(rightIdx); 138 } 139 else 140 { 141 if (nextIdx == listSize - 1 142 || leftIdx >= nextIdx + 1) 143 { 144 break; // Or we'll end up in an infinite loop 145 } 146 147 leftIdx = nextIdx + 1; 148 leftRow = inList.get(leftIdx); 149 } 150 } 151 152 return (inTargetRowId.equals(leftRow.getId()) ? leftIdx : -1); 153 } 154 155}