Changeset 12969 for trunk/abcl/src/org


Ignore:
Timestamp:
10/09/10 23:28:31 (11 years ago)
Author:
ehuelsmann
Message:

Implement nearly lock-free hash reader functionality, by
looking really well at ConcurrentHashMap? - agreed.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/abcl/src/org/armedbear/lisp/HashTable.java

    r12968 r12969  
    3434package org.armedbear.lisp;
    3535
    36 import java.util.concurrent.ConcurrentHashMap;
    37 import java.util.concurrent.locks.ReentrantReadWriteLock;
     36import java.util.concurrent.locks.ReentrantLock;
    3837import static org.armedbear.lisp.Lisp.*;
    3938
     
    4746    protected int threshold;
    4847    // Array containing the actual key-value mappings.
    49    
    5048    @SuppressWarnings("VolatileArrayField")
    5149    protected volatile HashEntry[] buckets;
    52    
    5350    // The number of key-value pairs.
    54     protected int count;
    55     private int mask;
     51    protected volatile int count;
    5652    final Comparator comparator;
    57     final private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
     53    final private ReentrantLock lock = new ReentrantLock();
    5854
    5955    protected HashTable(Comparator c, int size, LispObject rehashSize,
     
    6460        threshold = (int) (size * loadFactor);
    6561        comparator = c;
    66         mask = buckets.length - 1;
    6762    }
    6863
     
    157152
    158153    public void clear() {
    159         lock.writeLock().lock();
     154        lock.lock();
    160155        try {
    161156            buckets = new HashEntry[buckets.length];
    162157            count = 0;
    163158        } finally {
    164             lock.writeLock().unlock();
     159            lock.unlock();
    165160        }
    166161    }
     
    234229
    235230    protected HashEntry getEntry(LispObject key) {
    236         int index = comparator.hash(key) & mask;
    237         HashEntry e = buckets[index];
     231        HashEntry[] b = buckets;
     232        HashEntry e = b[comparator.hash(key) & (b.length - 1)];
    238233        while (e != null) {
    239234            if (comparator.keysEqual(key, e.key)) {
     
    246241
    247242    public LispObject get(LispObject key) {
    248         lock.readLock().lock();
     243        HashEntry e = getEntry(key);
     244        LispObject v = (e == null) ? null : e.value;
     245
     246        if (e == null || v != null) {
     247            return v;
     248        }
     249
     250        lock.lock();
     251        try {
     252            return e.value;
     253        } finally {
     254            lock.unlock();
     255        }
     256    }
     257
     258    public void put(LispObject key, LispObject value) {
     259        lock.lock();
    249260        try {
    250261            HashEntry e = getEntry(key);
    251             return (e == null) ? null : e.value;
    252         } finally {
    253             lock.readLock().unlock();
    254         }
    255     }
    256 
    257     public void put(LispObject key, LispObject value) {
    258         lock.writeLock().lock();
    259         try {
    260             HashEntry e = getEntry(key);
    261             if (e == null) {
     262            if (e != null) {
    262263                e.value = value;
    263264            } else {
     
    267268                }
    268269
    269                 int index = comparator.hash(key) & mask;
     270                int index = comparator.hash(key) & (buckets.length - 1);
    270271                buckets[index] = new HashEntry(key, value, buckets[index]);
    271272            }
    272273        } finally {
    273             lock.writeLock().unlock();
     274            lock.unlock();
    274275        }
    275276    }
    276277
    277278    public LispObject remove(LispObject key) {
    278         lock.writeLock().lock();
     279        lock.lock();
    279280        try {
    280             int index = comparator.hash(key) & mask;
     281            int index = comparator.hash(key) & (buckets.length - 1);
    281282
    282283            HashEntry e = buckets[index];
     
    297298            return null;
    298299        } finally {
    299             lock.writeLock().unlock();
     300            lock.unlock();
    300301        }
    301302    }
    302303
    303304    protected void rehash() {
    304         lock.writeLock().lock();
     305        lock.lock();
    305306        try {
    306307            final int newCapacity = buckets.length * 2;
    307308            threshold = (int) (newCapacity * loadFactor);
    308             mask = newCapacity - 1;
     309            int mask = newCapacity - 1;
    309310            HashEntry[] newBuckets = new HashEntry[newCapacity];
    310311
     
    319320            buckets = newBuckets;
    320321        } finally {
    321             lock.writeLock().unlock();
     322            lock.unlock();
    322323        }
    323324    }
     
    416417
    417418        LispObject key;
    418         LispObject value;
     419        volatile LispObject value;
    419420        HashEntry next;
    420421
Note: See TracChangeset for help on using the changeset viewer.