org.hd.d.pg2k.svrCore
Class AllExhibitImmutableData

java.lang.Object
  extended by org.hd.d.pg2k.svrCore.AllExhibitImmutableData
All Implemented Interfaces:
java.io.ObjectInputValidation, java.io.Serializable

public final class AllExhibitImmutableData
extends java.lang.Object
implements java.io.Serializable, java.io.ObjectInputValidation

Immutable set of names and ExhibitStaticAttr for all exhibits. This provides a set of all exhibits, mapped from the full name to the static/immutable attributes for an exhibit (ie the parts that will not change unless the exhibit itself is changed).

Also provides a mapping from the final file component (short name) of an exhibit to its full name within the collection. All exhibits should be unique in this last component; if not then only the alphabetically first full-name value will be kept.

Also contains the time of last change to exhibit set when this snapshot was taken; this is verified simply to be non-negative and may for example be some combination of timestamp and hash over the exhibit content to best catch changes in the exhibit-set composition or it may be a pure hash. If a combination then usually the most significant bits would be those of the newest exhibit and the least significant would be the hash. If the exhibit set changes then this value should change, however the timestamp may not monotonically increase as new exhibits are added (or existing ones are altered).

Designed to be efficient `on-the-wire'; for serialisation we send a count and the ExhibitStaticAttr objects in sorted order by name instead of the map, which should be much less bulky than our internal representation (which is designed for lookup speed), and contains all the required information. On deserialising we simply reconstruct the map. We still let default serialisation deal with any other fields (the timestamp).

(It looks like HashMap's serialisation must be quite good since the saving in uncompressed size is only about 6%.)

The hashCode() is based on a hash of the timestamp, and equality is based on the sets of exhibits and global and per-exhibit attributes being equal.

TODO: lazily compute dups and short-to-full lookup, etc, when conserving resources.

See Also:
Serialized Form

Field Summary
private  java.util.List<Name.ExhibitFull> _cacheSR_getAllExhibitNamesListSorted
          Cache for getAllExhibitNamesList() immutable content.
private static boolean ATTEMPT_TO_RECOMPRESS_NAMES
          If true, attempt to rebuild ESA names for better performance and/or reduced memory footprint.
 int length
          Exhibit count, with lock-free access; non-negative.
private  ExhibitStaticAttr[] orderedEsa
          In-order set of static-attribute instances; never null nor changed after construction/deserialisation.
private  java.util.SortedMap<java.lang.CharSequence,Name.ExhibitFull> pKeysToFull
          Sorted immutable Map of short-name persistable keys to full names; never null.
private static long serialVersionUID
          Our serial version...
private  Name.ExhibitFull[] shortNameDups
          Sorted logically-immutable array of full names with duplicate short names found by _buildShortToFull; never null.
static java.util.Comparator<java.lang.CharSequence> SORT_ORDER
          Sort order used for (full and short) exhibit names and static attrs containing them; non-null.
 long timestamp
          Timestamp of last exhibit update when this snapshot was taken.
private  Name.ExhibitShort[] uniqueShortNames
          Sorted logically-immutable set of unique short names; never null.
 
Constructor Summary
AllExhibitImmutableData()
          Construct an empty, zero-timestamp snapshot.
AllExhibitImmutableData(java.util.Set<ExhibitStaticAttr> staticAttrs, long lastExhibitChangeTimestamp)
          Construct a new snapshot.
 
Method Summary
private  void _buildShortToFull()
          Builds shortToFull and shortNameDups from orderedEsa.
private  void _computePKeys()
          Computes mapping from persistable keys back to full name.
private static void _optimiseESANames(ExhibitStaticAttr[] orderedESAs)
          Attempt to optimise the ESA names to improve sharing and/or performance.
 long computeFileSpaceBytes(java.lang.String author)
          Conservatively estimates filespace bytes required to store all exhibits.
 boolean equals(java.lang.Object obj)
          Returns true when the timestamp and underlying set of exhibit names is the same.
 java.util.List<Name.ExhibitFull> getAllExhibitNamesSorted()
          Gets an immutable sorted RandomAccess list of all full exhibit names; never null.
 Name.ExhibitShort[] getAllExhibitShortNamesArraySorted()
          Gets (sorted) array of all short exhibit names; never null nor containing nulls but may be zero-length.
 java.util.List<ExhibitStaticAttr> getAllStaticAttrs()
          Gets immutable (sorted) List of all static attrs; never null.
 Name.ExhibitFull getFullName(java.lang.CharSequence shortName)
          Gets the full name of an exhibit from its (unique) file component, ie short name or persistable key; null if no exhibit IN THIS AEID has the specified short name/key.
 Name.ExhibitFull getFullNameFromPersistableKey(java.lang.CharSequence cs)
          Gets the full name of an exhibit from its short-name persistable key; null if none.
 Name.ExhibitFull[] getFullNamesWithDuplicateShortNames()
          Gets (sorted) array of full names that have duplicate short names; never null nor containing nulls but may be zero-length.
 ExhibitStaticAttr getStaticAttr(java.lang.CharSequence fullName)
          Look up exhibit attributes by full exhibit name; null if not a valid exhibit in this set.
 ExhibitStaticAttr getStaticAttr(Name.ExhibitFull fullName)
          Look up exhibit attributes by full exhibit name; null if not a valid exhibit in this set.
 int hashCode()
          Returns a hash code value for the object derived from the timestamp.
 boolean isEmpty()
          True iff zero/no exhibits.
 boolean isPresent(java.lang.CharSequence fullName)
          Returns true iff the supplied full exhibit name is valid and is present in this collection.
 boolean isPresent(Name.ExhibitFull fullName)
          Returns true iff the supplied full exhibit name is valid and is present in this collection.
 boolean isPresent(Name.ExhibitShort shortName)
          Returns true iff the supplied short exhibit name is valid and is present in this collection.
private  void optionalEagerWarmup()
          Can be called from constructor or at end of deserialisation.
private  void readObject(java.io.ObjectInputStream ois)
          Deserialise.
 int size()
          Get exhibit count; 0 if no exhibits.
 void validateObject()
          Validate fields/state.
private  void writeObject(java.io.ObjectOutputStream oos)
          Write out a less-redundant (and more compressible) form of our internal information.
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

SORT_ORDER

public static final java.util.Comparator<java.lang.CharSequence> SORT_ORDER
Sort order used for (full and short) exhibit names and static attrs containing them; non-null.


orderedEsa

private transient ExhibitStaticAttr[] orderedEsa
In-order set of static-attribute instances; never null nor changed after construction/deserialisation.


timestamp

public final long timestamp
Timestamp of last exhibit update when this snapshot was taken. Strictly positive unless map is empty, in which case it will be zero.

This information is accessible without holding any locks.


length

public final int length
Exhibit count, with lock-free access; non-negative. The information in this is redundant but is small and useful for speed and an integrity check, etc.

This emulates the length field of an array while size() emulates the behaviour of collections...

This information is accessible without holding any locks.


shortNameDups

private transient Name.ExhibitFull[] shortNameDups
Sorted logically-immutable array of full names with duplicate short names found by _buildShortToFull; never null.


uniqueShortNames

private transient Name.ExhibitShort[] uniqueShortNames
Sorted logically-immutable set of unique short names; never null. Can implicitly be used to look up full names via getFullName().

Can be used to do look-up with other CharSequence implementations such as String.


pKeysToFull

private transient volatile java.util.SortedMap<java.lang.CharSequence,Name.ExhibitFull> pKeysToFull
Sorted immutable Map of short-name persistable keys to full names; never null. Can implicitly be used to look up full names via getFullName().

Can be used to do look-up with other CharSequence implementations such as String, ie the Comparator works with generic CharSequence values.

Volatile for lock-free read access.

Write access is under the instance lock and this map is created on first use.


_cacheSR_getAllExhibitNamesListSorted

private transient volatile java.util.List<Name.ExhibitFull> _cacheSR_getAllExhibitNamesListSorted
Cache for getAllExhibitNamesList() immutable content. Initially null, but never non-null once set.

Marked volatile for lock-free thread-safe access.

Marked transient as this is recomputable redundant state.

Not cleared once set so that the reference (and its identity hash) will be stable, suitable for use by AbstractFilterBean._select() for example.


ATTEMPT_TO_RECOMPRESS_NAMES

private static final boolean ATTEMPT_TO_RECOMPRESS_NAMES
If true, attempt to rebuild ESA names for better performance and/or reduced memory footprint. Fraught with peril, such as creating an extra copy of all names, etc.

See Also:
Constant Field Values

serialVersionUID

private static final long serialVersionUID
Our serial version...

See Also:
Constant Field Values
Constructor Detail

AllExhibitImmutableData

public AllExhibitImmutableData()
Construct an empty, zero-timestamp snapshot.


AllExhibitImmutableData

public AllExhibitImmutableData(java.util.Set<ExhibitStaticAttr> staticAttrs,
                               long lastExhibitChangeTimestamp)
                        throws java.lang.IllegalArgumentException
Construct a new snapshot. The input set is checked for uniqueness by full name, and the data may be reconstructed internally for efficiency.

The timestamp must be zero if the map is empty, else it must be strictly positive.

Throws:
java.lang.IllegalArgumentException - if the timestamp or input data are found to be malformed.
Method Detail

optionalEagerWarmup

private void optionalEagerWarmup()
Can be called from constructor or at end of deserialisation. Must not pass the possibly-incomplete object reference out.


_buildShortToFull

private void _buildShortToFull()
Builds shortToFull and shortNameDups from orderedEsa. We try to do this in a memory-efficient way.


getFullNamesWithDuplicateShortNames

public Name.ExhibitFull[] getFullNamesWithDuplicateShortNames()
Gets (sorted) array of full names that have duplicate short names; never null nor containing nulls but may be zero-length. This returns a copy that can be safely tampered with by the caller.


getAllExhibitShortNamesArraySorted

public Name.ExhibitShort[] getAllExhibitShortNamesArraySorted()
Gets (sorted) array of all short exhibit names; never null nor containing nulls but may be zero-length. This returns a copy that can be safely tampered with by the caller.


getFullNameFromPersistableKey

public Name.ExhibitFull getFullNameFromPersistableKey(java.lang.CharSequence cs)
Gets the full name of an exhibit from its short-name persistable key; null if none.


_computePKeys

private void _computePKeys()
Computes mapping from persistable keys back to full name. Should be called under the instance lock for efficiency, or when there is no possibility of multi-threading such as from the constructor or readObject().


getFullName

public Name.ExhibitFull getFullName(java.lang.CharSequence shortName)
Gets the full name of an exhibit from its (unique) file component, ie short name or persistable key; null if no exhibit IN THIS AEID has the specified short name/key.

Parameters:
shortName - file component or persistable key; must not be null
Returns:
non-null full name iff the supplied short name is a syntactically-valid short name or persistable key for that extant full name

isPresent

public boolean isPresent(Name.ExhibitShort shortName)
Returns true iff the supplied short exhibit name is valid and is present in this collection. Equivalent to the 'traditional' (null != getFullName(fullName)) test but may be more efficient and its purpose is clearer.

Parameters:
shortName - putative short name of an exhibit
Returns:
true iff shortName is not null and is the valid full name of an exhibit in this collection

isPresent

public boolean isPresent(Name.ExhibitFull fullName)
Returns true iff the supplied full exhibit name is valid and is present in this collection. Equivalent to the 'traditional' (null != getStaticAttr(fullName)) test but may be more efficient and its purpose is clearer.

Parameters:
fullName - putative full name of an exhibit
Returns:
true iff fullName is not null and is the valid full name of an exhibit in this collection

isPresent

public boolean isPresent(java.lang.CharSequence fullName)
Returns true iff the supplied full exhibit name is valid and is present in this collection. Equivalent to the 'traditional' (null != getStaticAttr(fullName)) test but may be more efficient and its purpose is clearer.

Parameters:
fullName - putative full name of an exhibit
Returns:
true iff fullName is not null and is the valid full name of an exhibit in this collection

getStaticAttr

public ExhibitStaticAttr getStaticAttr(Name.ExhibitFull fullName)
Look up exhibit attributes by full exhibit name; null if not a valid exhibit in this set. If result is non-null then the exhibit is valid.

May be slow if the argument is not a Name.ExhibitFillName, but especially in this case note that what is returned is the canonical internal ExhibitFull.

If the argument is null or invalid then this returns null rather than throwing an exception.


getStaticAttr

public ExhibitStaticAttr getStaticAttr(java.lang.CharSequence fullName)
Look up exhibit attributes by full exhibit name; null if not a valid exhibit in this set. If result is non-null then the exhibit is valid.

May be slow if the argument is not a Name.ExhibitFillName, but especially in this case note that what is returned is the canonical internal ExhibitFull.

If the argument is null or invalid then this returns null rather than throwing an exception.


size

public int size()
Get exhibit count; 0 if no exhibits.


isEmpty

public boolean isEmpty()
True iff zero/no exhibits.


getAllExhibitNamesSorted

public java.util.List<Name.ExhibitFull> getAllExhibitNamesSorted()
Gets an immutable sorted RandomAccess list of all full exhibit names; never null. Result is cached (and does not change) and so may be more efficient than (say) getAllExhibitNamesSet().


getAllStaticAttrs

public java.util.List<ExhibitStaticAttr> getAllStaticAttrs()
Gets immutable (sorted) List of all static attrs; never null. Should be fast to get and access elements of, ie lightweight and efficient.


computeFileSpaceBytes

public final long computeFileSpaceBytes(java.lang.String author)
Conservatively estimates filespace bytes required to store all exhibits. This makes some assumptions about filespace overhead and so on.

This is for the specific named author, unless author is null in which case it for all authors.

This separately rounds up each exhibit size and name size to an assume filesystem block size as per FileTools.roundUpToFSBlockSize().

Throws:
java.lang.IllegalArgumentException - if author is not null and is not a syntactically-valid author name (initials)

hashCode

public int hashCode()
Returns a hash code value for the object derived from the timestamp. Will be zero (because the timestamp is) if there are no exhibits.

Overrides:
hashCode in class java.lang.Object
Returns:
a hash code value for this object.
See Also:
Object.equals(Object), Hashtable

equals

public boolean equals(java.lang.Object obj)
Returns true when the timestamp and underlying set of exhibit names is the same.

Overrides:
equals in class java.lang.Object
Parameters:
obj - the reference object with which to compare.
Returns:
true if this object is the same as the obj argument; false otherwise.
See Also:
Boolean.hashCode(), Hashtable

writeObject

private void writeObject(java.io.ObjectOutputStream oos)
                  throws java.io.IOException
Write out a less-redundant (and more compressible) form of our internal information. We used to write this out in reverse sorted order; now we write in in forward sorted order and the ESA itself should be holding the name in a shared-prefix form.

Throws:
java.io.IOException

readObject

private void readObject(java.io.ObjectInputStream ois)
                 throws java.io.IOException,
                        java.lang.ClassNotFoundException
Deserialise.

Throws:
java.io.IOException
java.lang.ClassNotFoundException

_optimiseESANames

private static void _optimiseESANames(ExhibitStaticAttr[] orderedESAs)
Attempt to optimise the ESA names to improve sharing and/or performance. The ESAs passed in must be sorted in natural order, and all the embedded exhibit names are assumed likely to be intern()ed.

Parameters:
orderedESAs - sorted (in natural order, ie by name) ESAs; may be empty but never null.

validateObject

public void validateObject()
                    throws java.io.InvalidObjectException
Validate fields/state. Called in the constructor and possibly after de-serialising.

Barf if something bad is found. (Maybe allow some extra info in debug version.)

Specified by:
validateObject in interface java.io.ObjectInputValidation
Throws:
java.io.InvalidObjectException

DHD Multimedia Gallery V1.60.69

Copyright (c) 1996-2012, Damon Hart-Davis. All rights reserved.