Purpose

The Adaptive History List subsystem provides a list of the user’s favorite items based on the user’s previous behavior.

Constraints

There are no Product Platform exceptions.

API Description

The client-side module provides an API for applications to log items, request recommended lists, modify items, or to configure Adaptive History List Engine. The server-side module handles requests from clients and incorporates a weight-based sorting algorithm to arrange items in the most-used order. In order to implement sorting algorithm, the engine has two data storages. The most important items with optional names are stored in the primary storage and in the secondary storage there are stored only hashes of items. Secondary storage is used for more accurate sorting of items in primary storage when these will advance in future.

Use Cases

There are twelve use cases here:

AHL initialization

  • Create AHL client

Engine configuration

  • Get engine configuration

  • Set engine configuration

Items managing

  • Log an item

  • Rename an item

  • Delete item(s)

    • Delete a single item

    • Delete many items

    • Delete items matching

  • Clear items

  • Flush items

  • Get adaptive list

  • Order items

Observer managing

  • Set observer

  • Cancel observer

API Class Structure

The API interface class structure consists of two interfaces. MAHLEGenericAPI interface provides functionality for handling adaptive list. The client application can also create a class inherited from MAHLEObserver to observe AHL engine events.

Related APIs
  • MAHLEGenericAPI
  • MAHLEObserver

Using the AHL API

To use the AHL API, an application needs to firstly link the AHLE2CLIENT library to itself, and then create the AHL engine instance.

In general, using the AHL API always contains the following steps:

  • Link the AHLE2CLIENT library (AHLE2CLIENT.lib) to the project file of an application.

  • If needed provide an observer class which realizes MAHLEObserver interface.

  • Call NewAHLEClientL() function with database name as a parameter to create a client object.

  • Working on AHL database: changing database configuration, inserting items, deleting items etc.

  • Destroy the client object.

See the following section for detailed instructions on how to use the interfaces.

In examples for test cases we assume that there are following items in database (first item is most recently/frequently used):

Example database content.

Key value Name (description)

1

Item

Name

2

Item3

Name3

3

Item1

Name1

4

AItem

AName

5

AFoo

Foo

Create AHL client

To create a new instance of AHL, a client application should call NewAHLEClientL() with database name (an object derived from TDesC).

The following code snippet demonstrates how to create an AHL client.

TPtrC databaseName = _L("SampleName");    // database name for created client

MAHLEGenericAPI* ahle = NewAHLEClientL(databaseName);

After finishing work with AHL client, the pointer returned by NewAHLEClientL() needs to be destroyed.

delete ahle;    // destroys client object
ahle = NULL;
Related APIs
  • NewAHLEClientL()

Get engine configuration

The following code snippet demonstrates how to get engine configuration.

TUint primarySize;    // primary storage size
TUint secondarySize;    // secondary storage size
TReal32 adaptationSpeed;    // adaptation speed

TInt err = ahle->GetConfiguration(primarySize, secondarySize, adaptationSpeed);

Set engine configuration

The following code snippet demonstrates how to set engine configuration.

TUint primarySize = 100;    // primary storage size
TUint secondarySize = 200;    // secondary storage size
TReal32 adaptationSpeed = 0.5;    // adaptation speed

TInt err = ahle->Reconfigure(primarySize, secondarySize, adaptationSpeed);

Adaptation speed determines how fast new items will advance on adaptive history list. The value set should be between 0 and 1, excluding. The closer the adaptation speed is to 1, the slower items will advance. Default value for adaptation speed is 0.95. The default size of the primary storage is 50 items and of secondary - 500.

Log an item

The following code snippet demonstrates how to log a new item to AHL database.

TPtrC item = _L("Item");    // key value for item
TPtrC name = _L("Name");    // name of item (descriptive inforamtion about item)
TReal32 weight = 2.0f;     // base weight of item

TInt err = ahle->NewAccess(item, name, weight);

Name and weight can be omitted. Weight can be used to categorize items: more important items should have higher base weight value.

After that operation example database content does not change, because "Item" is already on first place. If it would be on further place it could advance and if it would not exist in database it could be added depending on other items weights.

Rename an item

The following code snippet demonstrates how to rename an item.

TPtrC item = _L("Item");    // key value for item
TPtrC newName = _L("New name");    // new item's name

TInt err = ahle->RenameL(item, newName);

Example database content after Rename.

Key value Name (description)

1

Item

New name

2

Item3

Name3

3

Item1

Name1

4

AItem

AName

5

AFoo

Foo

Delete item(s)

Delete a single item

The following code snippet demonstrates how to delete one item from AHL database.

TPtrC item = _L("Item");    // key value for item

TInt err = ahle->Remove(item);

Example database content after delete single item.

Key value Name (description)

1

Item3

Name3

2

Item1

Name1

3

AItem

AName

4

AFoo

Foo

Delete many items

The following code snippet demonstrates how to delete several specified items from AHL database.

CDesCArrayFlat* items = new (ELeave) CDesCArrayFlat(20);
CleanupStack::PushL(items);
items->AppendL(_L("Item1"));
items->AppendL(_L("Item2"));
items->AppendL(_L(AFoo));

TInt err = ahle->RemoveL(items);

CleanupStack::PopAdnDestroy(items);

Example database content after delete specified items.

Key value Name (description)

1

Item

Name

2

Item3

Name3

3

AItem

AName

Delete items matching

The following code snippet demonstrates how to delete several items matching a specified string from AHL database.

TPtrC match = _L("It");    // match for item's key value

TInt err = ahle->RemoveMatching(match);

Example database content after delete items matching.

Key value Name (description)

1

AItem

AName

2

AFoo

Foo

Clear items

The following code snippet demonstrates how to clear database (delete all items).

TInt err = ahle->Clear();

After that operation database will be empty.

Flush items

The following code snippet demonstrates how to write AHL database from memory to the disk file.

TInt err = ahle->Flush();

Get Adaptive list

The following code snippet demonstrates how to get adaptive list of items.

CDesCArrayFlat* items = new (ELeave) CDesCArrayFlat(20);
CleanupStack::PushL(items);
CDesCArrayFlat* names = new (ELeave) CDesCArrayFlat(20);
CleanupStack::PushL(names);
TUint size = 3;
TPtrC match = _L("A");

TInt err = AdaptiveListL(*items, *names, size, match);

// working with items
.
.
.

CleanupStack::PopAndDestroy(2, items);

For example database content after "AdaptiveListL" call "items" table will consists following values {"AItem", "AFoo"} and in names table values {"AName", "Foo"}.

Match can be omitted and then the first items are taken from the list. If the match is omitted in the previous example, the tables contain the following values: "items" {"Item", "Item3", "Item1"} and "names" {"Name", "Name3", "Name1"}.

Order items

The following code snippet demonstrates how to order items based on adaptive list hierarchy.

CDesCArrayFlat* items = new (ELeave) CDesCArrayFlat(20);
CleanupStack::PushL(items);
RArray<TInt> sortedItems;
CleanupClosePushL(sortedItems);

items->AppendL(_L("Item1"));
items->AppendL(_L("Item2"));
items->AppendL(_L("Item3"));

TInt err = OrderByWeightL(*items, sortedItems);

// working with sorted items
.
.
.

CleanupStack::PopAndDestroy(2, items);

For example database content after "OrderByWeightL" call "sortedItems" table will consists following values {3, 1}.

Set observer

To set an observer, the client application should provide a class implementing interface MAHLEObserver.

The following code snippet demonstrates how to set AHL engine observer.

ahle->SetObserver(clientObserverObject);

After consuming an event, the client application needs to set the observer again before handling further events, e.g.:

// client's observer class implementation
void CClientObserver::AdaptiveListChanged(const TInt aError)
    {
    // event handling goes here
    .
    .
    .

    ahle->SetObserver(this)
    }
Related APIs
  • MAHLEObserver

Cancel observer

The following code snippet demonstrates how to cancel AHL engine observer.

ahle->CancelObserver();

Error handling

Responses from Adaptive History List Server and errors occurring due to incorrect parameters passed by the client to the API functions (e.g. out of range) are returned as return codes for synchronous functions and in the request status parameter for asynchronous functions. If a system error occurs in a client-side function, the function leaves.

Error messages

Code Description

KErrNoMemory

Reported when there is not enough memory.

KErrPermissionDenied

Reported by AHL server when the client process does not have sufficient capabilities.

KErrServerBusy

Reported when AHL server is busy.

KErrGeneral

Reported when there is an error in inter-process communication.

KErrAlreadyExists

Reported on an attempt to set an observer, when it is already set.

KErrCancel

Reported when the observer was cancelled by client application.

KErrNotFound

Reported when client application tries to cancel the observer, which is not set.

KErrArgument

Reported on incorrect parameter passed to a function.

KErrInUse

Reported when AHL server cannot process operation because it is reading from or writing to the AHL database file.

Related APIs
  • KErrAlreadyExists
  • KErrArgument
  • KErrCancel
  • KErrGeneral
  • KErrInUse
  • KErrNoMemory
  • KErrNotFound
  • KErrPermissionDenied
  • KErrServerBusy

Memory overhead

Memory consumption on the client side depends on the size of requested or sent data. It can be up to 2.5 times more than the size of requested data for adaptive list and it will not exceed 1,5 of sent/received data for other use cases.

Average memory consumption per database on server side is about 30kB in default configuration (primary storage 50 and secondary storage 500), maximal is about 180kB.

Extensions to the API

The AHL API does not explicitly support any kinds of extensions.

Related APIs
  • MAHLEObserver
  • NewAHLEClientL()

Glossary

Abbreviations

AHL API abbreviations

AHL(E)

Adaptive History List (Engine)

Definitions

AHL API definitions

Primary storage

Place where are stored items (key values) with their names and weights.

Secondary storage

Place where are stored only hashes of items (hashes of key values) with their weights (but without names).

Adaptation speed

Determines how fast AHL adopts to new items (new behaviors). It should be between 0 and 1 excluding. The smaller adaptation speed, the faster will be new items advance.

AHL database

A place where items are stored. It consists of primary and secondary storage and it is saved as a disk file.