From: Wolfgang M. M. <wol...@us...> - 2004-07-05 20:02:56
|
Update of /cvsroot/exist/eXist-1.0/src/org/exist/storage/store In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25405/src/org/exist/storage/store Modified Files: DOMFile.java NodeIterator.java Log Message: Fixed concurrency issue in the dom.dbx node store: in some cases, a reading thread could interfere with a writing thread. As a result, some data pages got lost. Index: DOMFile.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/storage/store/DOMFile.java,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** DOMFile.java 30 Jun 2004 15:57:16 -0000 1.36 --- DOMFile.java 5 Jul 2004 20:02:47 -0000 1.37 *************** *** 27,32 **** --- 27,35 ---- import java.io.UnsupportedEncodingException; import java.util.ArrayList; + import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; + import java.util.Map; + import java.util.TreeMap; import org.dbxml.core.DBException; *************** *** 49,52 **** --- 52,56 ---- import org.exist.storage.cache.ClockCache; import org.exist.util.ByteConversion; + import org.exist.util.FastQSort; import org.exist.util.Lock; import org.exist.util.LockException; *************** *** 206,209 **** --- 210,214 ---- throws ReadOnlyException { final int valueLen = value.length; + final Object myOwner = owner; // always append data to the end of the file DOMPage page = getCurrentPage(); *************** *** 218,227 **** --- 223,238 ---- dataCache.add(page); } + // LOG.debug("created new page: " + newPage.getPageNum() + "; prev = " + page.getPageNum() + + // "; oldLen = " + page.len + "; valueLen = " + valueLen); page = newPage; setCurrentPage(newPage); + if(owner != myOwner) + LOG.error("Owner changed during transaction!!!!!!!!!!!!!!!!!"); } // save tuple identifier final DOMFilePageHeader ph = page.getPageHeader(); final short tid = ph.getNextTID(); + // LOG.debug("writing to " + page.getPageNum() + "; " + page.len + "; tid = " + tid + + // "; len = " + valueLen + "; dataLen = " + page.data.length); ByteConversion.shortToByte(tid, page.data, page.len); page.len += 2; *************** *** 392,397 **** // write the data short tid = rec.page.getPageHeader().getNextTID(); ! // LOG.debug("inserting " + new String(value) + " to " + rec.page.page.getPageInfo() + "; " + ! // tid); ByteConversion.shortToByte((short) tid, rec.page.data, rec.offset); rec.offset += 2; --- 403,407 ---- // write the data short tid = rec.page.getPageHeader().getNextTID(); ! // LOG.debug("inserting " + new String(value) + " to " + rec.page.page.getPageInfo() + "; " + tid); ByteConversion.shortToByte((short) tid, rec.page.data, rec.offset); rec.offset += 2; *************** *** 449,455 **** long backLink; short splitRecordCount = 0; ! // LOG.debug("splitting " + rec.page.getPageNum() + ": new: " ! // + nextSplitPage.getPageNum() + "; next: " + ! // rec.page.getPageHeader().getNextDataPage()); for (int pos = rec.offset; pos < oldDataLen; splitRecordCount++) { // read the current id --- 459,465 ---- long backLink; short splitRecordCount = 0; ! LOG.debug("splitting " + rec.page.getPageNum() + ": new: " ! + nextSplitPage.getPageNum() + "; next: " + ! rec.page.getPageHeader().getNextDataPage()); for (int pos = rec.offset; pos < oldDataLen; splitRecordCount++) { // read the current id *************** *** 627,632 **** } ! private void printPageContents(DOMPage page) { ! System.out.print("Page " + page.getPageNum() + ": "); short count = 0; short currentId, vlen; --- 637,643 ---- } ! public String debugPageContents(DOMPage page) { ! StringBuffer buf = new StringBuffer(); ! buf.append("Page " + page.getPageNum() + ": "); short count = 0; short currentId, vlen; *************** *** 634,638 **** for (int pos = 0; pos < dlen; count++) { currentId = ByteConversion.byteToShort(page.data, pos); ! System.out.print(currentId + " "); if (ItemId.isLink(currentId)) { pos += 10; --- 645,649 ---- for (int pos = 0; pos < dlen; count++) { currentId = ByteConversion.byteToShort(page.data, pos); ! buf.append(currentId + " "); if (ItemId.isLink(currentId)) { pos += 10; *************** *** 645,650 **** } } ! System.out.println(); ! LOG.debug("page " + page.getPageNum() + " has " + count + " records."); } --- 656,661 ---- } } ! buf.append("; records in page: " + count); ! return buf.toString(); } *************** *** 824,828 **** super.flush(); dataCache.flush(); ! pages.remove(owner); try { if (fileHeader.isDirty()) fileHeader.write(); --- 835,840 ---- super.flush(); dataCache.flush(); ! // pages.remove(owner); ! closeDocument(); try { if (fileHeader.isDirty()) fileHeader.write(); *************** *** 836,840 **** super.flush(); dataCache.flush(); ! pages.remove(owner); try { if (fileHeader.isDirty()) fileHeader.write(); --- 848,853 ---- super.flush(); dataCache.flush(); ! // pages.remove(owner); ! closeDocument(); try { if (fileHeader.isDirty()) fileHeader.write(); *************** *** 957,960 **** --- 970,975 ---- final DOMPage page = new DOMPage(); pages.put(owner, page.page.getPageNum()); + LOG.debug("new page created: " + page.page.getPageNum() + " by " + owner + + "; thread: " + Thread.currentThread().getName()); dataCache.add(page); return page; *************** *** 980,983 **** --- 995,1000 ---- public void closeDocument() { pages.remove(owner); + // LOG.debug("current doc closed by: " + owner + + // "; thread: " + Thread.currentThread().getName()); } *************** *** 1105,1108 **** --- 1122,1126 ---- rec.page.setDirty(true); ph.decRecordCount(); + // LOG.debug(debugPageContents(rec.page)); if (rec.page.len == 0) { // LOG.debug("removing page " + rec.page.getPageNum()); *************** *** 1168,1177 **** --- 1186,1205 ---- public void removeAll(long p) { + // StringBuffer debug = new StringBuffer(); + // debug.append("Removed pages: "); long pnum = StorageAddress.pageFromPointer(p); while(-1 < pnum) { + // debug.append(' ').append(pnum); DOMPage page = getCurrentPage(pnum); pnum = page.getPageHeader().getNextDataPage(); dataCache.remove(page); try { + DOMFilePageHeader ph = page.getPageHeader(); + ph.setNextDataPage(-1); + ph.setPrevDataPage(-1); + ph.setDataLength(0); + ph.setNextTID((short) -1); + ph.setRecordCount((short) 0); + page.len = 0; unlinkPages(page.page); } catch (IOException e) { *************** *** 1179,1182 **** --- 1207,1224 ---- } } + // LOG.debug(debug.toString()); + } + + public String debugPages(DocumentImpl doc) { + StringBuffer buf = new StringBuffer(); + buf.append("Pages used by ").append(doc.getFileName()); + buf.append(':'); + long pnum = StorageAddress.pageFromPointer(((NodeImpl)doc.getFirstChild()).getInternalAddress()); + while(-1 < pnum) { + DOMPage page = getCurrentPage(pnum); + buf.append(' ').append(pnum); + pnum = page.getPageHeader().getNextDataPage(); + } + return buf.toString(); } *************** *** 1188,1194 **** */ private final void setCurrentPage(DOMPage page) { ! final long pnum = pages.get(owner); if (pnum == page.page.getPageNum()) return; ! //pages.remove(owner); pages.put(owner, page.page.getPageNum()); } --- 1230,1238 ---- */ private final void setCurrentPage(DOMPage page) { ! long pnum = pages.get(owner); if (pnum == page.page.getPageNum()) return; ! // pages.remove(owner); ! // LOG.debug("current page set: " + page.page.getPageNum() + " by " + owner.hashCode() + ! // "; thread: " + Thread.currentThread().getName()); pages.put(owner, page.page.getPageNum()); } *************** *** 1210,1220 **** */ public final void setOwnerObject(Object obj) { owner = obj; } - public final void releaseOwner(Object obj) { - //pages.remove(obj); - } - /** * Update the key/value pair. --- 1254,1262 ---- */ public final void setOwnerObject(Object obj) { + // if(owner != obj && obj != null) + // LOG.debug("owner set -> " + obj.hashCode()); owner = obj; } /** * Update the key/value pair. Index: NodeIterator.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/storage/store/NodeIterator.java,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** NodeIterator.java 16 Jun 2004 09:23:50 -0000 1.11 --- NodeIterator.java 5 Jul 2004 20:02:47 -0000 1.12 *************** *** 121,130 **** if (nextPage < 0) { LOG.debug("bad link to next " + p.page.getPageInfo() + "; previous: " + ! ph.getPrevDataPage()); return null; } - // LOG.debug(page + " -> " + nextPage); page = nextPage; p = db.getCurrentPage(nextPage); db.addToBuffer(p); offset = 0; --- 121,130 ---- if (nextPage < 0) { LOG.debug("bad link to next " + p.page.getPageInfo() + "; previous: " + ! ph.getPrevDataPage() + "; offset = " + offset + "; lastTID = " + lastTID); return null; } page = nextPage; p = db.getCurrentPage(nextPage); + // LOG.debug(" -> " + nextPage + "; len = " + p.len + "; " + p.page.getPageInfo()); db.addToBuffer(p); offset = 0; *************** *** 169,172 **** --- 169,173 ---- p.getPageHeader().getPrevDataPage() + "; offset = " + (offset - l) + "; len = " + p.getPageHeader().getDataLength()); + LOG.debug(db.debugPageContents(p)); return null; } |