Title: ObjectOriented DBMSs
1Chapter 22
- Object-Oriented DBMSs
- Transparencies
2Chapter - Objectives
- Framework for an OODM.
- Basics of persistent programming languages.
- Main strategies for developing an OODBMS.
- Single-level v. two-level storage models.
- How an OODBMS accesses records.
- Persistent schemes.
- Advantages and disadvantages of orthogonal
persistence.
2
3Chapter - Objectives
- Pointer swizzling.
- Issues underlying ODBMSs.
- Advantages and disadvantages.
- OODBMS Manifesto.
- Object-oriented database design.
- Main features of ODMG Object Database Standard.
3
4Object-Oriented Data Model
- No one agreed object data model. One definition
- Object-Oriented Data Model (OODM)
- Data model that captures semantics of objects
supported in object-oriented programming. - Object-Oriented Database (OODB)
- Persistent and sharable collection of objects
defined by an ODM. - Object-Oriented DBMS (OODBMS)
- Manager of an ODB.
4
5Object-Oriented Data Model
- Zdonik and Maier present a threshold model that
an OODBMS must at a minimum, satisfy - It must provide database functionality.
- It must support object identity.
- It must provide encapsulation.
- It must support objects with complex state.
5
6Object-Oriented Data Model
- Khoshafian and Abnous define OODBMS as
- OO ADTs Inheritance Object identity
- OODBMS OO Database capabilities.
- Parsaye et al. gives
- High-level query language with query
optimization. - Support for persistence, atomic transactions
concurrency and recovery control. - Support for complex object storage, indexes, and
access methods. - OODBMS OO system (1), (2), and (3).
6
7Commercial OODBMSs
- GemStone from Gemstone Systems Inc.,
- Itasca from Itasca Systems Inc.,
- Objectivity/DB from Objectivity Inc.,
- ObjectStore from Object Design Inc.,
- Ontos from Ontos Inc.,
- O2 from O2 Technology,
- Poet from Poet Software Corp.,
- Versant from Versant Object Technology.
7
8Origins of the Object-Oriented Data Model
8
9Persistent Programming Languages (PPLs)
- A language that provides users with ability to
(transparently) preserve data across successive
executions of a program, and even allows such
data to be used by many different programs. - In contrast, database programming language (e.g.
SQL) differs by its incorporation of features
beyond persistence, such as transaction
management, concurrency control, and recovery.
9
10Persistent Programming Languages (PPLs)
- PPLs eliminate impedance mismatch by extending
programming language with database capabilities. - In PPL, languages type system provides data
model, containing rich structuring mechanisms. - In some PPLs procedures are first class objects
and are treated like any other object in
language. - Procedures are assignable, may be result of
expressions, other procedures or blocks, and may
be elements of constructor types. - Procedures can be used to implement ADTs.
10
11Persistent Programming Languages (PPLs)
- PPL also maintains same data representation in
memory as in persistent store. - Overcomes difficulty and overhead of mapping
between the two representations. - Addition of (transparent) persistence into a PPL
is important enhancement to IDE, and integration
of two paradigms provides more functionality and
semantics.
11
12Alternative Strategies for Developing an OODBMS
- Extend existing object-oriented programming
language. - GemStone extended Smalltalk.
- Provide extensible object-oriented DBMS library.
- Approach taken by Ontos and ObjectStore.
- Embed OODB language constructs in a conventional
host language. - Approach taken by O2,which has extensions for C.
12
13Alternative Strategies for Developing an OODBMS
- Extend existing database language with
object-oriented capabilities. - Approach being pursued by RDBMS and OODBMS
vendors. - Ontos, Versant and O2 provide a version of OSQL.
- Develop a novel database data model/language.
13
14Single-Level v. Two-Level Storage Model
- Traditional programming languages lack built-in
support for many database features. - Increasing number of applications now require
functionality from both database systems and
programming languages. - Such applications need to store and retrieve
large amounts of shared, structured data.
14
15Single-Level v. Two-Level Storage Model
- With a traditional DBMS, programmer has to
- decide when to read and update objects.
- write code to translate between applications
object model and the data model of the DBMS. - perform additional type-checking when object is
read back from database, to guarantee object will
conform to its original type.
15
16Single-Level v. Two-Level Storage Model
- Difficulties occur because conventional DBMSs
have two-level storage model storage model in
memory, and database storage model on disk. - In contrast, OODBMS gives illusion of
single-level storage model, with similar
representation in both memory and in database
stored on disk. - Requires clever management of representation of
objects in memory and on disk (called pointer
swizzling).
16
17Two-level Storage Model for RDBMS
17
18Single-level Storage Model for OODBMS
18
19Accessing an Object with a RDBMS
19
20Accessing an Object with an OODBMS
20
21Persistent Schemes
- Consider three persistent schemes
- Checkpointing
- Serialization
- Explicit Paging.
- Note, persistence can also be applied to (object)
code and to the program execution state.
21
22Checkpointing
- Copy all or part of programs address space to
secondary storage. - If complete address space saved, program can
restart from checkpoint. - In other cases, only programs heap saved.
- Two main drawbacks
- Can only be used by program that created it
- May contain large amount of data that is of no
use in subsequent executions.
22
23Serialization
- Copy closure of a data structure to disk.
- Write on a data value may involve traversal of
graph of objects reachable from the value, and
writing of flattened version of structure to
disk. - Reading back flattened data structure produces
new copy of original data structure. - Sometimes called serialization, pickling, or in a
distributed computing context, marshaling.
23
24Serialization
- Two inherent problems
- Does not preserve object identity.
- Not incremental, so saving small changes to a
large data structure is not efficient.
24
25Explicit Paging
- Explicitly page objects between application
heap and persistent store. - Usually requires conversion of object pointers
from disk-based scheme to memory-based scheme. - Two common methods for creating/updating
persistent objects - Reachability-based
- Allocation-based.
25
26Explicit Paging - Reachability-based persistence
- Object will persist if it is reachable from a
persistent root object. - Programmer does not need to decide at object
creation time whether object should be
persistent. - Object can become persistent by adding it to the
reachability tree. - Maps well onto language that contains garbage
collection mechanism (e.g. Smalltalk or Java).
26
27Explicit Paging - Allocation-based persistence
- Object only made persistent if it is explicitly
declared as such within the application program. - Can be achieved in several ways
- By class
- By explicit call .
27
28Explicit Paging - Allocation-based persistence
- By class
- Class is statically declared to be persistent and
all instances made persistent when they are
created. - Class may be subclass of system-supplied
persistent class. - By explicit call
- Object may be specified as persistent when it is
created or, dynamically at runtime.
28
29Orthogonal Persistence
- Three fundamental principles
- Persistence independence
- Data type orthogonality
- Transitive persistence (originally referred to as
persistence identification but ODMG term
transitive persistence used here).
29
30Persistence Independence
- Persistence of object independent of how program
manipulates that object. - Conversely, code fragment independent of
persistence of data it manipulates. - Should be possible to call function with its
parameters sometimes objects with long term
persistence and sometimes only transient. - Programmer does not need to control movement of
data between long and short term storage.
30
31Data Type Orthogonality
- All data objects should be allowed full range of
persistence irrespective of their type. - No special cases where object is not allowed to
be long-lived or is not allowed to be transient. - In some PPLs, persistence is quality attributable
to only subset of language data types.
31
32Transitive Persistence
- Choice of how to identify and provide persistent
objects at language level is independent of the
choice of data types in the language. - Technique that is now widely used for
identification is reachability-based.
32
33Orthogonal Persistence - Advantages
- Improved programmer productivity from simpler
semantics. - Improved maintenance.
- Consistent protection mechanisms over whole
environment. - Support for incremental evolution.
- Automatic referential integrity.
33
34Orthogonal Persistence - Disadvantages
- Some runtime expense in a system where every
pointer reference might be addressing persistent
object. - System required to test if object must be loaded
in from disk-resident database. - Although orthogonal persistence promotes
transparency, system with support for sharing
among concurrent processes cannot be fully
transparent.
34
35Pointer Swizzling Techniques
- The action of converting object identifiers
(OIDs) to main memory pointers. - Aim is to optimize access to objects.
- Should be able to locate any referenced objects
on secondary storage using their OIDs. - Once objects have been read into cache, want to
record that objects are now in memory to prevent
them from being retrieved again.
35
36Pointer Swizzling Techniques
- Could hold lookup table that maps OIDs to memory
pointers. - Pointer swizzling attempts to provide a more
efficient strategy by storing memory pointers in
the place of referenced OIDs, and vice versa when
the object is written back to disk.
36
37No Swizzling
- Easiest implementation is not to do any
swizzling. - Objects faulted into memory, and handle passed to
application containing objects OID. - OID is used every time the object is accessed.
- System must maintain some type of lookup table so
that objects virtual memory pointer can be
located and then used to access object. - Inefficient if same objects are accessed
repeatedly. - Acceptable if objects only accessed once.
37
38Object Referencing
- Need to distinguish between resident and
non-resident objects. - Most techniques variations of edge marking or
node marking. - Edge marking marks every object pointer with a
tag bit. - If bit set, reference is to memory pointer
- Else, still pointing to OID and needs to be
swizzled when object it refers to is faulted
into.
38
39Object Referencing
- Node marking requires that all object references
are immediately converted to virtual memory
pointers when object is faulted into memory. - First approach is software-based technique but
second can be implemented using software or
hardware-based techniques.
39
40Hardware-based Schemes
- Use virtual memory access protection violations
to detect accesses of non-resident objects. - Use standard virtual memory hardware to trigger
transfer of persistent data from disk to memory. - Once page has been faulted in, objects are
accessed via normal virtual memory pointers and
no further object residency checking is required.
- Avoids overhead of residency checks incurred by
software approaches.
40
41Pointer Swizzling - Other Issues
- Three other issues that affect swizzling
techniques - Copy versus In-Place Swizzling
- Eager versus Lazy Swizzling
- Direct versus Indirect Swizzling.
41
42Copy versus In-Place Swizzling
- When faulting objects in, data can either be
copied into applications local object cache or
accessed in-place within object managers
database cache . - Copy swizzling may be more efficient as, in the
worst case, only modified objects have to be
swizzled back to their OIDs. - In-place may have to unswizzle entire page of
objects if one object on page is modified.
42
43Eager versus Lazy Swizzling
- Moss defines eager swizzling as swizzling all
OIDs for persistent objects on all data pages
used by application, before any object can be
accessed. - More relaxed definition restricts swizzling to
all persistent OIDs within object the application
wishes to access. - Lazy swizzling only swizzles pointers as they are
accessed or discovered.
43
44Direct versus Indirect Swizzling
- Only an issue when swizzled pointer can refer to
object that is no longer in virtual memory. - With direct swizzling, virtual memory pointer of
referenced object is placed directly in swizzled
pointer. - With indirect swizzling, virtual memory pointer
is placed in an intermediate object, which acts
as a placeholder for the actual object. - Allows objects to be uncached without requiring
swizzled pointers to be unswizzled.
44
45Versions
- Allows changes to properties of objects to be
managed so that object references always point to
correct object version. - Itasca identifies 3 types of versions
- Transient Versions.
- Working Versions.
- Released Versions.
45
46Versions and Configurations
46
47Multiversion Timestamp Ordering
- Versioning of data can be used to increase
concurrency. - Basic timestamp ordering protocol assumes only
one version of data item exists, and so only one
transaction can access data item at a time. - Can allow multiple transactions to read and write
different versions of same data item, and ensure
each transaction sees consistent set of versions
for all data items it accesses.
47
48Multiversion Timestamp Ordering
- In multiversion concurrency control, each write
operation creates new version of data item while
retaining old version. - When transaction attempts to read data item,
system selects one version that ensures
serializability. - Versions can be deleted once they are no longer
required.
48
49Schema Evolution
- Some applications require considerable
flexibility in dynamically defining and modifying
database schema. - Typical schema changes
- (1) Changes to class definition
- (a) Modifying Attributes
- (b) Modifying Methods.
49
50Schema Evolution
- (2) Changes to inheritance hierarchy
- (a) Making a class S superclass of a class C.
- (b) Removing S from list of superclasses of C.
- (c) Modifying order of superclasses of C.
- (3) Changes to set of classes, such as creating
and deleting classes and modifying class names. - Changes must not leave schema inconsistent.
50
51Schema Consistency
- 1. Resolution of conflicts caused by multiple
inheritance and redefinition of attributes and
methods in a subclass. - 1.1 Rule of precedence of subclasses over
superclasses. - 1.2 Rule of precedence between superclasses of a
different origin. - 1.3 Rule of precedence between superclasses of
the same origin.
51
52Schema Consistency
- 2. The propagation of modifications to
subclasses. - 2.1 Rule for propagation of modifications.
- 2.2 Rule for propagation of modifications in the
event of conflicts. - 2.3 Rule for modification of domains.
52
53Schema Consistency
- 3. The aggregation and deletion of inheritance
relationships between classes and the creation
and removal of classes. - 3.1 Rule for inserting superclasses.
- 3.2 Rule for removing superclasses.
- 3.3 Rule for inserting a class into a schema.
- 3.4 Rule for removing a class from a schema.
53
54Client-Server Architecture
- Three basic architectures
- Object Server
- Page Server
- Database Server.
54
55Object Server
- Distribute processing between the two components.
- Typically, client is responsible for transaction
management and interfacing to programming
language. - Server responsible for other DBMS functions.
- Best for cooperative, object-to-object processing
in an open, distributed environment.
55
56Page and Database Server
- Page Server
- Most database processing is performed by client.
- Server responsible for secondary storage and
providing pages at client's request. - Database Server
- Most database processing performed by server.
- Client simply passes requests to server, receives
results and passes them to application. - Approach taken by many RDBMSs.
56
57Client-Server Architecture
57
58Architecture - Storing and Executing Methods
- Two approaches
- Store methods in external files.
- Store methods in database.
- Benefits of latter approach
- Eliminates redundant code.
- Simplifies modifications.
58
59Architecture - Storing and Executing Methods
- Methods are more secure.
- Methods can be shared concurrently.
- Improved integrity.
- Obviously, more difficult to implement.
59
60Architecture - Storing and Executing Methods
60
61OODBMS Manifesto
- Complex objects must be supported.
- Object identity must be supported.
- Encapsulation must be supported.
- Types or Classes must be supported.
- Types or Classes must be able to inherit from
their ancestors. - Dynamic binding must be supported.
- The DML must be computationally complete.
61
62OODBMS Manifesto
- The set of data types must be extensible.
- Data persistence must be provided.
- The DBMS must be capable of managing very large
databases. - The DBMS must support concurrent users.
- DBMS must be able to recovery from
hardware/software failures. - The DBMS must provide a simple way of querying
data.
62
63OODBMS Manifesto
- The manifesto proposes the following optional
features - Multiple inheritance, type checking and type
inferencing, distribution across a network,
design transactions and versions. - No direct mention of support for security,
integrity, views or even a declarative query
language.
63
64Advantages of OODBMSs
- Enriched Modeling Capabilities.
- Extensibility.
- Removal of Impedance Mismatch.
- More Expressive Query Language.
- Support for Schema Evolution.
- Support for Long Duration Transactions.
- Applicability to Advanced Database Applications.
- Improved Performance.
64
65Disadvantages of OODBMSs
- Lack of Universal Data Model.
- Lack of Experience.
- Lack of Standards.
- Query Optimization compromises Encapsulation.
- Object Level Locking may impact Performance.
- Complexity.
- Lack of Support for Views.
- Lack of Support for Security.
65
66Object-Oriented Database Design
66
67Relationships
- Relationships represented using reference
attributes, typically implemented using OIDs. - Consider how to represent following binary
relationships according to their cardinality - 11
- 1M
- MN.
67
6811 Relationship Between Objects A and B
- Add reference attribute to A and, to maintain
referential integrity, reference attribute to B.
68
691M Relationship Between Objects A and B
- Add reference attribute to B and attribute
containing set of references to A.
69
70MN Relationship Between Objects A and B
- Add attribute containing set of references to
each object. - For relational database design, would decompose
MN into two 1M relationships linked by
intermediate entity. Can also represent this
model in an ODBMS.
70
71MN Relationships
71
72Alternative Design for MN Relationships
72
73Referential Integrity
- Several techniques to handle referential
integrity - Do not allow user to explicitly delete objects.
- System is responsible for "garbage collection".
- Allow user to delete objects when they are no
longer required. - System may detect invalid references
automatically and set reference to NULL or
disallow the deletion.
73
74Referential Integrity
- Allow user to modify and delete objects and
relationships when they are no longer required. - System automatically maintains the integrity of
objects. - Inverse attributes can be used to maintain
referential integrity.
74
75Behavioral Design
- EER approach must be supported with technique
that identifies behavior of each class. - Involves identifying
- public methods visible to all users
- private methods internal to class.
- Three types of methods
- constructors and destructors
- access
- transform.
75
76Behavioral Design - Methods
- Constructor - creates new instance of class.
- Destructor - deletes class instance no longer
required. - Access - returns value of one or more attributes
(Get). - Transform - changes state of class instance (Put).
76
77Identifying Methods
- Several methodologies for identifying methods,
typically combine following approaches - Identify classes and determine methods that may
be usefully provided for each class. - Decompose application in top-down fashion and
determine methods required to provide required
functionality.
77
78Object Management Group (OMG)
- International non profit-making consortium
founded in 1989 to address object standards. - Several hundred member organizations including
many platform and major software vendors. - Primary aims of OMG are
- Promotion of object-oriented approach.
- Development of standards in which location,
environment, language, and other characteristics
of objects are transparent.
78
79Object Management Group (OMG)
- Not recognized standards group but aims to
develop de facto standards. - Defines standard object-based facilities for
- Concurrent execution.
- Distributed transactions.
- Versioning.
- Event notification.
- Internationalization.
79
80Object Management Architecture
- Four areas identified for reference model
- Object Model (OM) - Design-portable abstract
model for communicating with OMG-compliant
object-oriented systems. - Object Request Broker (ORB) - Handle distribution
of messages between application objects in a
highly interoperable manner. - Like distributed 'software bus' enabling objects
to make/receive requests/ responses from a
provider.
80
81Object Management Architecture
- Object Services - Provide main functions for
realizing basic object functionality. Many of
these services are database-oriented. - Common Facilities - Comprise a set of tasks that
many applications must perform but are
traditionally duplicated within each one.
81
82Object Reference Model
82
83Object Model
83
84Common Object Request Broker Architecture (CORBA)
- Defines architecture of ORB-based environments.
- Basis of any OMG component, defining parts that
form ORB and associated structures. - Some elements of CORBA are
- Interface Definition Language (IDL).
- Type model.
- Interface Repository.
- Methods for getting interfaces/specifications of
objects.
84
85Object Database Management Group
- Established by vendors of ODBMSs to define
standards. - Have produced an Object Model that specifies a
standard model for the semantics of database
objects. - Design of class libraries and applications using
these semantics should be portable across various
ODBMSs.
85
86Object Database Management Group
- Major components of ODMG architecture for an
OODBMS are - Object Model (OM)
- Object Definition Language (ODL)
- Object Query Language (OQL)
- C Language Binding
- Smalltalk Language Binding
- Java Language Binding.
86
87ODMG Object Model
- Specifies following basic modeling primitives
- Basic modeling primitives are object/literal.
- Objects/literals can be categorized into types.
- All objects of given type exhibit common behavior
and state. A type is itself an object. - Behavior defined by set of operations that can be
performed on or by object. - State defined by values objects carry for a set
of properties.
87
88ODMG Object Model
- Property may be either an attribute of object or
relationship between object and one or more other
objects. - A database stores objects, enabling them to be
shared by multiple users and applications. - A database is based on a schema defined in Object
Definition Language (ODL).
88
89ODMG Object Model - Objects
- Object types decomposed as atomic, collections,
or structured types. - Structured types as defined in ISO SQL standard.
- Objects created using new() of corresponding
factory interface provided by language binding. - Each object has a unique identity, the object
identifier, which does not change and is not
reused when the object is deleted. - May be given one or more names by user.
89
90Set of Built-in Types for ODMG Object Model
90
91ODMG Object Model - Objects
- Lifetime of an object is orthogonal to its type.
- Means that persistence is independent of type.
- Lifetime specified when object is created may
be - Transient objects memory allocated and
deallocated by programming languages runtime
system. - Persistent objects storage managed by OODBMS.
91
92ODL Interface for Objects
92
93ODMG Object Model - Literals
- Literal types decomposed as atomic, collections,
structured, or null. - Values of a literals properties may not change.
- Do not have their own identifiers and cannot
stand alone as objects. - They are embedded in objects and cannot be
individually referenced. - Structured literals contain fixed number of named
heterogeneous elements.
93
94ODMG Object Model - Collections
- Contains arbitrary number of unnamed homogeneous
elements each can be instance of atomic type,
another collection, or a literal type. - Only collection objects have identity.
- Use iterator to iterate over collection.
- There are ordered and unordered collections
- Ordered collections traversed first to last, or
vice versa - Unordered collections have no fixed order of
iteration.
94
95ODMG Object Model - Collections
- Five built-in collection subtypes
- Set unordered collections without duplicates.
- Bag unordered collections that do allow
duplicates. - List ordered collections that allow duplicates.
- Array 1D array of dynamically varying length.
- Dictionary unordered sequence of key-value pairs
with no duplicate keys.
95
96ODL Interface for Collections
96
97ODMG Object Model - Types and Classes
- Type has one specification and one or more
implementations. - Specification defines properties and operations
that can be invoked on instances of the type. - An implementation defines data structures,
exceptions, and methods to support required state
and behavior. - Combination of type specification and one
implementation is a class.
97
98ODMG Object Model - Types and Classes
- Interface definition specifies its supertype(s),
its extent, and its keys - Extents - set of all instances of given type.
May request OODBMS maintain index to members of
this set. - Keys - uniquely identifies the instances of a
type (similar to the concept of a candidate key).
98
99ODMG Object Model - Relationships
- Traversal paths are defined in interface for each
direction of traversal. - interface Branch
- relationship set ltStaffgtHas
- inverse Staff WorksAt
- interface Staff
- relationship Branch WorksAt
- inverse Branch Has
99
100ODMG Object Model
- Object model also specifies
- Exceptions
- Metadata
- Transactions
- Databases.
100
101Object Definition Language (ODL)
- interface Branch
- (extent branch_offices
- key bno)
-
- attribute string bno
- relationship Manager ManagedBy
- inverse ManagerManages
- void take_on_property_for_rent(in PFR)
- raises(property_already_for_rent)
101
102Object Query Language (OQL)
- Provides declarative access to object database
using SQL-like syntax. - Does not provide explicit update operators -
leaves this to operations defined on object
types. - Can be used as a standalone language and as a
language embedded in another language, for which
an ODMG binding is defined (Smalltalk, C, and
Java). - OQL can also invoke operations programmed in
these languages.
102
103Object Query Language (OQL)
- An OQL query is a function that delivers an
object whose type may be inferred from operator
contributing to query expression. - Query definition expressions is of form
- DEFINE Q as e
- Defines query with name Q given query expression
e .
103
104Object Query Language (OQL)
- Expression can take several forms
- Elementary - Construction
- Atomic type - Object
- Collection - Indexed collections
- Binary set - Structure
- Conversion
- Query consists of a (possibly empty) set of query
definition expressions followed by an expression. - Result is object with or without identity.
104
105Object Query Language (OQL) - Examples
- (a) Get set of all staff (with identity)
- staff
- (b) Get set of all branch managers (with
identity) - branch_offices.ManagedBy
105
106Object Query Language (OQL) - Examples
- (c) Get set of all staff who live in London
(without identity) - define Londoners as
- select x
- from x in staff
- where x.address.city "London"
- select x.name.lname from x in Londoners
- This returns a literal of type setltstringgt.
106
107Object Query Language (OQL) - Examples
- (d) Get structured set (without identity)
containing name, sex and age for all staff who
live in London - select struct (lnamex.name.lname, sexx.sex,
- agex.age)
- from x in staff
- where x.address.city "London
- This returns a literal of type setltstructgt.
107
108Object Query Language (OQL) - Examples
- (e) Get structured set (with identity) containing
name and age for all deputy managers over 60 - type deputies attribute lname string age
integer - deputies (select struct (lnamex.name.lname,
- agex.age)
- from x in (select y from staff
- where position "Deputy")
- where x.age gt 60)
- This returns a mutable object of type deputies.
108
109Object Query Language (OQL) - Examples
- (f) Get structured set (without identity)
containing branch number and set of all
Assistants at branches in London - select struct (bnox.bno, assistants
- (select y from y in x.WorksAt
- where y.position "Assistant"))
- from x in (select z from branch_offices
- where z.address.city "London")
- This returns a literal of type setltstructgt.
109
110OQL - Creating Objects
- A type name constructor is used to create an
object with identity - Person(fnameJohn, lnameWhite,
- address19 Taylor St, Cranford, London,
- tel_no01718845112,
- sexM, date_of_birth1-Oct-45)
110