Permalink
Browse files

Fixed some concurrency bugs.

  • Loading branch information...
tzaeschke committed Sep 19, 2017
1 parent 3505959 commit 62936f5438d9c6c3a9b869e619cbbdc14036a169
View
@@ -0,0 +1 @@
/.~lock.ZooDB-Server.odg#
@@ -156,6 +156,8 @@ public void commit(boolean retainValues) {
lock();
checkActive();
closeResources();
//pre-commit: traverse object tree for transitive persistence
cache.persistReachableObjects();
@@ -379,6 +381,7 @@ public void rollback() {
}
public void rollbackInteral() {
closeResources();
schemaManager.rollback();
OptimisticTransactionResult otr = new OptimisticTransactionResult();
@@ -854,8 +857,9 @@ private void closeResources() {
//This can currently not happen
DBLogger.newFatal("Failed closing resource", e);
}
//TODO Why is this currently not done?
//resources.clear();
//This is a bit risky, if we get a concurrent update here we may not
//clear something from the list that has not been closed...(?)
resources.clear();
}
@@ -140,11 +140,11 @@
//such as the StorageRootFile.
//We keep the lock until initialization is finished, the lock is
//released by an initial rollback() call
if (ALLOW_READ_CONCURRENCY) {
// if (ALLOW_READ_CONCURRENCY) {
sm.readLock(this);
} else {
sm.writeLock(this);
}
// } else {
// sm.writeLock(this);
// }
this.freeIndex = sm.getFsm();
this.file = sm.getFile().createChannel();
@@ -434,11 +434,11 @@ public long beginTransaction() {
//TODO
//TODO
//TODO
if (ALLOW_READ_CONCURRENCY) {
// if (ALLOW_READ_CONCURRENCY) {
sm.readLock(this);
} else {
sm.writeLock(this);
}
// } else {
// sm.writeLock(this);
// }
//lock.lock();
// try {
// DBLogger.debugPrintln(1, "DAOF.beginTransaction() WLOCK");
@@ -452,7 +452,7 @@ public long beginTransaction() {
return txId;
}
private static boolean ALLOW_READ_CONCURRENCY = true;
private static boolean ALLOW_READ_CONCURRENCY = false;
@Deprecated
public static void allowReadConcurrency(boolean allowReadConcurrency) {
//System.err.println("Remove this and always allow read-concurrency!");
@@ -0,0 +1,60 @@
/*
* Copyright 2009-2016 Tilmann Zaeschke. All rights reserved.
*
* This file is part of ZooDB.
*
* ZooDB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ZooDB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ZooDB. If not, see <http://www.gnu.org/licenses/>.
*
* See the README and COPYING files for further information.
*/
package org.zoodb.internal.server.index;
import java.util.concurrent.atomic.AtomicLong;
import org.zoodb.internal.util.DBLogger;
public class OidCounter {
static final long MIN_OID = 100;
private final AtomicLong lastAllocatedInMemory = new AtomicLong(MIN_OID);
public long getLast() {
return lastAllocatedInMemory.get();
}
public void update(long oid) {
long expected;
while (oid > (expected = lastAllocatedInMemory.get())) {
lastAllocatedInMemory.compareAndSet(expected, oid);
}
}
public long[] allocateOids(int oidAllocSize) {
long l2 = lastAllocatedInMemory.addAndGet(oidAllocSize);
long l1 = l2 - oidAllocSize;
long[] ret = new long[(int) (l2-l1)];
for (int i = 0; i < l2-l1; i++ ) {
ret[i] = l1 + i + 1;
}
if (l2 < 0) {
throw DBLogger.newFatalInternal("OID overflow after alloc: " + oidAllocSize +
" / " + l2);
}
return ret;
}
}
@@ -85,8 +85,6 @@
*
*/
public class PagedOidIndex {
private static final long MIN_OID = 100;
public static final class FilePos {
final int page;
@@ -169,7 +167,7 @@ public void remove() {
}
private transient long lastAllocatedInMemory = MIN_OID;
private transient final OidCounter lastAllocatedInMemory = new OidCounter();
private transient LongLongIndex.LongLongUIndex idx;
/**
@@ -190,17 +188,13 @@ public PagedOidIndex(IOResourceProvider file) {
*/
public PagedOidIndex(IOResourceProvider file, int pageId, long lastUsedOid) {
idx = IndexFactory.loadUniqueIndex(PAGE_TYPE.OID_INDEX, file, pageId);
if (lastUsedOid > lastAllocatedInMemory) {
lastAllocatedInMemory = lastUsedOid;
}
lastAllocatedInMemory.update(lastUsedOid);
}
public void insertLong(long oid, int schPage, int schOffs) {
long newVal = (((long)schPage) << 32) | (long)schOffs;
idx.insertLong(oid, newVal);
if (oid > lastAllocatedInMemory) {
lastAllocatedInMemory = oid;
}
lastAllocatedInMemory.update(oid);
}
/**
@@ -236,21 +230,8 @@ public FilePos findOid(long oid) {
}
public long[] allocateOids(int oidAllocSize) {
long l1 = lastAllocatedInMemory;
long l2 = l1 + oidAllocSize;
long[] ret = new long[(int) (l2-l1)];
for (int i = 0; i < l2-l1; i++ ) {
ret[i] = l1 + i + 1;
}
lastAllocatedInMemory += oidAllocSize;
if (lastAllocatedInMemory < 0) {
throw DBLogger.newFatalInternal("OID overflow after alloc: " + oidAllocSize +
" / " + lastAllocatedInMemory);
}
//do not set dirty here!
return ret;
return lastAllocatedInMemory.allocateOids(oidAllocSize);
}
public OidIterator iterator() {
@@ -263,7 +244,7 @@ public void print() {
public long getMaxValue() {
long m = idx.getMaxKey();
return m > 0 ? m : MIN_OID;
return m > 0 ? m : OidCounter.MIN_OID;
}
public int statsGetLeavesN() {
@@ -283,7 +264,7 @@ public int write(StorageChannelOutput out) {
}
public long getLastUsedOid() {
return lastAllocatedInMemory;
return lastAllocatedInMemory.getLast();
}
public List<Integer> debugPageIds() {

0 comments on commit 62936f5

Please sign in to comment.