1 / 61

Designing a Flexible Framework for a Table Abstraction

Designing a Flexible Framework for a Table Abstraction. H. Conrad Cunningham 1 Yi Liu 2 Jingyi Wang 3 1 University of Mississippi 2 South Dakota State University 3 Acxiom Corporation. Software Interfaces Project (1996-2000).

karolyn
Download Presentation

Designing a Flexible Framework for a Table Abstraction

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Designing a Flexible Framework for a Table Abstraction H. Conrad Cunningham 1 Yi Liu 2 Jingyi Wang 3 1 University of Mississippi 2 South Dakota State University 3Acxiom Corporation

  2. Software Interfaces Project (1996-2000) Context: development of an instructional data and file structures library (for Java in CSci 211) • artifacts for study of good design techniques • system for use, extension, and modification Motivation: study techniques for • presenting important methods to students (frameworks, software design patterns, design by contract, etc.) • unifying related file and data structures in framework

  3. Table Abstract Data Type (ADT) • Collection of records • each a finite sequence of data fields • key field value uniquely identifies record within collection • Operations on collection and on record using key • Several different implementations possible

  4. Table ADT Operations • Insert new record • Delete existing record given key • Update existing record • Retrieve existing record given key • Get number of records • Query whether contains given key • Query whether empty • Query whether full

  5. Software Framework • Generic application allowing creation of members of family of related programs • Reusable design expressed as set of abstract classes and way they collaborate • Common and variable aspects known as frozen spots and hot spots Frozen spots Framework library Framework Hot spots User-supplied code(application specific)

  6. Software Design Contracts • Preconditions for correct use of operation • Postconditions for correct result of operation • Invariant conditions for correct implementation of class Insert record operation pre: record is valid and not already in table post: record now in table Invariant for table all records are valid, no duplicate keys

  7. Software Design Patterns • Describe recurring design problems arising in specific contexts • Present well-proven generic solution schemes • Describe solution’s components and their responsibilities and relationships • To use: • select pattern that fits problem • structure solution to follow pattern

  8. Table Framework Requirements(from 2001 paper) • Provide Table ADT functionality for client-defined records and keys • Support many implementations of access and storage mechanisms • Separate key-based access mechanism from storage mechanism • Present coherent abstractions with well-defined interfaces • Use software design patterns and design contracts

  9. Hot Spot Analysis of Requirements • Provide Table ADT functionalityfor client-defined records and keys • Support many implementations of access and storage mechanisms • Separate key-based access mechanism from storage mechanism • Present coherent abstractions with well-defined interfaces • Use software design patterns and design contracts

  10. Table Hot Spot Analysis Frozen spot • Provide Table ADT functionality Hot spots • Variability in keys (defined by clients) • Variability in records (defined by clients) • Variability in external representation of record state • Variability in access (i.e, indexing) mechanism • Variability in storage mechanism Hot spots #1 and #2 not completely independent Hot spot #3 quite subtle Desire to separate concerns (i.e., the hot spots)

  11. Client Layer Access Layer Storage Layer Layered Architecture Pattern • Distinct groups of services • Hierarchical arrangement of groups into layers • Layer implemented with services of layer below • Enables independent implementation of hot spots in layers

  12. Applying Layered Architecture Pattern Client Layer – Hot spots #1 and #2 • includes client application programs • implements record and key abstractions • uses layer below to store and retrieve records Access Layer – Frozen spot and Hot spot #4 • includes table implementations • provides key-based access to records for layer above • calls back to record and key implementations in level above • uses physical storage in layer below Storage Layer – Hot spot #5 • storage managers • provides physical storage for records • calls back to record implementations in layers above

  13. Encapsulate hot spots #1 and #2 Variability in keys (defined by clients) Variability in records (defined by clients) Client Layer of Architecture

  14. Challenges enabling Access Layer to access client-defined records and keys avoiding unnecessary programming to use common data types Pattern Interface – applied independently for hot spots #1 (keys) and #2 (records) Client Layer Design

  15. Client Layer Interfaces(1 of 2) Hot spot #1 – Variability in keys • Must be able to (at a minimum) compare with total ordering • Choose to use Comparable interface from Java API for convenience Comparable interface for keys • int compareTo(Object key)compares object with argument

  16. Client Layer Interfaces(2 of 2) Hot spot #2 – Variability in records • Must be able to extract keys for comparison • Choose to define an appropriate new interface Keyed interface for records • Comparable getKey() extracts key from record

  17. Client Layer Model Abstract predicates – for use in specification of this and other layers (not necessarily implemented) • boolean isValidKey(Object key) yields true for valid key values • boolean isValidRec(Object rec) yields true for valid record values

  18. Client Layer Design Contracts Hot spot #1 Comparable int compareTo(Object key) Pre: isValidKey(this) && isValidKey(key) Post: result == (if this < key then -1 else if this == key then 0 else 1) Hot spot #2 Keyed Comparable getKey() Pre: isValidRec(this) Post: (result == attribute key of this record) && isValidKey(result)

  19. Client Layer Challenges Met? • Enabling Access Layer to access client-defined records and keys • records and keys implementations encapsulated within objects that implement Keyed and Comparable • Avoiding unnecessary programming to use common data types • reuse Comparable from Java API

  20. Access Layer of Architecture Encapsulate hot spot #4: Variability in access (i.e, indexing) mechanism

  21. Access Layer Design Challenges • enabling use of client-defined keys and records • enabling diverse implementations of indexing structure • enabling use of diverse storage structures Pattern • Interface – applied for hot spot #4 (access) and frozen spot (Table ADT)

  22. Access Layer Interface Table void insert(Keyed r) inserts r into table void delete(Comparable key) removes record with key void update(Keyed r) changes record with same key Keyed retrieve(Comparable key) returns record with key int getSize() returns size of table boolean containsKey(Comparable key) searches for key boolean isEmpty() checks whether table is empty boolean isFull() checks whether table is full • for unbounded, always returns false

  23. Access Layer Model Partial function table :: Comparable  Keyed • represents abstract table state • consider this: number of entries finite or infinite? If finite, bounded or unbounded? If infinite, countable or not? • #table in postcondition denotes table before operation • use as either function or set of key-record pairs Abstract predicates (to capture environmental assumptions) • isValidKey(Object)and isValidRec(Object)defined in Client Layer to identify valid keys and records • isStorable(Object) defined in Storage Layer to identify records that can be stored

  24. Table Design Contract (1 of 5) Invariant ( k, r : r == table(k) : isValidKey(k) && isValidRec(r) && isStorable(r) && k == r.getKey() )

  25. Table Design Contract (2 of 5) void insert(Keyed r) inserts r into table Pre: isValidRec(r) && isStorable(r) && !containsKey(r.getKey())&& !isFull() Post: table == #table  {(r.getKey(),r)} void delete(Comparable key) removes record with key from table Pre: isValidKey(key) && containsKey(key) Post: table == #table - {(key,#table(key))} Question: Does this allow table be initialized nonempty?

  26. Table Design Contract (3 of 5) void update(Keyed r)changes record with same key Pre: isValidRec(r) && isStorable(r) && containsKey(r.getKey()) Post: table == (#table - {(r.getKey(),#table(r.getKey()))} )  {(r.getKey(),r)} Keyed retrieve(Comparable key) returns record with key Pre: isValidKey(key) && containsKey(key) Post: result == #table(r.getKey())

  27. Table Design Contract (4 of 5) int getSize() returns size of table Pre: true Post: result == cardinality(#table) Note: If size not finite, need way to represent infinity boolean containsKey(Comparable key) searches table for key Pre: isValidKey(key) Post: result == defined(#table(key))

  28. Table Design Contract (5 of 5) boolean isEmpty()checks whether table is empty Pre: true Post: result == (#table = ) boolean isFull()checks whether table is full – for unbounded, always returns false Pre : true Post: result == (#table implementation has no free space to store record)

  29. Client/Access Layer Interactions • Client calls Access Layer class implementing Table interface • Access calls back to Client implementations of Keyed and Comparable interfaces

  30. Access Layer Challenges Met? • Enabling use of client-defined keys and records • callbacks to Comparable and Keyed abstractions which hide the implementation details • Enabling diverse implementations of the table • careful design of table interface semantics using design by contract • Enabling use of diverse storage mechanisms • calls to Storage Layer interfaces

  31. Storage Layer of Architecture Encapsulate hot spot #5: Variability in storage mechanism

  32. Storage Layer Design Challenges • supporting client-defined records • supporting diverse table implementations in Access Layer (simple indexes, hashing, balanced trees, etc.) • allowing diverse physical media (in-memory, on-disk, etc.) • enabling persistence of table, including access layer • decoupling implementations as much as possible Patterns • Bridge • Proxy

  33. uses Table RecordStore Simple Indexed File Hashed File Slotted File Store Vector File Bridge Pattern • Decouple “interface” from “implementation” • table from storage in this case • Allow them to vary independently • plug any storage mechanism into table

  34. Proxy Pattern • Transparently manage services of target object • isolate Table implementation from nature/location of record slots in RecordStore implementation • Introduce proxy object as surrogate for target RecordStore Table RecordSlot handle

  35. Storage Layer Interfaces RecordStore • operations to allocate and deallocate storage slots RecordSlot • operations to get and set records in slots • operations to get handle and containingRecordStore

  36. Storage Layer Model(1 of 2) Partial function store :: int  Object • represents abstract RecordStore state Set Handles  int, NULLHANDLE  Handles Set alloc  Handles • represents set of allocated slot handles Setunalloc == Handles - alloc • represents set of unallocated slot handles Abstract predicateisStorable(Object) • depends on storage mechanism

  37. Storage Layer Model(2 of 2) Invariant: ( h,r : r == store(h) : isStorable(r)) && ( h :: h  alloc == defined(store(h)))

  38. RecordStore Interface RecordSlot newSlot()allocates a new record slot RecordSlot getSlot(int handle)rebuilds record slot using given handle void releaseSlot(RecordSlot slot)deallocates recordslot

  39. RecordStore Design Contract (1 of 2) RecordSlot newSlot() allocates a new record slot, but it might be done in a lazy fashion Pre: true Post: result.getContainer() == this_RecordStore && result.getRecord() == NULLRECORD &&result.getHandle()  #alloc && result.getHandle()  alloc  {NULLHANDLE} Note: NULLRECORD built according to Null Object pattern RecordSlot getSlot(int handle) rebuilds record slot using given handle Pre: handle  alloc Post: result.getContainer() == this_RecordStore && result.getRecord() == #store(handle) &&result.getHandle() == handle

  40. RecordStore Design Contract (2 of 2) void releaseSlot(RecordSlot slot) deallocates record slot Pre: slot.getHandle()  alloc {NULLHANDLE}&& slot.getContainer() == this_RecordStore Post: alloc == #alloc - {slot.getHandle()} && store == #store – {(slot.getHandle(),slot.getRecord())}

  41. RecordSlot Interface void setRecord(Object rec) stores rec in this slot • allocation of handle done here or already done by getSlot Object getRecord() returns record stored in this slot int getHandle() returns handle of this slot RecordStore getContainer() returns reference to RecordStore holding this slot boolean isEmpty() determines whether this slot empty

  42. RecordSlot Model Each slot has two attributes: • reference to RecordStore to which this RecordSlot belongs, which is immutable • handle for the associated physical storage slot in the RecordStore (as constrained in RecordStore) Invariant: getHandle() alloc  {NULLHANDLE}

  43. RecordSlot Design Contract (1 of 3) void setRecord(Object rec) stores rec in this slot • allocation of handle done here or already done by getSlot() Pre: isStorable(rec) Post: Let h == getHandle(): (h  #alloc  store == (#store - {(h,#store(h))})  {(h,rec)} ) && (h = NULLHANDLE  ( g : g  #unalloc : alloc == #alloc  {g} && store = #store  {(g,rec)} ))

  44. RecordSlot Design Contract (2 of 3) Object getRecord() returns record stored in this slot Pre: true Post: Let h == getHandle(): (h  #alloc  result == #store(h)) && (h == NULLHANDLEresult == NULLRECORD) int getHandle() returns handle of this slot Pre: true Post: result == handle associated with this slot

  45. RecordSlot Design Contract (3 of 3) RecordStore getContainer() returns reference to RecordStore holding this slot Pre: true Post: result == RecordStore associated with this slot boolean isEmpty() determines whether this slot empty Pre: true Post: result == (getHandle() == NULLHANDLE || record associated with slot is NULLRECORD)

  46. Storage Layer Challenges Met?(1 of 2) • Supporting client-defined records • deferred to Externalization Module • Supporting diverse table implementations in Access Layer • careful design of RecordStore and RecordSlot abstractions to have sufficient functionality • Allowing diverse physical media • careful design of RecordStore abstraction to hide media, implementable in many ways, • partly deferred to Externalization Module

  47. Storage Layer Challenges Met?(2 of 2) • Decoupling implementations as much as possible • use of RecordSlot, handle, and Externalization Module • Enabling persistence of Table, including Access Layer • store RecordStore identifier and handles

  48. Access/Storage Layer Interactions • Access Layer Table callsRecordStore in Storage Layer to get RecordSlot object • Access Layer calls RecordSlot to store and retrieve its records • If needed, RecordSlot calls back to Record implementation in Access Layer • interface Record defined in Externalization Module

  49. Externalization Module of Architecture Encapsulate Hot Spot #3: Variability in external representation of record state

  50. Externalization Module Design Challenges (e.g., to support Storage Layer) • supporting client-defined records • allowing diverse physical media • decoupling implementations Pattern: Interface

More Related