mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-13 21:04:00 +00:00
The old version_array rewind code used linear stack space in order to
perform it's updates in the right order (newest to oldest) by following the
structure's next pointers (which are a oldest to newest list). I previously
introduced week prev pointers so that walking over this structure newest to
oldest could be done with constant stack space. However that is less
efficient than the method suggested by Peter Wang.
Peter suggested using a bitmap and traversing oldest-to-newest, marking
each update in the bitmap and checking the bitmap before making any update.
Thus preserving older values over newer ones (which is good, this code
_rewinds_ updates). This patch implements Peter's suggestion and removes
the prev pointers from the structure for C and Java backends.
Thanks to Peter Wang for giving me a hand with C#.
library/version_array.m:
As above.
runtime/mercury_bitmap.h:
Add some macros for initialising bitmaps and testing, setting and clearing
their bits.
library/bitmap.m:
java/runtime/MercuryBitmap.java:
Move the Java MercuryBitmap class into the runtime library. This makes
it easier for other standard library modules to use this Java class.
library/bitmap.m:
runtime/mercury_dotnet.cs.in:
Move C# MercuryBitmap class into runtime/mercury_dotnet.cs
library/bitmap.m:
Add extra methods to the C# MercuryBitmap class.
tests/hard_coded/version_array_test.exp:
tests/hard_coded/version_array_test.m:
Ensure that the test verifies that rolling back updates to a version
array rolls back changes in the correct order: If two updates modify the
same cell, then the older one should be visible in the result.
Use longer arrays so that the bitmap used in the rollback code is more
than one byte in length.
74 lines
2.0 KiB
Java
74 lines
2.0 KiB
Java
//
|
|
// Copyright (C) 2001-2002, 2004-2007, 2009-2011 The University of Melbourne
|
|
// Copyright (C) 2014 The Mercury Team.
|
|
// This file may only be copied under the terms of the GNU Library General
|
|
// Public License - see the file COPYING.LIB in the Mercury distribution.
|
|
//
|
|
|
|
package jmercury.runtime;
|
|
|
|
/**
|
|
* Simple bitmap implementation.
|
|
* This bitmap class is mainly used by bitmap.m in the standard library. It
|
|
* is also used by version_array.m which is why it is part of the
|
|
* jmercury.runtime package rather than being internal to bitmap.m
|
|
*/
|
|
public class MercuryBitmap implements java.io.Serializable {
|
|
public static final int BITS_PER_BYTE = 8;
|
|
public int num_bits;
|
|
public byte[] elements;
|
|
|
|
public MercuryBitmap(int numBits) {
|
|
int num_bytes = (numBits + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
|
|
|
|
this.num_bits = numBits;
|
|
this.elements = new byte[num_bytes];
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object that) {
|
|
if (this == that) {
|
|
return true;
|
|
}
|
|
if (that instanceof MercuryBitmap) {
|
|
MercuryBitmap other = (MercuryBitmap)that;
|
|
return this.num_bits == other.num_bits
|
|
&& java.util.Arrays.equals(this.elements, other.elements);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public boolean getBit(int bit)
|
|
{
|
|
return (elements[byteIndexForBit(bit)]
|
|
& (1 << bitIndexWithinByte(bit))) != 0;
|
|
}
|
|
|
|
public void setBit(int bit)
|
|
{
|
|
byte b;
|
|
|
|
b = elements[byteIndexForBit(bit)];
|
|
b |= 1 << bitIndexWithinByte(bit);
|
|
elements[byteIndexForBit(bit)] = b;
|
|
}
|
|
|
|
public void clearBit(int bit)
|
|
{
|
|
byte b;
|
|
|
|
b = elements[byteIndexForBit(bit)];
|
|
b &= ~(1 << bitIndexWithinByte(bit));
|
|
elements[byteIndexForBit(bit)] = b;
|
|
}
|
|
|
|
public static int byteIndexForBit(int bit) {
|
|
return bit / BITS_PER_BYTE;
|
|
}
|
|
|
|
public static int bitIndexWithinByte(int bit) {
|
|
return bit % BITS_PER_BYTE;
|
|
}
|
|
}
|
|
|